0da3e0b0614ec34f31c1031a799997f9ca6b6406
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / P263 / p263_mb_layer.c
1 #include <VP_Os/vp_os_assert.h>
2 #include <VLIB/video_packetizer.h>
3
4 #include "p263_codec.h"
5 #include "p263_layers.h"
6 #include "p263_huffman.h"
7
8 p263_mb_type_t standard_mb_types[STANDARD_MB_TYPES_NUM] = {
9   MAKE_MB_TYPE( 1, 1, 1, 0, 1, 0 ), // INTER
10   MAKE_MB_TYPE( 1, 1, 1, 1, 1, 0 ), // INTER+Q
11   MAKE_MB_TYPE( 1, 1, 1, 0, 1, 1 ), // INTER4V
12   MAKE_MB_TYPE( 1, 1, 1, 0, 0, 0 ), // INTRA
13   MAKE_MB_TYPE( 1, 1, 1, 1, 0, 0 ), // INTRA+Q
14   MAKE_MB_TYPE( 1, 1, 1, 1, 1, 1 ), // INTER4V+Q
15   MAKE_MB_TYPE( 1, 1, 0, 0, 0, 0 )  // Stuffing
16 };
17
18 static C_RESULT p263_read_block( video_stream_t* stream, int16_t* data, int32_t* num_coeff )
19 {
20   int32_t* zztable;
21   int32_t index, code, run, last, nc, idx, sign;
22   p263_tcoeff_t* tc;
23
24   zztable = &video_zztable_t81[0];
25
26   nc = *num_coeff;
27
28   // DC coeff
29   code = run = last = 0;
30   video_read_data( stream, (uint32_t*) &code, 8 );
31   data[0] = code;
32
33   if( nc > 0 )
34   {
35     // AC coeff
36     while( last == 0 )
37     {
38       idx = huffman_stream_code( vlc_tcoeff_tree, stream );
39       VP_OS_ASSERT(idx < 0 );
40
41       sign = 0;
42       tc    = &tcoeff[idx];
43       if( tc->last == VLC_TCOEFF_ESCAPE )
44       {
45         code = run = last = 0;
46
47         video_read_data( stream, (uint32_t*) &last, 1 );
48         video_read_data( stream, (uint32_t*) &run, 6 );
49         video_read_data( stream, (uint32_t*) &code, 8 );
50
51         // For level (variable code in this program) the code 0000 0000 is forbidden,
52         // and the code 1000 0000 is forbidden unless the Modified Quantization mode is
53         // in use (see Annex T).
54
55         // Do sign extension for code. see Table 17/H.263 \96 FLC table for RUNs and LEVELs
56         code <<= 24;
57         code >>= 24; // This works because shift is signed & code can't be zero 
58       }
59       else
60       {
61         // read sign
62         video_read_data( stream, (uint32_t*) &sign, 1 );
63       }
64
65       code  = (sign == 0 ) ? tc->level : -tc->level;
66       run   = tc->run;
67       last  = tc->last;
68
69       VP_OS_ASSERT( run < 64 );
70
71       if( last == 0 )
72       {
73         zztable    += (run+1);
74         index       = *zztable;
75         data[index] = code;
76
77         nc++;
78       }
79     }
80
81     *num_coeff = nc;
82   }
83
84   return C_OK;
85 }
86
87 C_RESULT p263_read_mb_layer( video_controller_t* controller, video_stream_t* stream, video_macroblock_t* mb )
88 {
89   C_RESULT res = C_OK;
90   uint32_t cod = 0;
91   p263_mcbpc_t* mcbpc = NULL;
92   p263_cbpy_t   cbpy;
93   p263_codec_t* p263_codec = (p263_codec_t*) controller->video_codec;
94   p263_mb_type_t mb_type = MAKE_MB_TYPE( 1, 0, 0, 0, 0, 0 ); // By default we have only cod
95   int32_t dquant = 0, idx = 0;
96   int16_t* data;
97
98   if( controller->picture_type != VIDEO_PICTURE_INTRA )
99   {
100     // Read Coded macroblock indication (COD) (1 bit)
101     video_read_data( stream, &cod, 1 );
102   }
103
104   if( cod == 0 ) // Macroblock is coded (see 5.3.1)
105   {
106     // Read Macroblock type & Coded Block Pattern for Chrominance (MCBPC) (Variable length)
107     idx     = huffman_stream_code( vlc_mcbpc_ipictures_tree, stream );
108     mcbpc   = &mcbpc_ipictures[idx];
109
110     mb->num_coeff_cb = CBPC_CB(*mcbpc);
111     mb->num_coeff_cr = CBPC_CR(*mcbpc);
112
113     mb_type = p263_codec->mb_types[mcbpc->mb_type];
114   }
115
116   if( MB_TYPE_HAS_CBPY(mb_type) )
117   {
118     // Coded Block Pattern for luminance (CBPY) (Variable length)
119     idx = huffman_stream_code( vlc_cbpy_standard_tree, stream );
120     cbpy = p263_codec->cbpys[idx];
121
122     switch( controller->picture_type )
123     {
124       case VIDEO_PICTURE_INTRA:
125         mb->num_coeff_y0 = CBPY_INTRA_Y0(cbpy);
126         mb->num_coeff_y1 = CBPY_INTRA_Y1(cbpy);
127         mb->num_coeff_y2 = CBPY_INTRA_Y2(cbpy);
128         mb->num_coeff_y3 = CBPY_INTRA_Y3(cbpy);
129         break;
130
131       case VIDEO_PICTURE_INTER:
132         mb->num_coeff_y0 = CBPY_INTER_Y0(cbpy);
133         mb->num_coeff_y1 = CBPY_INTER_Y1(cbpy);
134         mb->num_coeff_y2 = CBPY_INTER_Y2(cbpy);
135         mb->num_coeff_y3 = CBPY_INTER_Y3(cbpy);
136         break;
137
138       default:
139         // Picture type not supported
140         break;
141     }
142   }
143
144   if( MB_TYPE_HAS_DQUANT(mb_type) )
145   {
146     mb->dquant = 0;
147     video_read_data( stream, (uint32_t*) &mb->dquant, 2 );
148
149     dquant = ( mb->dquant < 2 ) ? ~mb->dquant : (mb->dquant - 1);
150   }
151
152   dquant += controller->Qp;
153   mb->dquant = dquant;
154
155   /**************** Block Y0 ****************/
156   data = mb->data;
157   p263_read_block( stream, data, &mb->num_coeff_y0 );
158
159   /**************** Block Y1 ****************/
160   data += MCU_BLOCK_SIZE;
161   p263_read_block( stream, data, &mb->num_coeff_y1 );
162
163   /**************** Block Y2 ****************/
164   data += MCU_BLOCK_SIZE;
165   p263_read_block( stream, data, &mb->num_coeff_y2 );
166
167   /**************** Block Y3 ****************/
168   data += MCU_BLOCK_SIZE;
169   p263_read_block( stream, data, &mb->num_coeff_y3 );
170
171   /**************** Block CB ****************/
172   data += MCU_BLOCK_SIZE;
173   p263_read_block( stream, data, &mb->num_coeff_cb );
174
175   /**************** Block CR ****************/
176   data += MCU_BLOCK_SIZE;
177   p263_read_block( stream, data, &mb->num_coeff_cr );
178
179   return res;
180 }