X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_parser%2Fvpar_blocks.c;h=9946dc02f546883ebead1d0f3f67f8c7a1478c44;hb=3c6ac119d3d1cb392d913f50153a9a28707490c1;hp=32dde069f0cb776c8cc4e48f608a85ee57090d60;hpb=6a7b7ae713344c8ff93b84565475c9806e77910b;p=vlc diff --git a/src/video_parser/vpar_blocks.c b/src/video_parser/vpar_blocks.c index 32dde069f0..9946dc02f5 100644 --- a/src/video_parser/vpar_blocks.c +++ b/src/video_parser/vpar_blocks.c @@ -39,14 +39,10 @@ #include "vpar_synchro.h" #include "video_parser.h" + /* * Local prototypes */ -static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, - macroblock_t * p_mb ); -static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ); -static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, - macroblock_t * p_mb ); typedef void (*f_decode_block_t)( vpar_thread_t *, macroblock_t *, int ); static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ); static void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ); @@ -57,7 +53,7 @@ static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, * Initialisation tables */ /* Table for coded_block_pattern resolution */ -lookup_t pl_coded_pattern_init_table[512] = +static lookup_t pl_coded_pattern_init_table[512] = { {MB_ERROR, 0}, {0, 9}, {39, 9}, {27, 9}, {59, 9}, {55, 9}, {47, 9}, {31, 9}, {58, 8}, {58, 8}, {54, 8}, {54, 8}, {46, 8}, {46, 8}, {30, 8}, {30, 8}, {57, 8}, {57, 8}, {53, 8}, {53, 8}, {45, 8}, {45, 8}, {29, 8}, {29, 8}, @@ -128,7 +124,7 @@ lookup_t pl_coded_pattern_init_table[512] = */ /* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ -lookup_t pl_dct_dc_lum_init_table_1[32] = +static lookup_t pl_dct_dc_lum_init_table_1[32] = { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, @@ -136,7 +132,7 @@ lookup_t pl_dct_dc_lum_init_table_1[32] = }; /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ -lookup_t pl_dct_dc_lum_init_table_2[32] = +static lookup_t pl_dct_dc_lum_init_table_2[32] = { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, @@ -146,7 +142,7 @@ lookup_t pl_dct_dc_lum_init_table_2[32] = }; /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ -lookup_t pl_dct_dc_chrom_init_table_1[32] = +static lookup_t pl_dct_dc_chrom_init_table_1[32] = { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, @@ -154,18 +150,25 @@ lookup_t pl_dct_dc_chrom_init_table_1[32] = }; /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ -lookup_t pl_dct_dc_chrom_init_table_2[32] = +static lookup_t pl_dct_dc_chrom_init_table_2[32] = { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} }; + + /* + * Structure to store the tables B14 & B15 + * Is constructed from the tables below + */ + dct_lookup_t ppl_dct_coef[2][16384]; + -/* Tables for ac DCT coefficients. There are cut in many parts to save space */ + /* Tables for ac DCT coefficients. There are cut in many parts to save space */ /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for first (DC) coefficient) */ -dct_lookup_t pl_DCT_tab_dc[12] = +static dct_lookup_t pl_DCT_tab_dc[12] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, @@ -175,7 +178,7 @@ dct_lookup_t pl_DCT_tab_dc[12] = /* Table B-14, DCT coefficients table zero, * codes 0100 ... 1xxx (used for all other coefficients) */ -dct_lookup_t pl_DCT_tab_ac[12] = +static dct_lookup_t pl_DCT_tab_ac[12] = { {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, /* EOB */ @@ -185,7 +188,7 @@ dct_lookup_t pl_DCT_tab_ac[12] = /* Table B-14, DCT coefficients table zero, * codes 000001xx ... 00111xxx */ -dct_lookup_t pl_DCT_tab0[60] = +static dct_lookup_t pl_DCT_tab0[60] = { {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, /* Escape */ @@ -208,10 +211,9 @@ dct_lookup_t pl_DCT_tab0[60] = /* Table B-15, DCT coefficients table one, * codes 000001xx ... 11111111 */ -dct_lookup_t pl_DCT_tab0a[252] = +static dct_lookup_t pl_DCT_tab0a[252] = { - {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, - /* Escape */ + {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, @@ -234,10 +236,10 @@ dct_lookup_t pl_DCT_tab0a[252] = {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, /* EOB */ - {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, - {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, - {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, {DCT_EOB,0,4}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, + {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, @@ -257,6 +259,7 @@ dct_lookup_t pl_DCT_tab0a[252] = {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, + {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, @@ -278,7 +281,7 @@ dct_lookup_t pl_DCT_tab0a[252] = /* Table B-14, DCT coefficients table zero, * codes 0000001000 ... 0000001111 */ -dct_lookup_t pl_DCT_tab1[8] = +static dct_lookup_t pl_DCT_tab1[8] = { {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} @@ -287,7 +290,7 @@ dct_lookup_t pl_DCT_tab1[8] = /* Table B-15, DCT coefficients table one, * codes 000000100x ... 000000111x */ -dct_lookup_t pl_DCT_tab1a[8] = +static dct_lookup_t pl_DCT_tab1a[8] = { {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} @@ -296,7 +299,7 @@ dct_lookup_t pl_DCT_tab1a[8] = /* Table B-14/15, DCT coefficients table zero / one, * codes 000000010000 ... 000000011111 */ -dct_lookup_t pl_DCT_tab2[16] = +static dct_lookup_t pl_DCT_tab2[16] = { {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, @@ -307,7 +310,7 @@ dct_lookup_t pl_DCT_tab2[16] = /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000010000 ... 0000000011111 */ -dct_lookup_t pl_DCT_tab3[16] = +static dct_lookup_t pl_DCT_tab3[16] = { {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, @@ -318,7 +321,7 @@ dct_lookup_t pl_DCT_tab3[16] = /* Table B-14/15, DCT coefficients table zero / one, * codes 00000000010000 ... 00000000011111 */ -dct_lookup_t pl_DCT_tab4[16] = +static dct_lookup_t pl_DCT_tab4[16] = { {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, @@ -329,7 +332,7 @@ dct_lookup_t pl_DCT_tab4[16] = /* Table B-14/15, DCT coefficients table zero / one, * codes 000000000010000 ... 000000000011111 */ -dct_lookup_t pl_DCT_tab5[16] = +static dct_lookup_t pl_DCT_tab5[16] = { {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, @@ -340,7 +343,7 @@ dct_lookup_t pl_DCT_tab5[16] = /* Table B-14/15, DCT coefficients table zero / one, * codes 0000000000010000 ... 0000000000011111 */ -dct_lookup_t pl_DCT_tab6[16] = +static dct_lookup_t pl_DCT_tab6[16] = { {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, @@ -360,9 +363,9 @@ void vpar_InitCrop( vpar_thread_t * p_vpar ) { int i_dummy; - p_vpar->pi_crop = p_vpar->pi_crop_buf + 32768; + p_vpar->pi_crop = p_vpar->pi_crop_buf + 4096; - for( i_dummy = -32768; i_dummy < -2048; i_dummy++ ) + for( i_dummy = -4096; i_dummy < -2048; i_dummy++ ) { p_vpar->pi_crop[i_dummy] = -2048; } @@ -370,7 +373,7 @@ void vpar_InitCrop( vpar_thread_t * p_vpar ) { p_vpar->pi_crop[i_dummy] = i_dummy; } - for( ; i_dummy < 32767; i_dummy++ ) + for( ; i_dummy < 4095; i_dummy++ ) { p_vpar->pi_crop[i_dummy] = 2047; } @@ -381,26 +384,29 @@ void vpar_InitCrop( vpar_thread_t * p_vpar ) * InitMbAddrInc : Initialize the lookup table for mb_addr_inc *****************************************************************************/ -/* Fonction for filling up the lookup table for mb_addr_inc */ -void __inline__ FillMbAddrIncTable( vpar_thread_t * p_vpar, +/* Function for filling up the lookup table for mb_addr_inc */ +static void __inline__ FillMbAddrIncTable( vpar_thread_t * p_vpar, int i_start, int i_end, int i_step, int * pi_value, int i_length ) { - int i_dummy, i_dummy2; - for( i_dummy = i_start ; i_dummy < i_end ; i_dummy += i_step ) - for( i_dummy2 = 0 ; i_dummy2 < i_step ; i_dummy2 ++ ) + int i_pos, i_offset; + for( i_pos = i_start ; i_pos < i_end ; i_pos += i_step ) + { + for( i_offset = 0 ; i_offset < i_step ; i_offset ++ ) { - p_vpar->pl_mb_addr_inc[i_dummy + i_dummy2].i_value = * pi_value; - p_vpar->pl_mb_addr_inc[i_dummy + i_dummy2].i_length = i_length; + p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_value = * pi_value; + p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_length = i_length; } - (*pi_value)--; + (*pi_value)--; + } } -/* Fonction that initialize the table using the last one */ -void InitMbAddrInc( vpar_thread_t * p_vpar ) +/* Function that initialize the table using the last one */ +void vpar_InitMbAddrInc( vpar_thread_t * p_vpar ) { int i_dummy; - int * pi_value; + int i_value; + for( i_dummy = 0 ; i_dummy < 8 ; i_dummy++ ) { p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR; @@ -424,16 +430,17 @@ void InitMbAddrInc( vpar_thread_t * p_vpar ) p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR; p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0; } - pi_value = (int *) malloc( sizeof( int ) ); - * pi_value = 33; - FillMbAddrIncTable( p_vpar, 1024, 2048, 1024, pi_value, 1 ); - FillMbAddrIncTable( p_vpar, 512, 1024, 256, pi_value, 3 ); - FillMbAddrIncTable( p_vpar, 256, 512, 128, pi_value, 4 ); - FillMbAddrIncTable( p_vpar, 128, 256, 64, pi_value, 5 ); - FillMbAddrIncTable( p_vpar, 96, 128, 16, pi_value, 7 ); - FillMbAddrIncTable( p_vpar, 48, 96, 8, pi_value, 8 ); - FillMbAddrIncTable( p_vpar, 36, 48, 2, pi_value, 10 ); - FillMbAddrIncTable( p_vpar, 24, 36, 1, pi_value, 11 ); + + i_value = 33; + + FillMbAddrIncTable( p_vpar, 24, 36, 1, &i_value, 11 ); + FillMbAddrIncTable( p_vpar, 36, 48, 2, &i_value, 10 ); + FillMbAddrIncTable( p_vpar, 48, 96, 8, &i_value, 8 ); + FillMbAddrIncTable( p_vpar, 96, 128, 16, &i_value, 7 ); + FillMbAddrIncTable( p_vpar, 128, 256, 64, &i_value, 5 ); + FillMbAddrIncTable( p_vpar, 256, 512, 128, &i_value, 4 ); + FillMbAddrIncTable( p_vpar, 512, 1024, 256, &i_value, 3 ); + FillMbAddrIncTable( p_vpar, 1024, 2048, 1024, &i_value, 1 ); } /***************************************************************************** @@ -458,7 +465,7 @@ static void __inline__ FillMBType( vpar_thread_t * p_vpar, } /* Fonction that fills the table for P MB_Type */ -void InitPMBType( vpar_thread_t * p_vpar ) +void vpar_InitPMBType( vpar_thread_t * p_vpar ) { FillMBType( p_vpar, 0, 32, 64, MB_MOTION_FORWARD|MB_PATTERN, 1 ); FillMBType( p_vpar, 0, 16, 32, MB_PATTERN, 2 ); @@ -473,7 +480,7 @@ void InitPMBType( vpar_thread_t * p_vpar ) } /* Fonction that fills the table for B MB_Type */ -void InitBMBType( vpar_thread_t * p_vpar ) +void vpar_InitBMBType( vpar_thread_t * p_vpar ) { FillMBType( p_vpar, 1, 48, 64, MB_MOTION_FORWARD |MB_MOTION_BACKWARD|MB_PATTERN, 2 ); @@ -499,10 +506,9 @@ void InitBMBType( vpar_thread_t * p_vpar ) * InitCodedPattern : Initialize the lookup table for decoding * coded block pattern *****************************************************************************/ -void InitCodedPattern( vpar_thread_t * p_vpar ) +void vpar_InitCodedPattern( vpar_thread_t * p_vpar ) { - memcpy( p_vpar->pl_coded_pattern, pl_coded_pattern_init_table , - sizeof(pl_coded_pattern_init_table) ); + p_vpar->pl_coded_pattern = (lookup_t*) pl_coded_pattern_init_table; } /***************************************************************************** @@ -510,37 +516,212 @@ void InitCodedPattern( vpar_thread_t * p_vpar ) * from the vlc code *****************************************************************************/ -void InitDCTTables( vpar_thread_t * p_vpar ) +/* First fonction for filling the table */ +static void __inline__ FillDCTTable( dct_lookup_t * p_tab_dest, dct_lookup_t * p_tab_src, + int i_step, int i_nb_elem, int i_offset ) { - /* Tables are cut in two parts to reduce memory occupation */ - memcpy( p_vpar->pppl_dct_dc_size[0][0], pl_dct_dc_lum_init_table_1, - sizeof( pl_dct_dc_lum_init_table_1 ) ); - memcpy( p_vpar->pppl_dct_dc_size[0][1], pl_dct_dc_lum_init_table_2, - sizeof( pl_dct_dc_lum_init_table_2 ) ); - memcpy( p_vpar->pppl_dct_dc_size[1][0], pl_dct_dc_chrom_init_table_1, - sizeof( pl_dct_dc_chrom_init_table_1 ) ); - memcpy( p_vpar->pppl_dct_dc_size[1][1], pl_dct_dc_chrom_init_table_2, - sizeof( pl_dct_dc_chrom_init_table_2 ) ); - /* For table B14 & B15, we have a pointer to tables */ - memcpy( p_vpar->ppl_dct_coef[0], pl_DCT_tab_dc, sizeof( pl_DCT_tab_dc ) ); - memcpy( p_vpar->ppl_dct_coef[1], pl_DCT_tab_ac, sizeof( pl_DCT_tab_ac ) ); - memcpy( p_vpar->ppl_dct_coef[2], pl_DCT_tab0, sizeof( pl_DCT_tab0 ) ); - memcpy( p_vpar->ppl_dct_coef[3], pl_DCT_tab1, sizeof( pl_DCT_tab1 ) ); - memcpy( p_vpar->ppl_dct_coef[4], pl_DCT_tab2, sizeof( pl_DCT_tab2 ) ); - memcpy( p_vpar->ppl_dct_coef[5], pl_DCT_tab3, sizeof( pl_DCT_tab3 ) ); - memcpy( p_vpar->ppl_dct_coef[6], pl_DCT_tab4, sizeof( pl_DCT_tab4 ) ); - memcpy( p_vpar->ppl_dct_coef[7], pl_DCT_tab5, sizeof( pl_DCT_tab5 ) ); - memcpy( p_vpar->ppl_dct_coef[8], pl_DCT_tab6, sizeof( pl_DCT_tab6 ) ); - memcpy( p_vpar->ppl_dct_coef[9], pl_DCT_tab0a, sizeof( pl_DCT_tab0a ) ); - memcpy( p_vpar->ppl_dct_coef[10], pl_DCT_tab1a, sizeof( pl_DCT_tab1a ) ); + int i_dummy, i_dummy2; + + for( i_dummy=0 ; i_dummy < i_nb_elem ; i_dummy++ ) + { + for( i_dummy2=0 ; i_dummy2 < i_step ; i_dummy2++ ) + { + p_tab_dest[(i_dummy+i_offset)*i_step+i_dummy2] = p_tab_src[i_dummy]; + } + } +} +/* Fonction that actually fills the table or create the pointers */ +void vpar_InitDCTTables( vpar_thread_t * p_vpar ) +{ + /* Tables are cut in two parts to reduce memory occupation */ + p_vpar->pppl_dct_dc_size[0][0] = pl_dct_dc_lum_init_table_1; + p_vpar->pppl_dct_dc_size[0][1] = pl_dct_dc_lum_init_table_2; + p_vpar->pppl_dct_dc_size[1][0] = pl_dct_dc_chrom_init_table_1; + p_vpar->pppl_dct_dc_size[1][1] = pl_dct_dc_chrom_init_table_2; + + memset( ppl_dct_coef[0], MB_ERROR, 16 ); + memset( ppl_dct_coef[1], MB_ERROR, 16 ); + + /* For table B14 & B15, we have a pointer to tables */ + /* We fill the table thanks to the fonction defined above */ + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab0, 256, 60, 4 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab1, 64, 8, 8 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab2, 16, 16, 16 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab3, 8, 16, 16 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab4, 4, 16, 16 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab5, 2, 16, 16 ); + FillDCTTable( ppl_dct_coef[0], pl_DCT_tab6, 1, 16, 16 ); + + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab0a, 256, 60, 4 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab1a, 64, 8, 8 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab2, 16, 16, 16 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab3, 8, 16, 16 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab4, 4, 16, 16 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab5, 2, 16, 16 ); + FillDCTTable( ppl_dct_coef[1], pl_DCT_tab6, 1, 16, 16 ); } /* * Macroblock parsing functions */ +/***************************************************************************** + * InitMacroblock : Initialize macroblock values + *****************************************************************************/ +static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, + macroblock_t * p_mb ) +{ + static f_chroma_motion_t pf_chroma_motion[4] = + { NULL, vdec_Motion420, vdec_Motion422, vdec_Motion444 }; + + p_mb->p_picture = p_vpar->picture.p_picture; + p_mb->i_structure = p_vpar->picture.i_structure; + p_mb->i_current_structure = p_vpar->picture.i_current_structure; + p_mb->i_l_x = p_vpar->mb.i_l_x; + p_mb->i_l_y = p_vpar->mb.i_l_y; + p_mb->i_c_x = p_vpar->mb.i_c_x; + p_mb->i_c_y = p_vpar->mb.i_c_y; + p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks; + p_mb->pf_chroma_motion = pf_chroma_motion[p_vpar->sequence.i_chroma_format]; + p_mb->b_P_coding_type = ( p_vpar->picture.i_coding_type == P_CODING_TYPE ); + + if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) || + (p_vpar->picture.i_coding_type == B_CODING_TYPE) ) + p_mb->p_forward = p_vpar->sequence.p_forward; + if( p_vpar->picture.i_coding_type == B_CODING_TYPE ) + p_mb->p_backward = p_vpar->sequence.p_backward; + + p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8; + p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8; + + /* Update macroblock real position. */ + p_vpar->mb.i_l_x += 16; + p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width) + * (2 - p_vpar->picture.b_frame_structure) * 16; + p_vpar->mb.i_l_x %= p_vpar->sequence.i_width; + + p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width; + p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width) + * (2 - p_vpar->picture.b_frame_structure) + * p_vpar->sequence.i_chroma_mb_height; + p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width; +} + +/***************************************************************************** + * MacroblockAddressIncrement : Get the macroblock_address_increment field + *****************************************************************************/ +static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) +{ + int i_addr_inc = 0; + /* Index in the lookup table mb_addr_inc */ + int i_index = ShowBits( &p_vpar->bit_stream, 11 ); + + /* Test the presence of the escape character */ + while( i_index == 8 ) + { + RemoveBits( &p_vpar->bit_stream, 11 ); + i_addr_inc += 33; + i_index = ShowBits( &p_vpar->bit_stream, 11 ); + } + + /* Affect the value from the lookup table */ + i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value; + + /* Dump the good number of bits */ + RemoveBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length ); + + return i_addr_inc; +} + +/***************************************************************************** + * MacroblockModes : Get the macroblock_modes structure + *****************************************************************************/ +static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, + macroblock_t * p_mb ) +{ + static f_motion_t pf_motion[2][4] = + { {NULL, vdec_MotionFieldField, vdec_MotionField16x8, vdec_MotionFieldDMV}, + {NULL, vdec_MotionFrameField, vdec_MotionFrameFrame, vdec_MotionFrameDMV} }; + static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} }; + static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} }; + + /* Get macroblock_type. */ + p_vpar->mb.i_mb_type = (p_vpar->picture.pf_macroblock_type)( p_vpar ); + p_mb->i_mb_type = p_vpar->mb.i_mb_type; + + /* SCALABILITY : warning, we don't know if spatial_temporal_weight_code + * has to be dropped, take care if you use scalable streams. */ + /* RemoveBits( &p_vpar->bit_stream, 2 ); */ + + if( !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) ) + { + /* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this + * is useless, but also harmless. */ + p_vpar->mb.i_motion_type = MOTION_FRAME; + } + else + { + if( p_vpar->picture.i_structure == FRAME_STRUCTURE + && p_vpar->picture.b_frame_pred_frame_dct ) + { + p_vpar->mb.i_motion_type = MOTION_FRAME; + } + else + { + p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 ); + } + } + + if( p_mb->b_P_coding_type && !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) ) + { + /* Special No-MC macroblock in P pictures (7.6.3.5). */ + memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); + memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) ); + + p_vpar->mb.i_motion_type = MOTION_FRAME; + p_mb->ppi_field_select[0][0] = ( p_vpar->picture.i_current_structure == BOTTOM_FIELD ); + } + + if( p_vpar->mb.i_mb_type & MB_INTRA ) + { + /* For the intra macroblocks, we use an empty motion + * compensation function */ + p_mb->pf_motion = vdec_MotionDummy; + } + else + { + p_mb->pf_motion = pf_motion[p_vpar->picture.b_frame_structure] + [p_vpar->mb.i_motion_type]; + } + p_vpar->mb.i_mv_count = ppi_mv_count[p_vpar->picture.b_frame_structure] + [p_vpar->mb.i_motion_type]; + p_vpar->mb.i_mv_format = ppi_mv_format[p_vpar->picture.b_frame_structure] + [p_vpar->mb.i_motion_type]; + + p_vpar->mb.b_dct_type = 0; + if( (p_vpar->picture.i_structure == FRAME_STRUCTURE) && + (!p_vpar->picture.b_frame_pred_frame_dct) && + (p_vpar->mb.i_mb_type & (MB_PATTERN|MB_INTRA)) ) + { + if( (p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 )) ) + { + /* The DCT is coded on fields. Jump one line between each + * sample. */ + p_mb->i_addb_l_stride <<= 1; + p_mb->i_addb_l_stride += 8; + /* With CHROMA_420, the DCT is necessarily frame-coded. */ + if( p_vpar->sequence.i_chroma_format != CHROMA_420 ) + { + p_mb->i_addb_c_stride <<= 1; + p_mb->i_addb_c_stride += 8; + } + } + } + p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV; +} + /***************************************************************************** * vpar_ParseMacroblock : Parse the next macroblock *****************************************************************************/ @@ -554,24 +735,29 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8}; static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8}, {0,0,1,1,0,0,1,1,0,0,1,1} }; - static int pi_chroma_hor[4] = { 0, 1, 1, 0 }; - static int pi_chroma_ver[4] = { 0, 1, 0, 0 }; int i_mb, i_b, i_mask; macroblock_t * p_mb; f_addb_t pf_addb; - elem_t * p_data1; - elem_t * p_data2; + yuv_data_t * p_data1; + yuv_data_t * p_data2; + + /************* DEBUG *************/ + int i_inc; + static int i_count; +i_count++; - *pi_mb_address += MacroblockAddressIncrement( p_vpar ); + i_inc = MacroblockAddressIncrement( p_vpar ); + *pi_mb_address += i_inc; + //*pi_mb_address += MacroblockAddressIncrement( p_vpar ); - for( i_mb = i_mb_previous; i_mb < *pi_mb_address; i_mb++ ) + for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ ) { /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */ static int pi_dc_dct_reinit[4] = {128,256,512,1024}; - static f_motion_t pf_motion_skipped[4] = {NULL, vdec_MotionField, - vdec_MotionField, vdec_MotionFrame}; - + static f_motion_t pf_motion_skipped[4] = {NULL, vdec_MotionFieldField, + vdec_MotionFieldField, vdec_MotionFrameFrame}; +fprintf(stderr, "On sauuuute !\n"); /* Reset DC predictors (7.2.1). */ p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1] = p_vpar->slice.pi_dc_dct_pred[2] @@ -580,14 +766,14 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, if( p_vpar->picture.i_coding_type == P_CODING_TYPE ) { /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */ - bzero( p_vpar->slice.pppi_pmv, 8*sizeof(int) ); + memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); } if( (p_mb = p_vpar->picture.pp_mb[i_mb_base + i_mb] = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL ) { p_vpar->picture.b_error = 1; - intf_ErrMsg("vpar error: macroblock list is empty !"); + intf_ErrMsg("vpar error: macroblock list is empty !\n"); return; } @@ -602,13 +788,11 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, /* Motion type is picture structure. */ p_mb->pf_motion = pf_motion_skipped[p_vpar->picture.i_structure]; + p_mb->i_mb_type = MB_MOTION_FORWARD; /* Set the field we use for motion compensation */ p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1] = ( p_vpar->picture.i_current_structure == BOTTOM_FIELD ); - - /* Predict from field of same parity. */ - /* ??? */ } /* Get a macroblock structure. */ @@ -616,7 +800,7 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, vpar_NewMacroblock( &p_vpar->vfifo )) == NULL ) { p_vpar->picture.b_error = 1; - intf_ErrMsg("vpar error: macroblock list is empty !"); + intf_ErrMsg("vpar error: macroblock list is empty !\n"); return; } @@ -632,48 +816,66 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, if( p_vpar->mb.i_mb_type & MB_MOTION_FORWARD ) { +//fprintf( stderr, "motion !\n" ); (*p_vpar->sequence.pf_decode_mv)( p_vpar, p_mb, 0 ); } if( p_vpar->mb.i_mb_type & MB_MOTION_BACKWARD ) { +//fprintf( stderr, "motion2 !\n" ); (*p_vpar->sequence.pf_decode_mv)( p_vpar, p_mb, 1 ); } if( p_vpar->picture.b_concealment_mv && (p_vpar->mb.i_mb_type & MB_INTRA) ) { - DumpBits( &p_vpar->bit_stream, 1 ); + RemoveBits( &p_vpar->bit_stream, 1 ); } +if( 0 ) + //i_count == 1231 && + // i_count != *pi_mb_address) + //p_vpar->picture.i_coding_type == P_CODING_TYPE ) +{ + fprintf( stderr, "i_count = %d (%d)\n", i_count, p_vpar->mb.i_mb_type ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); + exit(0); +} if( p_vpar->mb.i_mb_type & MB_PATTERN ) { - (*p_vpar->sequence.pf_decode_pattern)( p_vpar ); + p_vpar->mb.i_coded_block_pattern = (*p_vpar->sequence.pf_decode_pattern)( p_vpar ); +//fprintf( stderr, "pattern : %d\n", p_vpar->mb.i_coded_block_pattern ); } else { int pi_coded_block_pattern[2] = {0, - (1 << 4+2*p_vpar->sequence.i_chroma_nb_blocks) - 1}; + (1 << (4+p_vpar->sequence.i_chroma_nb_blocks)) - 1}; p_vpar->mb.i_coded_block_pattern = pi_coded_block_pattern [p_vpar->mb.i_mb_type & MB_INTRA]; } - pf_addb = ppf_addb_intra[p_vpar->mb.i_mb_type & MB_INTRA]; /* * Effectively decode blocks. */ - i_mask = 1 << (3 + 2*p_vpar->sequence.i_chroma_nb_blocks); + i_mask = 1 << (3 + p_vpar->sequence.i_chroma_nb_blocks); /* luminance */ - p_data1 = (elem_t*) p_mb->p_picture->p_y; - // + p_mb->i_l_x + p_mb->i_l_y*(p_vpar->sequence.i_width); + p_data1 = p_mb->p_picture->p_y + + p_mb->i_l_x + p_mb->i_l_y*(p_vpar->sequence.i_width); for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) { if( p_vpar->mb.i_coded_block_pattern & i_mask ) { - memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(elem_t) ); + memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); (*pppf_decode_block[p_vpar->sequence.b_mpeg2] [p_vpar->mb.i_mb_type & MB_INTRA]) ( p_vpar, p_mb, i_b ); @@ -683,8 +885,9 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, /* Calculate block coordinates. */ p_mb->p_data[i_b] = p_data1 - + pi_y[p_vpar->mb.b_dct_type][i_b] - * p_vpar->sequence.i_chroma_width; + + pi_y[p_vpar->mb.b_dct_type][i_b] + * p_vpar->sequence.i_width + + pi_x[i_b]; } else { @@ -694,24 +897,24 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, } } - /* chrominance U */ - p_data1 = (elem_t*) p_mb->p_picture->p_u - + (p_mb->i_c_x >> pi_chroma_hor[p_vpar->sequence.i_chroma_format]) - + (p_mb->i_c_y >> pi_chroma_ver[p_vpar->sequence.i_chroma_format]) + /* chrominance */ + p_data1 = p_mb->p_picture->p_u + + p_mb->i_c_x + + p_mb->i_c_y * (p_vpar->sequence.i_chroma_width); - p_data2 = (elem_t*) p_mb->p_picture->p_v - + (p_mb->i_c_x >> pi_chroma_hor[p_vpar->sequence.i_chroma_format]) - + (p_mb->i_c_y >> pi_chroma_ver[p_vpar->sequence.i_chroma_format]) + p_data2 = p_mb->p_picture->p_v + + p_mb->i_c_x + + p_mb->i_c_y * (p_vpar->sequence.i_chroma_width); - - for( i_b = 4; i_b < 4 + 2*p_vpar->sequence.i_chroma_nb_blocks; + + for( i_b = 4; i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks; i_b++, i_mask >>= 1 ) { - elem_t * pp_data[2] = {p_data1, p_data2}; + yuv_data_t * pp_data[2] = {p_data1, p_data2}; if( p_vpar->mb.i_coded_block_pattern & i_mask ) { - memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(elem_t) ); + memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); (*pppf_decode_block[p_vpar->sequence.b_mpeg2] [p_vpar->mb.i_mb_type & MB_INTRA]) ( p_vpar, p_mb, i_b ); @@ -722,7 +925,8 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, /* Calculate block coordinates. */ p_mb->p_data[i_b] = pp_data[i_b & 1] + pi_y[p_vpar->mb.b_dct_type][i_b] - * p_vpar->sequence.i_chroma_width; + * p_vpar->sequence.i_chroma_width + + pi_x[i_b]; } else { @@ -744,146 +948,35 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, else if( !p_vpar->picture.b_concealment_mv ) { /* Reset MV predictors. */ - bzero( p_vpar->slice.pppi_pmv, 8*sizeof(int) ); + memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); } -} - -/***************************************************************************** - * InitMacroblock : Initialize macroblock values - *****************************************************************************/ -static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, - macroblock_t * p_mb ) -{ - static f_chroma_motion_t pf_chroma_motion[4] = - { NULL, vdec_Motion420, vdec_Motion422, vdec_Motion444 }; - - p_mb->p_picture = p_vpar->picture.p_picture; - p_mb->i_structure = p_vpar->picture.i_structure; - p_mb->i_l_x = p_vpar->mb.i_l_x; - p_mb->i_l_y = p_vpar->mb.i_l_y; - p_mb->i_c_x = p_vpar->mb.i_c_x; - p_mb->i_c_y = p_vpar->mb.i_c_y; - p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks; - p_mb->pf_chroma_motion = pf_chroma_motion[p_vpar->sequence.i_chroma_format]; - - p_mb->p_forward = p_vpar->sequence.p_forward; - p_mb->p_backward = p_vpar->sequence.p_backward; - - p_mb->i_addb_l_stride = p_mb->i_l_stride = p_vpar->picture.i_l_stride; - p_mb->i_addb_c_stride = p_mb->i_c_stride = p_vpar->picture.i_c_stride; - /* Update macroblock real position. */ - p_vpar->mb.i_l_x += 16; - p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width) - * (2 - p_vpar->picture.b_frame_structure) * 16; - p_vpar->mb.i_l_x %= p_vpar->sequence.i_width; - - p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width; - p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width) - * (2 - p_vpar->picture.b_frame_structure) - * p_vpar->sequence.i_chroma_mb_height; - p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width; -} - -/***************************************************************************** - * MacroblockAddressIncrement : Get the macroblock_address_increment field - *****************************************************************************/ -static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) -{ - /* Index in the lookup table mb_addr_inc */ - int i_index = ShowBits( &p_vpar->bit_stream, 11 ); - p_vpar->mb.i_addr_inc = 0; - /* Test the presence of the escape character */ - while( i_index == 8 ) + if( p_mb->b_P_coding_type && !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) ) { - DumpBits( &p_vpar->bit_stream, 11 ); - p_vpar->mb.i_addr_inc += 33; - i_index = ShowBits( &p_vpar->bit_stream, 11 ); + p_mb->i_mb_type |= MB_MOTION_FORWARD; } - /* Affect the value from the lookup table */ - p_vpar->mb.i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value; - /* Dump the good number of bits */ - DumpBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length ); +/* +if( p_vpar->picture.i_coding_type != I_CODING_TYPE )//!(p_mb->b_P_coding_type & MB_INTRA) ) +{ + p_mb->i_mb_type |= MB_MOTION_FORWARD; } - -/***************************************************************************** - * MacroblockModes : Get the macroblock_modes structure - *****************************************************************************/ -static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, - macroblock_t * p_mb ) +*/ + if( 0 ) + //i_count == 249) + // i_count != *pi_mb_address) + //b_stop ) { - static f_motion_t pf_motion[2][4] = - { {NULL, vdec_FieldRecon, vdec_16x8Recon, vdec_DMVRecon}, - {NULL, vdec_FieldRecon, vdec_FrameRecon, vdec_DMVRecon} }; - static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} }; - static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} }; - - /* Get macroblock_type. */ - p_vpar->mb.i_mb_type = (p_vpar->picture.pf_macroblock_type)( p_vpar ); - - /* SCALABILITY : warning, we don't know if spatial_temporal_weight_code - * has to be dropped, take care if you use scalable streams. */ - /* DumpBits( &p_vpar->bit_stream, 2 ); */ - - if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) && - !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) ) - { - /* Special No-MC macroblock in P pictures (7.6.3.5). */ - memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); - memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) ); - - p_vpar->mb.i_motion_type = MOTION_FRAME; - p_mb->ppi_field_select[0][0] = ( p_vpar->picture.i_current_structure == BOTTOM_FIELD ); - } - else if( !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) - || p_vpar->picture.b_frame_pred_frame_dct ) - { - /* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this - * is useless, but also harmless. */ - p_vpar->mb.i_motion_type = MOTION_FRAME; - } - else - { - p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 ); - } - - if( p_vpar->mb.i_mb_type & MB_INTRA ) - { - /* For the intra macroblocks, we use an empty motion - * compensation function */ - p_mb->pf_motion = vdec_DummyRecon; - } - else - { - p_mb->pf_motion = pf_motion[p_vpar->picture.b_frame_structure] - [p_vpar->mb.i_motion_type]; - } - p_vpar->mb.i_mv_count = ppi_mv_count[p_vpar->picture.b_frame_structure] - [p_vpar->mb.i_motion_type]; - p_vpar->mb.i_mv_format = ppi_mv_format[p_vpar->picture.b_frame_structure] - [p_vpar->mb.i_motion_type]; - - p_vpar->mb.b_dct_type = 0; - if( (p_vpar->picture.i_structure == FRAME_STRUCTURE) && - (!p_vpar->picture.b_frame_pred_frame_dct) && - (p_vpar->mb.i_mb_type & (MB_PATTERN|MB_INTRA)) ) - { - if( p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 ) ) - { - /* The DCT is coded on fields. Jump one line between each - * sample. */ - p_mb->i_addb_l_stride <<= 1; - p_mb->i_addb_l_stride += 8; - /* With CHROMA_420, the DCT is necessarily frame-coded. */ - if( p_vpar->sequence.i_chroma_format != CHROMA_420 ) - { - p_mb->i_addb_c_stride <<= 1; - p_mb->i_addb_c_stride += 8; - } - } - } - - p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV; + fprintf( stderr, "i_count = %d (%d)\n", i_count, i_inc ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); + fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); + exit(0); +} } /***************************************************************************** @@ -893,13 +986,14 @@ int vpar_IMBType( vpar_thread_t * p_vpar ) { /* Take two bits for testing */ int i_type = ShowBits( &p_vpar->bit_stream, 2 ); + /* Lookup table for macroblock_type */ static lookup_t pl_mb_Itype[4] = { {MB_ERROR, 0}, {MB_QUANT|MB_INTRA, 2}, {MB_INTRA, 1}, - {MB_INTRA, 2} }; + {MB_INTRA, 1} }; /* Dump the good number of bits */ - DumpBits( &p_vpar->bit_stream, pl_mb_Itype[i_type].i_length ); + RemoveBits( &p_vpar->bit_stream, pl_mb_Itype[i_type].i_length ); return pl_mb_Itype[i_type].i_value; } @@ -910,8 +1004,46 @@ int vpar_PMBType( vpar_thread_t * p_vpar ) { /* Testing on 6 bits */ int i_type = ShowBits( &p_vpar->bit_stream, 6 ); + +#if 0 +/* Table B-3, macroblock_type in P-pictures, codes 001..1xx */ +static lookup_t PMBtab0[8] = { + {-1,0}, + {MB_MOTION_FORWARD,3}, + {MB_PATTERN,2}, {MB_PATTERN,2}, + {MB_MOTION_FORWARD|MB_PATTERN,1}, + {MB_MOTION_FORWARD|MB_PATTERN,1}, + {MB_MOTION_FORWARD|MB_PATTERN,1}, + {MB_MOTION_FORWARD|MB_PATTERN,1} +}; + +/* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */ +static lookup_t PMBtab1[8] = { + {-1,0}, + {MB_QUANT|MB_INTRA,6}, + {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5}, + {MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN,5}, + {MB_INTRA,5}, {MB_INTRA,5} +}; + + + if(i_type >= 8) + { + i_type >>= 3; + RemoveBits( &p_vpar->bit_stream,PMBtab0[i_type].i_length ); + return PMBtab0[i_type].i_value; + } + + if (i_type==0) + { + printf("Invalid P macroblock_type code\n"); + return -1; + } + RemoveBits( &p_vpar->bit_stream,PMBtab1[i_type].i_length ); + return PMBtab1[i_type].i_value; +#endif /* Dump the good number of bits */ - DumpBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length ); + RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length ); /* return the value from the lookup table for P type */ return p_vpar->ppl_mb_type[0][i_type].i_value; } @@ -923,8 +1055,10 @@ int vpar_BMBType( vpar_thread_t * p_vpar ) { /* Testing on 6 bits */ int i_type = ShowBits( &p_vpar->bit_stream, 6 ); + /* Dump the good number of bits */ - DumpBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[1][i_type].i_length ); + RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[1][i_type].i_length ); + /* return the value from the lookup table for B type */ return p_vpar->ppl_mb_type[1][i_type].i_value; } @@ -936,8 +1070,10 @@ int vpar_DMBType( vpar_thread_t * p_vpar ) { /* Taking 1 bit */ int i_type = GetBits( &p_vpar->bit_stream, 1 ); + /* Lookup table */ static int pi_mb_Dtype[2] = { MB_ERROR, 1 }; + return pi_mb_Dtype[i_type]; } @@ -948,8 +1084,10 @@ int vpar_CodedPattern420( vpar_thread_t * p_vpar ) { /* Take the max 9 bits length vlc code for testing */ int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); + /* Trash the good number of bits read in the lookup table */ - DumpBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); + RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); + /* return the value from the vlc table */ return p_vpar->pl_coded_pattern[i_vlc].i_value; } @@ -960,10 +1098,13 @@ int vpar_CodedPattern420( vpar_thread_t * p_vpar ) int vpar_CodedPattern422( vpar_thread_t * p_vpar ) { int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); + /* Supplementary 2 bits long code for 422 format */ int i_coded_block_pattern_1; - DumpBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); + + RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); i_coded_block_pattern_1 = GetBits( &p_vpar->bit_stream, 2 ); + /* the code is just to be added to the value found in the table */ return p_vpar->pl_coded_pattern[i_vlc].i_value | (i_coded_block_pattern_1 << 6); @@ -976,8 +1117,10 @@ int vpar_CodedPattern444( vpar_thread_t * p_vpar ) { int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); int i_coded_block_pattern_2; - DumpBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); + + RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); i_coded_block_pattern_2 = GetBits( &p_vpar->bit_stream, 6 ); + return p_vpar->pl_coded_pattern[i_vlc].i_value | ( i_coded_block_pattern_2 << 6 ); } @@ -987,18 +1130,12 @@ int vpar_CodedPattern444( vpar_thread_t * p_vpar ) *****************************************************************************/ static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) { - /* À pomper dans Berkeley. Pour toutes ces fonctions, il faut mettre - p_mb->pf_idct[i_b] à : - - vdec_IDCT ou - - vdec_SparseIDCT si la matrice n'a qu'un coefficient non nul. - Dans le deuxième cas, p_mb->pi_sparse_pos[i_b] contient le numéro - de ce coefficient. */ if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) { /* Remove end_of_macroblock (always 1, prevents startcode emulation) * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ - DumpBits( &p_vpar->bit_stream, 1 ); + RemoveBits( &p_vpar->bit_stream, 1 ); } } @@ -1007,13 +1144,12 @@ static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, in *****************************************************************************/ static void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) { - /* À pomper dans Berkeley. */ if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) { /* Remove end_of_macroblock (always 1, prevents startcode emulation) * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ - DumpBits( &p_vpar->bit_stream, 1 ); + RemoveBits( &p_vpar->bit_stream, 1 ); } } @@ -1022,7 +1158,111 @@ static void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, *****************************************************************************/ static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) { - /* À pomper dans Berkeley. Bien sûr les matrices seront différentes... */ + int i_parse; + int i_nc; + int i_cc; + int i_coef; + int i_type; + int i_code; + int i_length; + int i_pos; + int i_run; + int i_level; + boolean_t b_sign; + int * ppi_quant[2]; + + /* Lookup Table for the chromatic component */ + static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 }; + + i_cc = pi_cc_index[i_b]; + + /* Determine whether it is luminance or not (chrominance) */ + i_type = ( i_cc + 1 ) >> 1; + + /* Give a pointer to the quantization matrices for intra blocks */ + ppi_quant[0] = p_vpar->sequence.nonintra_quant.pi_matrix; + ppi_quant[1] = p_vpar->sequence.chroma_nonintra_quant.pi_matrix; + + /* Decoding of the AC coefficients */ + + i_nc = 0; + i_coef = 0; + for( i_parse = 0; ; i_parse++ ) + { + i_code = ShowBits( &p_vpar->bit_stream, 16 ); + if( i_code >= 16384 ) + { + if( i_parse == 0 ) + { + i_run = pl_DCT_tab_dc[(i_code>>12)-4].i_run; + i_level = pl_DCT_tab_dc[(i_code>>12)-4].i_level; + i_length = pl_DCT_tab_dc[(i_code>>12)-4].i_length; + } + else + { + i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run; + i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level; + i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length; + } + } + else if( i_code >= 1024 ) + { + i_run = pl_DCT_tab0[(i_code>>8)-4].i_run; + i_length = pl_DCT_tab0[(i_code>>8)-4].i_length; + i_level = pl_DCT_tab0[(i_code>>8)-4].i_level; + } + else + { + i_run = ppl_dct_coef[0][i_code].i_run; + i_length = ppl_dct_coef[0][i_code].i_length; + i_level = ppl_dct_coef[0][i_code].i_level; + } + + + RemoveBits( &p_vpar->bit_stream, i_length ); + + switch( i_run ) + { + case DCT_ESCAPE: + i_run = GetBits( &p_vpar->bit_stream, 6 ); + i_level = GetBits( &p_vpar->bit_stream, 12 ); + i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level + : i_level; + break; + case DCT_EOB: + if( i_nc <= 1 ) + { + p_mb->pf_idct[i_b] = vdec_SparseIDCT; + p_mb->pi_sparse_pos[i_b] = i_coef; + } + else + { + p_mb->pf_idct[i_b] = vdec_IDCT; + } + return; + + break; + default: + b_sign = GetBits( &p_vpar->bit_stream, 1 ); + } + i_coef = i_parse; + i_parse += i_run; + i_nc ++; + +if( i_parse >= 64 ) +{ + break; +} + + i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse]; + i_level = ( i_level * + p_vpar->slice.i_quantizer_scale * + ppi_quant[i_type][i_pos] ) >> 5; + p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; + } +fprintf( stderr, "Non intra MPEG2 end (%d)\n", i_b ); +exit(0); +//p_vpar->picture.b_error = 1; } /***************************************************************************** @@ -1030,115 +1270,238 @@ static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, in *****************************************************************************/ static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) { - int i_dummy; + int i_parse; int i_nc; int i_cc; int i_coef; - int i_type; + int i_type, i_quant_type; int i_code; - int i_code5; - int i_select; - int i_offset; + int i_length; int i_pos; int i_dct_dc_size; int i_dct_dc_diff; int i_run; int i_level; - int i_2b; - int i_4b; + boolean_t b_vlc_intra; boolean_t b_sign; + int * ppi_quant[2]; + /* Lookup Table for the chromatic component */ static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 }; - /* Lookup table for the offset in the tables for ac coef decoding */ - static lookup_t pl_offset_table[8] = { { 12, 4 }, { 8, 4 }, { 6, 8 }, - { 4, 16 }, { 3, 16 }, { 2, 16 }, - { 1, 16 }, { 0, 16 } }; - i_cc = pi_cc_index[i_b]; + /* Determine whether it is luminance or not (chrominance) */ i_type = ( i_cc + 1 ) >> 1; + i_quant_type = i_type | (p_vpar->sequence.i_chroma_format == CHROMA_420); + /* Give a pointer to the quantization matrices for intra blocks */ + ppi_quant[0] = p_vpar->sequence.intra_quant.pi_matrix; + ppi_quant[1] = p_vpar->sequence.chroma_intra_quant.pi_matrix; + +#if 0 /* Decoding of the DC intra coefficient */ /* The nb of bits to parse depends on i_type */ i_code = ShowBits( &p_vpar->bit_stream, 9 + i_type ); + /* To reduce memory occupation, there are two lookup tables * See InitDCT above */ - i_code5 = i_code >> 4; + i_code5 = i_code >> (4+i_type); + /* Shall we lookup in the first or in the second table ? */ - i_select = ( i_code5 - 1 ) / 31; + i_select = ( i_code5 == 31 ); /* Offset value for looking in the second table */ i_offset = 0x1f0 + ( i_type * 0x1f0 ); i_pos = ( i_code5 * ( ! i_select ) ) + ( ( i_code - i_offset ) * i_select ); i_dct_dc_size = p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_value; +#endif + + if( !i_type/*i_b < 4*/ ) + { + /* decode length */ + i_code = ShowBits(&p_vpar->bit_stream, 5); + if (i_code<31) + { + i_dct_dc_size = pl_dct_dc_lum_init_table_1[i_code].i_value; + i_length = pl_dct_dc_lum_init_table_1[i_code].i_length; + RemoveBits( &p_vpar->bit_stream, i_length); + } + else + { + i_code = ShowBits(&p_vpar->bit_stream, 9) - 0x1f0; + i_dct_dc_size = pl_dct_dc_lum_init_table_2[i_code].i_value; + i_length = pl_dct_dc_lum_init_table_2[i_code].i_length; + RemoveBits( &p_vpar->bit_stream, i_length); + } + } + else + { + /* decode length */ + i_code = ShowBits(&p_vpar->bit_stream, 5); + + if (i_code<31) + { + i_dct_dc_size = pl_dct_dc_chrom_init_table_1[i_code].i_value; + i_length = pl_dct_dc_chrom_init_table_1[i_code].i_length; + RemoveBits(&p_vpar->bit_stream, i_length); + } + else + { + i_code = ShowBits(&p_vpar->bit_stream, 10) - 0x3e0; + i_dct_dc_size = pl_dct_dc_chrom_init_table_2[i_code].i_value; + i_length = pl_dct_dc_chrom_init_table_2[i_code].i_length; + RemoveBits( &p_vpar->bit_stream, i_length); + } + } + if (i_dct_dc_size==0) + i_dct_dc_diff = 0; + else + { + i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size); + if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1)))==0) + i_dct_dc_diff-= (1<bit_stream, - p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_length ); + //RemoveBits( &p_vpar->bit_stream, + // p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_length ); + /* Read the actual code with the good length */ - i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size ); p_vpar->slice.pi_dc_dct_pred[i_cc] += i_dct_dc_diff; -#ifndef VDEC_DFT + p_mb->ppi_blocks[i_b][0] = ( p_vpar->slice.pi_dc_dct_pred[i_cc] << ( 3 - p_vpar->picture.i_intra_dc_precision ) ); - i_nc = 1; -#else - p_mb->ppi_blocks[i_b][0] = ( p_vpar->slice.pi_dc_dct_pred[i_cc] << - ( 11 - p_vpar->picture.i_intra_dc_precision ) ); i_nc = ( p_vpar->slice.pi_dc_dct_pred[i_cc] != 0 ); -#endif +//fprintf( stderr, "coucou\n" ); /* Decoding of the AC coefficients */ + i_coef = 0; - for( i_dummy = 1; i_dummy < 64; i_dummy++ ) + b_vlc_intra = p_vpar->picture.b_intra_vlc_format; + for( i_parse = 1; /*i_parse < 64*/; i_parse++ ) { i_code = ShowBits( &p_vpar->bit_stream, 16 ); - i_2b = ! ( i_code >> 14 ); - i_4b = ! ( ( i_code & 0x3C00 ) >> 10 ); - /* Will contain the number of table to use in ppl_dct_coef */ - i_select = i_2b + i_4b + ( i_code & 0x0200 ) + ( i_code & 0x0100 ) + - ( i_code & 0x0080 ) + ( i_code & 0x0040 ) + - ( i_code & 0x0020 ) + ( i_code & 0x0010 ); - /* Shall we use B15 table or not */ - i_type = p_vpar->picture.b_intra_vlc_format & ( ( i_select & 3 ) >> 1 ); - i_select += (i_type * 7 ); - i_offset = ( i_code >> pl_offset_table[i_select].i_value ) - - pl_offset_table[i_select].i_length; - i_run = ( * ( p_vpar->ppl_dct_coef[i_select] - + ( i_offset * sizeof(dct_lookup_t) ) ) ).i_run; - DumpBits( &p_vpar->bit_stream, - ( * ( p_vpar->ppl_dct_coef[i_select] - + ( i_offset * sizeof(dct_lookup_t) ) ) ).i_length ); + if( i_code >= 16384 ) + { + if( b_vlc_intra ) + { + i_run = pl_DCT_tab0a[(i_code>>8)-4].i_run; + i_level = pl_DCT_tab0a[(i_code>>8)-4].i_level; + i_length = pl_DCT_tab0a[(i_code>>8)-4].i_length; +//fprintf( stderr, "**********> %d, %d, %d *******\n", i_run, i_level, (i_code>>8)-4 ); + } + else + { + i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run; + i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level; + i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length; + } + } + else + { + i_run = ppl_dct_coef[b_vlc_intra][i_code].i_run; + i_length = ppl_dct_coef[b_vlc_intra][i_code].i_length; + i_level = ppl_dct_coef[b_vlc_intra][i_code].i_level; + } + +#if 0 + { + int code = i_code; + int intra_vlc_format = b_vlc_intra; + dct_lookup_t tab; + + if (code>=16384 && !intra_vlc_format) + tab = pl_DCT_tab_ac[(code>>12)-4]; + else if (code>=1024) + { + if (intra_vlc_format) + tab = pl_DCT_tab0a[(code>>8)-4]; + else + tab = pl_DCT_tab0[(code>>8)-4]; + } + else if (code>=512) + { + if (intra_vlc_format) + tab = pl_DCT_tab1a[(code>>6)-8]; + else + tab = pl_DCT_tab1[(code>>6)-8]; + } + else if (code>=256) + tab = pl_DCT_tab2[(code>>4)-16]; + else if (code>=128) + tab = pl_DCT_tab3[(code>>3)-16]; + else if (code>=64) + tab = pl_DCT_tab4[(code>>2)-16]; + else if (code>=32) + tab = pl_DCT_tab5[(code>>1)-16]; + else if (code>=16) + tab = pl_DCT_tab6[code-16]; + else + { + fprintf( stderr, "invalid Huffman code in Decode_MPEG2_Intra_Block()\n"); + } + + if( (i_run != tab.i_run) || (i_length != tab.i_length) || (i_level != tab.i_level) ) + { + fprintf( stderr, "ET M....... !!!\n" ); + exit(0); + } + } +#endif + + + + + RemoveBits( &p_vpar->bit_stream, i_length ); + switch( i_run ) { case DCT_ESCAPE: i_run = GetBits( &p_vpar->bit_stream, 6 ); i_level = GetBits( &p_vpar->bit_stream, 12 ); - p_mb->ppi_blocks[i_b][i_dummy] = ( b_sign = ( i_level > 2047 ) ) + /*p_mb->ppi_blocks[i_b][i_parse] = ( b_sign = ( i_level > 2047 ) ) ? ( -4096 + i_level ) - : i_level; - i_coef = i_dummy; - i_dummy += i_run; - i_nc ++; + : i_level;*/ + i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level + : i_level; break; case DCT_EOB: - i_dummy = 64; + if( i_nc <= 1 ) + { + p_mb->pf_idct[i_b] = vdec_SparseIDCT; + p_mb->pi_sparse_pos[i_b] = i_coef; + } + else + { + p_mb->pf_idct[i_b] = vdec_IDCT; + } + return; + break; default: - i_level = ( * ( p_vpar->ppl_dct_coef[i_select] - + ( i_offset * sizeof(dct_lookup_t) ) ) ).i_level; - b_sign = Getbits( &p_vpar->bit_stream, 1 ); - p_mb->ppi_blocks[i_b][i_dummy] = b_sign ? -i_level : i_level; - i_coef = i_dummy; - i_dummy += i_run; - i_nc ++; + b_sign = GetBits( &p_vpar->bit_stream, 1 ); + //p_mb->ppi_blocks[i_b][i_parse] = b_sign ? -i_level : i_level; } +// fprintf( stderr, "i_code : %d (%d), run : %d, %d, %d (%4x) ", i_code , b_vlc_intra, +// i_run, i_level, i_parse, ShowBits( &p_vpar->bit_stream, 16 ) ); + +//fprintf( stderr, "- %4x\n",ShowBits( &p_vpar->bit_stream, 16 ) ); +if( i_parse >= 64 ) +{ + fprintf( stderr, "Beuhh dans l'intra decode (%d)\n", i_b ); + break; +} + i_coef = i_parse; + i_parse += i_run; + i_nc ++; + + i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse]; + i_level = ( i_level * + p_vpar->slice.i_quantizer_scale * + ppi_quant[i_quant_type][i_pos] ) >> 4; + p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; } - if( i_nc == 1 ) - { - p_mb->pf_idct[i_b] = vdec_SparseIDCT; - p_mb->pi_sparse_pos[i_b] = i_coef; - } - else - { - p_mb->pf_idct[i_b] = vdec_IDCT; - } + +fprintf( stderr, "MPEG2 end (%d)\n", i_b ); +exit(0); +//p_vpar->b_error = 1; }