source: soft/giet_vm/applications/mjpeg/idct.c @ 743

Last change on this file since 743 was 736, checked in by alain, 9 years ago

Modify the mjpeg application to support an optional
DCT hardware coprocessor.

File size: 7.8 KB
Line 
1////////////////////////////////////////////////////////////////////////////////////////
2// File   : idct.c 
3// Date   : octobre 2015
4// author : Alain Greiner
5////////////////////////////////////////////////////////////////////////////////////////
6// This file define the code of the IDCT (Inverse Discrete Cosinus Transform) thread
7// for the MJPEG application.
8// It read blocks of 8*8 pixels (one int32_t per pixel) from the <in> MWMR channel.
9// It write blocks of 8*8 pixels (one uint8_t per pixel) to the <out> MWMR channel.
10////////////////////////////////////////////////////////////////////////////////////////
11
12#include <mwmr_channel.h>
13#include <stdio.h>
14#include <stdint.h>
15#include "mjpeg.h"
16
17#define   INT_MAX   ((int32_t)0x7fffffff)
18#define   INT_MIN   ((int32_t)0x80000000)
19
20// macro to use a shared TTY
21#define PRINTF(...)    lock_acquire( &tty_lock ); \
22                       giet_tty_printf(__VA_ARGS__);  \
23                       lock_release( &tty_lock );
24
25// Useful constants
26
27/* ck = cos(k*pi/16) = s8-k = sin((8-k)*pi/16) times 1 << C_BITS and rounded */
28#define c0_1  16384
29#define c0_s2 23170
30#define c1_1  16069
31#define c1_s2 22725
32#define c2_1  15137
33#define c2_s2 21407
34#define c3_1  13623
35#define c3_s2 19266
36#define c4_1  11585
37#define c4_s2 16384
38#define c5_1  9102
39#define c5_s2 12873
40#define c6_1  6270
41#define c6_s2 8867
42#define c7_1  3196
43#define c7_s2 4520
44#define c8_1  0
45#define c8_s2 0
46#define sqrt2 c0_s2
47
48// The number of bits of accuracy in all (signed) integer operations
49
50#define ARITH_BITS      16
51
52// The minimum signed integer value that fits in ARITH_BITS
53#define ARITH_MIN       (-1 << (ARITH_BITS-1))
54#define ARITH_MAX       (~ARITH_MIN)
55
56// The number of bits coefficients are scaled up before 2-D idct
57#define S_BITS           3
58
59// The number of bits in the fractional part of a fixed point constant
60#define C_BITS          14
61
62// This version is vital in passing overall mean error test.
63#define descale(x, n) (((x) + (1 << ((n) - 1)) - ((x) < 0)) >> (n))
64
65static const int32_t COS[2][8] = 
66{
67   {c0_1 , c1_1 , c2_1 , c3_1 , c4_1 , c5_1 , c6_1 , c7_1 },
68   {c0_s2, c1_s2, c2_s2, c3_s2, c4_s2, c5_s2, c6_s2, c7_s2}
69};
70
71////////////////////////////////////
72static inline void rot( int32_t   f, 
73                        int32_t   k,
74                        int32_t   x, 
75                        int32_t   y,
76                        int32_t*  rx,
77                        int32_t*  ry )
78{
79#define Cos(k)  COS[f][k]
80#define Sin(k)  Cos(8-k)
81   *rx = (Cos(k) * x - Sin(k) * y) >> C_BITS;
82   //    r = (r + (1 << (C_BITS - 1))) >> C_BITS;
83   *ry = (Sin(k) * x + Cos(k) * y) >> C_BITS;
84   //    r = (r + (1 << (C_BITS - 1))) >> C_BITS;
85#undef Cos
86#undef Sin
87}
88
89/* Butterfly: but(a,b,x,y) = rot(sqrt(2),4,a,b,x,y) */
90#define but(a,b,x,y)   do { x = a - b; y = a + b; } while(0)
91
92// Inverse 1-D Discrete Cosine Transform.
93// Result Y is scaled up by factor sqrt(8).
94// Original Loeffler algorithm.
95static inline void idct_1d( int32_t* Y )
96{
97   int32_t z1[8], z2[8], z3[8];
98
99   /* Stage 1: */
100   but(Y[0], Y[4], z1[1], z1[0]);
101   rot(1, 6, Y[2], Y[6], &z1[2], &z1[3]);
102   but(Y[1], Y[7], z1[4], z1[7]);
103   z1[5] = (sqrt2 * Y[3]) >> C_BITS;
104   //    r = (r + (1 << (C_BITS - 1))) >> C_BITS;
105   z1[6] = (sqrt2 * Y[5]) >> C_BITS;
106   //    r = (r + (1 << (C_BITS - 1))) >> C_BITS;
107
108   /* Stage 2: */
109   but(z1[0], z1[3], z2[3], z2[0]);
110   but(z1[1], z1[2], z2[2], z2[1]);
111   but(z1[4], z1[6], z2[6], z2[4]);
112   but(z1[7], z1[5], z2[5], z2[7]);
113
114   /* Stage 3: */
115   z3[0] = z2[0];
116   z3[1] = z2[1];
117   z3[2] = z2[2];
118   z3[3] = z2[3];
119   rot(0, 3, z2[4], z2[7], &z3[4], &z3[7]);
120   rot(0, 1, z2[5], z2[6], &z3[5], &z3[6]);
121
122   /* Final stage 4: */
123   but(z3[0], z3[7], Y[7], Y[0]);
124   but(z3[1], z3[6], Y[6], Y[1]);
125   but(z3[2], z3[5], Y[5], Y[2]);
126   but(z3[3], z3[4], Y[4], Y[3]);
127}
128
129//////////////////////////////////////////////////////////////
130__attribute__ ((constructor)) void idct( unsigned int index )
131//////////////////////////////////////////////////////////////
132{
133    mwmr_channel_t* input  = iqzz_2_idct[index];
134    mwmr_channel_t* output = idct_2_libu[index];
135
136    int32_t row;
137    int32_t column;
138    int32_t block;
139
140    int32_t  bin[64];
141    uint8_t  bout[64];
142    int32_t  Y[64];
143
144    // get platform parameters
145    uint32_t  x_size;
146    uint32_t  y_size;
147    uint32_t  nprocs;
148    giet_procs_number( &x_size , &y_size , &nprocs );
149
150    // get processor coordinates
151    unsigned int x , y , p;
152    giet_proc_xyp( &x ,&y , &p );
153
154    // private TTY allocation
155    // giet_tty_alloc( 0 );
156
157    PRINTF("\n[MJPEG] thread IDCT[%d] starts on P[%d,%d,%d] / trdid = %x\n",
158           index , x , y , p, (uint32_t)trdid_idct[index] )
159
160
161    uint32_t  image = index;
162    uint32_t  nblocks = nblocks_h * nblocks_w;
163
164    while( image < MAX_IMAGES )   // one image per iteration
165    {
166        for ( block = 0 ; block < nblocks ; block++ )
167        {
168            uint32_t begin;
169
170            // read obe block of coefficients (4 bytes per pixel)
171            mwmr_read( input, (uint32_t*)bin , 64 );
172
173            for ( row = 0; row < 8 ; row++ )
174            {
175                for ( column = 0 ; column < 8 ; column++ )
176                {
177                    Y[row * 8 + column] = bin[row * 8 + column] << S_BITS;
178                }
179
180                idct_1d( &Y[8*row] );
181
182                // Result Y is scaled up by factor sqrt(8)*2^S_BITS.
183            }
184
185            for ( column = 0 ; column < 8 ; column++ )
186            {
187                int32_t Yc[8];
188
189                for ( row = 0 ; row < 8 ; row++ )
190                {
191                    Yc[row] = Y[8 * row + column];
192                }
193
194                idct_1d( Yc );
195       
196                for ( row = 0 ; row < 8 ; row++ ) 
197                {
198                    // Result is once more scaled up by a factor sqrt(8).
199                    int32_t r = 128 + descale(Yc[row], 2 * S_BITS);
200
201                    // Clip to 8 bits unsigned
202                    r = r > 0 ? (r < 255 ? r : 255) : 0;
203
204                    bout[8*row+column] = r;
205
206                    giet_pthread_assert( ((r & 0xFF) == r ) ,
207                    "ERROR in idct() : pixel overflow" ); 
208                }
209            }
210
211            // write one block to output MWMR channel (one byte per pixel)
212            mwmr_write( output, (uint32_t*)bout , 16 );
213
214#if (DEBUG_IDCT > 1)
215if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) )
216 PRINTF("\nIDCT[%d] completes block %d/%d in image %d\n" 
217         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
218         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
219         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
220         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
221         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
222         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
223         "  %x  %x  %x  %x  %x  %x  %x  %x\n"
224         "  %x  %x  %x  %x  %x  %x  %x  %x\n",
225         index , block , nblocks , image ,
226         bout[0] , bout[1] , bout[2] , bout[3] , bout[4] , bout[5] , bout[6] , bout[7] ,
227         bout[8] , bout[9] , bout[10], bout[11], bout[12], bout[13], bout[14], bout[15],
228         bout[16], bout[17], bout[18], bout[19], bout[20], bout[21], bout[22], bout[23],
229         bout[24], bout[25], bout[26], bout[27], bout[28], bout[29], bout[30], bout[31],
230         bout[32], bout[33], bout[34], bout[35], bout[36], bout[37], bout[38], bout[39],
231         bout[40], bout[41], bout[42], bout[43], bout[44], bout[45], bout[46], bout[47],
232         bout[48], bout[49], bout[50], bout[51], bout[52], bout[53], bout[54], bout[55],
233         bout[56], bout[57], bout[58], bout[59], bout[60], bout[61], bout[62], bout[63]) }
234}
235#endif
236        }  // end for blocks
237
238#if DEBUG_IDCT
239if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) )
240{ PRINTF("\nIDCT[%d] completes image %d at cycle %d\n", index , image , giet_proctime() ) }
241#endif
242
243        image = image + x_size*y_size;
244
245    }  // end while (1) on images
246
247    giet_pthread_exit( "IDCT completed" );
248
249}  // end idct()
250
Note: See TracBrowser for help on using the repository browser.