1 #include <VP_Os/vp_os_assert.h>
2 #include <VLIB/video_packetizer.h>
4 #include "p263_codec.h"
5 #include "p263_layers.h"
6 #include "p263_huffman.h"
10 p263_mb_type_t standard_mb_types[STANDARD_MB_TYPES_NUM] = {
11 MAKE_MB_TYPE( 1, 1, 1, 0, 1, 0 ), // INTER
12 MAKE_MB_TYPE( 1, 1, 1, 1, 1, 0 ), // INTER+Q
13 MAKE_MB_TYPE( 1, 1, 1, 0, 1, 1 ), // INTER4V
14 MAKE_MB_TYPE( 1, 1, 1, 0, 0, 0 ), // INTRA
15 MAKE_MB_TYPE( 1, 1, 1, 1, 0, 0 ), // INTRA+Q
16 MAKE_MB_TYPE( 1, 1, 1, 1, 1, 1 ), // INTER4V+Q
17 MAKE_MB_TYPE( 1, 1, 0, 0, 0, 0 ) // Stuffing
20 static C_RESULT p263_read_block( video_stream_t* stream, int16_t* data, int32_t* num_coeff )
23 int32_t index, code, run, last, nc, idx, sign;
26 zztable = &video_zztable_t81[0];
31 code = run = last = 0;
32 video_read_data( stream, (uint32_t*) &code, 8 );
40 idx = huffman_stream_code( vlc_tcoeff_tree, stream );
41 VP_OS_ASSERT(idx < 0 );
45 if( tc->last == VLC_TCOEFF_ESCAPE )
47 code = run = last = 0;
49 video_read_data( stream, (uint32_t*) &last, 1 );
50 video_read_data( stream, (uint32_t*) &run, 6 );
51 video_read_data( stream, (uint32_t*) &code, 8 );
53 // For level (variable code in this program) the code 0000 0000 is forbidden,
54 // and the code 1000 0000 is forbidden unless the Modified Quantization mode is
55 // in use (see Annex T).
57 // Do sign extension for code. see Table 17/H.263
\96 FLC table for RUNs and LEVELs
59 code >>= 24; // This works because shift is signed & code can't be zero
64 video_read_data( stream, (uint32_t*) &sign, 1 );
67 code = (sign == 0 ) ? tc->level : -tc->level;
71 VP_OS_ASSERT( run < 64 );
89 C_RESULT p263_read_mb_layer( video_controller_t* controller, video_stream_t* stream, video_macroblock_t* mb )
93 p263_mcbpc_t* mcbpc = NULL;
95 p263_codec_t* p263_codec = (p263_codec_t*) controller->video_codec;
96 p263_mb_type_t mb_type = MAKE_MB_TYPE( 1, 0, 0, 0, 0, 0 ); // By default we have only cod
97 int32_t dquant = 0, idx = 0;
100 if( controller->picture_type != VIDEO_PICTURE_INTRA )
102 // Read Coded macroblock indication (COD) (1 bit)
103 video_read_data( stream, &cod, 1 );
106 if( cod == 0 ) // Macroblock is coded (see 5.3.1)
108 // Read Macroblock type & Coded Block Pattern for Chrominance (MCBPC) (Variable length)
109 idx = huffman_stream_code( vlc_mcbpc_ipictures_tree, stream );
110 mcbpc = &mcbpc_ipictures[idx];
112 mb->num_coeff_cb = CBPC_CB(*mcbpc);
113 mb->num_coeff_cr = CBPC_CR(*mcbpc);
115 mb_type = p263_codec->mb_types[mcbpc->mb_type];
118 if( MB_TYPE_HAS_CBPY(mb_type) )
120 // Coded Block Pattern for luminance (CBPY) (Variable length)
121 idx = huffman_stream_code( vlc_cbpy_standard_tree, stream );
122 cbpy = p263_codec->cbpys[idx];
124 switch( controller->picture_type )
126 case VIDEO_PICTURE_INTRA:
127 mb->num_coeff_y0 = CBPY_INTRA_Y0(cbpy);
128 mb->num_coeff_y1 = CBPY_INTRA_Y1(cbpy);
129 mb->num_coeff_y2 = CBPY_INTRA_Y2(cbpy);
130 mb->num_coeff_y3 = CBPY_INTRA_Y3(cbpy);
133 case VIDEO_PICTURE_INTER:
134 mb->num_coeff_y0 = CBPY_INTER_Y0(cbpy);
135 mb->num_coeff_y1 = CBPY_INTER_Y1(cbpy);
136 mb->num_coeff_y2 = CBPY_INTER_Y2(cbpy);
137 mb->num_coeff_y3 = CBPY_INTER_Y3(cbpy);
141 // Picture type not supported
146 if( MB_TYPE_HAS_DQUANT(mb_type) )
149 video_read_data( stream, (uint32_t*) &mb->dquant, 2 );
151 dquant = ( mb->dquant < 2 ) ? ~mb->dquant : (mb->dquant - 1);
154 dquant += controller->Qp;
157 /**************** Block Y0 ****************/
159 p263_read_block( stream, data, &mb->num_coeff_y0 );
161 /**************** Block Y1 ****************/
162 data += MCU_BLOCK_SIZE;
163 p263_read_block( stream, data, &mb->num_coeff_y1 );
165 /**************** Block Y2 ****************/
166 data += MCU_BLOCK_SIZE;
167 p263_read_block( stream, data, &mb->num_coeff_y2 );
169 /**************** Block Y3 ****************/
170 data += MCU_BLOCK_SIZE;
171 p263_read_block( stream, data, &mb->num_coeff_y3 );
173 /**************** Block CB ****************/
174 data += MCU_BLOCK_SIZE;
175 p263_read_block( stream, data, &mb->num_coeff_cb );
177 /**************** Block CR ****************/
178 data += MCU_BLOCK_SIZE;
179 p263_read_block( stream, data, &mb->num_coeff_cr );