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