ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / Platform / x86 / UVLC / uvlc_codec.c
1 #include <VLIB/Platform/video_utils.h>
2 #include <VLIB/Platform/video_config.h>
3
4 #include <VLIB/video_quantizer.h>
5 #include <VLIB/video_dct.h>
6 #include <VLIB/video_mem32.h>
7 #include <VLIB/video_packetizer.h>
8
9 #include <VLIB/UVLC/uvlc_codec.h>
10 #include <VLIB/UVLC/uvlc.h>
11
12 #include <VP_Os/vp_os_malloc.h>
13 #include <VP_Os/vp_os_assert.h>
14
15 #if TARGET_CPU_X86 == 1
16
17 #ifdef HAS_UVLC_DECODE_BLOCKLINE
18 C_RESULT uvlc_read_block_unquantize( video_controller_t* controller, int16_t* data, int32_t quant, int32_t nc )
19 {
20   video_stream_t* stream = &controller->in_stream;
21   int32_t* zztable;
22   int32_t index, code, run, last;
23
24   zztable = &video_zztable_t81[0];
25
26   // DC coeff
27   code = run = last = 0;
28   video_read_data( stream, (uint32_t*) &code, 10 );
29
30   if( controller->picture_type == VIDEO_PICTURE_INTRA ) // intra
31   {
32     code <<= 3;
33   }
34   else
35   {
36     code = quant*( 2*code + 1 );
37     if( quant & 1 )
38       code -= 1;
39   }
40   data[0] = code;
41
42   if( nc > 0 )
43   {
44     // AC coeff
45     while( last == 0 )
46     {
47       code = run = last = 0;
48       uvlc_decode( stream, &run, &code, &last);
49
50       VP_OS_ASSERT( run < 64 );
51
52       if( last == 0 )
53       {
54         zztable    += (run+1);
55         index       = *zztable;
56
57         code = quant*( 2*code + 1 );
58         if( quant & 1 )
59           code -= 1;
60
61         data[index] = code;
62       }
63     }
64   }
65
66   return C_OK;
67 }
68
69 C_RESULT uvlc_read_mb_layer_unquantize( video_controller_t* controller, video_macroblock_t* mb, int32_t num_macro_blocks )
70 {
71   int16_t* data;
72   uint32_t code;
73
74   video_zeromem32( (uint32_t*)mb->data, num_macro_blocks * 6 * MCU_BLOCK_SIZE / 2 );
75
76   while( num_macro_blocks > 0 )
77   {
78     mb->azq = 0;
79     video_read_data( &controller->in_stream, (uint32_t*)&mb->azq, 1 );
80
81     if( mb->azq == 0 )
82     {
83       video_read_data( &controller->in_stream, &code, 8 );
84
85       mb->num_coeff_y0 = (code >> 0) & 1;
86       mb->num_coeff_y1 = (code >> 1) & 1;
87       mb->num_coeff_y2 = (code >> 2) & 1;
88       mb->num_coeff_y3 = (code >> 3) & 1;
89       mb->num_coeff_cb = (code >> 4) & 1;
90       mb->num_coeff_cr = (code >> 5) & 1;
91
92       mb->dquant = 0;
93       if( (code >> 6) & 1 )
94       {
95         video_read_data( &controller->in_stream, &code, 2 );
96
97         mb->dquant = (code < 2) ? ~code : code;
98       }
99
100       controller->quant += mb->dquant;
101
102       /**************** Block Y0 ****************/
103       data = mb->data;
104       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y0 );
105
106       /**************** Block Y1 ****************/
107       data += MCU_BLOCK_SIZE;
108       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y1 );
109
110       /**************** Block Y2 ****************/
111       data += MCU_BLOCK_SIZE;
112       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y2 );
113
114       /**************** Block Y3 ****************/
115       data += MCU_BLOCK_SIZE;
116       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_y3 );
117
118       /**************** Block CB ****************/
119       data += MCU_BLOCK_SIZE;
120       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_cb );
121
122       /**************** Block CR ****************/
123       data += MCU_BLOCK_SIZE;
124       uvlc_read_block_unquantize( controller, data, controller->quant, mb->num_coeff_cr );
125     }
126
127     mb ++;
128     num_macro_blocks --;
129   }
130
131   return C_OK;
132 }
133
134 C_RESULT uvlc_decode_blockline( video_controller_t* controller, vp_api_picture_t* picture, bool_t* got_image )
135 {
136   video_codec_t* video_codec;
137   vp_api_picture_t blockline = { 0 };
138   int16_t *in = NULL, *out = NULL;
139   int32_t num_macro_blocks = 0;
140   video_macroblock_t* macroblock = NULL;
141   video_picture_context_t blockline_ctx;
142   video_gob_t*  gobs;
143
144   controller->mode  = VIDEO_DECODE;
145   video_codec       = controller->video_codec;
146
147   blockline                   = *picture;
148   blockline.height            = MB_HEIGHT_Y;
149   blockline.complete          = 1;
150   blockline.vision_complete   = 0;
151
152   picture->complete  = controller->picture_complete;
153
154   blockline_ctx.y_woffset = blockline.y_line_size;
155   blockline_ctx.c_woffset = blockline.cb_line_size;
156   blockline_ctx.y_hoffset = blockline.y_line_size * MCU_HEIGHT;
157
158   // At least a complete blockline is found
159   while( !controller->picture_complete && controller->in_stream.index <= (controller->in_stream.used >> 2) )
160   {
161     uvlc_unpack_controller( controller );
162
163     if( !controller->picture_complete )
164     {
165       blockline.blockline  = controller->blockline;
166
167       blockline_ctx.y_src     = picture->y_buf + blockline.blockline * MB_HEIGHT_Y * picture->y_line_size;
168       blockline_ctx.cb_src    = picture->cb_buf + blockline.blockline * MB_HEIGHT_C * picture->cb_line_size;
169       blockline_ctx.cr_src    = picture->cr_buf + blockline.blockline * MB_HEIGHT_C * picture->cr_line_size;
170
171       picture->blockline  = controller->blockline;
172       num_macro_blocks    = controller->mb_blockline;
173
174       macroblock  = &controller->cache_mbs[0];
175       gobs        = &controller->gobs[controller->blockline];
176       out         = gobs->macroblocks->data;
177
178       if( gobs->quant != controller->quant )
179       {
180         controller->quant = gobs->quant;
181         video_quantizer_update( controller );
182       }
183
184       while( num_macro_blocks > MAX_NUM_MACRO_BLOCKS_PER_CALL )
185       {
186         in = &macroblock->data[0];
187
188         uvlc_read_mb_layer_unquantize( controller, macroblock, MAX_NUM_MACRO_BLOCKS_PER_CALL );
189
190         out = video_idct_compute( in, out, MAX_NUM_MACRO_BLOCKS_PER_CALL );
191
192         if( macroblock == &controller->cache_mbs[0] )
193           macroblock += MAX_NUM_MACRO_BLOCKS_PER_CALL;
194         else
195           macroblock -= MAX_NUM_MACRO_BLOCKS_PER_CALL;
196
197         num_macro_blocks -= MAX_NUM_MACRO_BLOCKS_PER_CALL;
198       }
199
200       in = macroblock->data;
201
202       uvlc_read_mb_layer_unquantize( controller, macroblock, num_macro_blocks );
203
204       video_idct_compute( in, out, num_macro_blocks );
205
206       video_blockline_from_macro_blocks(&blockline_ctx, gobs->macroblocks->data, controller->mb_blockline, picture->format);
207
208       // Update controller according to video statistics
209       video_controller_update( controller, controller->picture_complete );
210     }
211   }
212
213   if( controller->picture_complete )
214   {
215     picture->complete   = controller->picture_complete;
216     picture->blockline  = 0;
217
218     controller->picture_complete  = 0;
219     controller->in_stream.length  = 32;
220     //controller->num_frames++;
221
222     *got_image = TRUE;
223   }
224   else
225   {
226     controller->in_stream.used  = 0;
227     controller->in_stream.index = 0;
228   }
229
230   return C_OK;
231 }
232 #endif
233
234 #endif // TARGET_CPU_X86 == 1