📄 vpar_blocks.c
字号:
*****************************************************************************/static 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;}/***************************************************************************** * IMBType : macroblock_type in I pictures *****************************************************************************/static int 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, 1} }; /* Dump the good number of bits */ RemoveBits( &p_vpar->bit_stream, pl_mb_Itype[i_type].i_length ); return pl_mb_Itype[i_type].i_value;}/***************************************************************************** * PMBType : macroblock_type in P pictures *****************************************************************************/static int PMBType( vpar_thread_t * p_vpar ){ /* Testing on 6 bits */ int i_type = ShowBits( &p_vpar->bit_stream, 6 ); /* Dump the good number of bits */ 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;}/***************************************************************************** * BMBType : macroblock_type in B pictures *****************************************************************************/static int 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 */ 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;}/***************************************************************************** * DMBType : macroblock_type in D pictures *****************************************************************************/static int DMBType( vpar_thread_t * p_vpar ){ return GetBits( &p_vpar->bit_stream, 1 );}/***************************************************************************** * CodedPattern420 : coded_block_pattern with 4:2:0 chroma *****************************************************************************/static int 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 */ RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); /* return the value from the vlc table */ return pl_coded_pattern[i_vlc].i_value;}/***************************************************************************** * CodedPattern422 : coded_block_pattern with 4:2:2 chroma *****************************************************************************/static int CodedPattern422( vpar_thread_t * p_vpar ){ int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); /* Supplementary 2 bits long code for 4:2:2 format */ return pl_coded_pattern[i_vlc].i_value | (GetBits( &p_vpar->bit_stream, 2 ) << 6);}/***************************************************************************** * CodedPattern444 : coded_block_pattern with 4:4:4 chroma *****************************************************************************/static int CodedPattern444( vpar_thread_t * p_vpar ){ int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); return pl_coded_pattern[i_vlc].i_value | (GetBits( &p_vpar->bit_stream, 6 ) << 6);}/***************************************************************************** * InitMacroblock : Initialize macroblock values *****************************************************************************/static void InitMacroblock( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_coding_type, int i_chroma_format, int i_structure, boolean_t b_second_field ){ p_mb->i_chroma_nb_blocks = 1 << i_chroma_format; p_mb->p_picture = p_vpar->picture.p_picture; if( i_coding_type == B_CODING_TYPE ) p_mb->p_backward = p_vpar->sequence.p_backward; else p_mb->p_backward = NULL; if( (i_coding_type == P_CODING_TYPE) || (i_coding_type == B_CODING_TYPE) ) p_mb->p_forward = p_vpar->sequence.p_forward; else p_mb->p_forward = NULL; p_mb->i_l_x = p_vpar->mb.i_l_x; p_mb->i_c_x = p_vpar->mb.i_c_x; p_mb->i_motion_l_y = p_vpar->mb.i_l_y; p_mb->i_motion_c_y = p_vpar->mb.i_c_y; if( (p_mb->b_motion_field = (i_structure == BOTTOM_FIELD)) ) { p_mb->i_motion_l_y--; p_mb->i_motion_c_y--; } 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; p_mb->b_P_second = ( b_second_field && i_coding_type == P_CODING_TYPE );}/***************************************************************************** * UpdateContext : Update the p_vpar contextual values *****************************************************************************/static void UpdateContext( vpar_thread_t * p_vpar, int i_structure ){ /* 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 - (i_structure == 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 - (i_structure == FRAME_STRUCTURE)) * p_vpar->sequence.i_chroma_mb_height; p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width;}/***************************************************************************** * SkippedMacroblock : Generate a skipped macroblock with NULL motion vector *****************************************************************************/static void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, int i_mb_base, int i_coding_type, int i_chroma_format, int i_structure, boolean_t b_second_field ){ macroblock_t * p_mb; static f_motion_t pf_motion_skipped[4][4] = { {NULL, NULL, NULL, NULL}, {NULL, vdec_MotionFieldField420, vdec_MotionFieldField420, vdec_MotionFrameFrame420}, {NULL, vdec_MotionFieldField422, vdec_MotionFieldField422, vdec_MotionFrameFrame422}, {NULL, vdec_MotionFieldField444, vdec_MotionFieldField444, vdec_MotionFrameFrame444}, }; if( i_coding_type == I_CODING_TYPE ) { intf_DbgMsg("vpar error: skipped macroblock in I-picture\n"); p_vpar->picture.b_error = 1; return; } if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL ) { /* b_die == 1 */ return; }#ifdef VDEC_SMP p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;#endif InitMacroblock( p_vpar, p_mb, i_coding_type, i_chroma_format, i_structure, b_second_field ); /* Motion type is picture structure. */ p_mb->pf_motion = pf_motion_skipped[i_chroma_format] [i_structure]; p_mb->i_mb_type = MB_MOTION_FORWARD; p_mb->i_coded_block_pattern = 0; memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) ); /* Set the field we use for motion compensation */ p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1] = ( i_structure == BOTTOM_FIELD ); UpdateContext( p_vpar, i_structure );#ifndef VDEC_SMP /* Decode the macroblock NOW ! */ vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );#endif}/***************************************************************************** * MacroblockModes : Get the macroblock_modes structure *****************************************************************************/static void MacroblockModes( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_chroma_format, int i_coding_type, int i_structure ){ 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. */ switch( i_coding_type ) { case P_CODING_TYPE: p_mb->i_mb_type = PMBType( p_vpar ); break; case B_CODING_TYPE: p_mb->i_mb_type = BMBType( p_vpar ); break; case I_CODING_TYPE: p_mb->i_mb_type = IMBType( p_vpar ); break; case D_CODING_TYPE: p_mb->i_mb_type = DMBType( p_vpar ); } /* 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( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE) && (p_mb->i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) ) { if( !(i_structure == FRAME_STRUCTURE && p_vpar->picture.b_frame_pred_frame_dct) ) { p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 ); } else { p_vpar->mb.i_motion_type = MOTION_FRAME; } /* XXX?? */ p_vpar->mb.i_mv_count = ppi_mv_count[i_structure == FRAME_STRUCTURE] [p_vpar->mb.i_motion_type]; p_vpar->mb.i_mv_format = ppi_mv_format[i_structure == FRAME_STRUCTURE] [p_vpar->mb.i_motion_type]; p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV; } p_vpar->mb.b_dct_type = 0; if( (i_structure == FRAME_STRUCTURE) && (!p_vpar->picture.b_frame_pred_frame_dct) && (p_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( i_chroma_format != CHROMA_420 ) { p_mb->i_addb_c_stride <<= 1; p_mb->i_addb_c_stride += 8; } } }}/***************************************************************************** * ParseMacroblock : Parse the next macroblock *****************************************************************************/#define PARSEERROR \if( p_vpar->picture.b_error ) \{ \ /* Mark this block as skipped (better than green blocks), and \ * go to the next slice. */ \ (*pi_mb_address)--; \ vpar_DestroyMacroblock( &p_vpar->vfifo, p_mb ); \ return; \}#define PARSEBLOCKS( MPEG1FUNC, MPEG2FUNC ) \{ \ i_mask = 1 << (3 + (1 << i_chroma_format)); \ \ /* luminance */ \ p_data1 = p_mb->p_picture->p_y \ + p_mb->i_l_x + p_vpar->mb.i_l_y*(p_vpar->sequence.i_width); \ \ for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) \ { \ if( p_mb->i_coded_block_pattern & i_mask ) \ { \ memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \ if( b_mpeg2 ) \ MPEG2FUNC( p_vpar, p_mb, i_b, i_chroma_format ); \ else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -