transrate.c
来自「VLC媒体播放程序」· C语言 代码 · 共 2,148 行 · 第 1/5 页
C
2,148 行
tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16); bs_flush( bs, 16 ); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } bs_flush( bs, 2 ); /* dump end of block code */ blk->level = 0; return i;}static void motion_fr_frame( bs_transrate_t *bs, unsigned int f_code[2] ){ get_motion_delta( bs, f_code[0] ); get_motion_delta( bs, f_code[1] );}static void motion_fr_field( bs_transrate_t *bs, unsigned int f_code[2] ){ bs_copy( bs, 1); get_motion_delta( bs, f_code[0]); get_motion_delta( bs, f_code[1]); bs_copy( bs, 1); get_motion_delta( bs, f_code[0]); get_motion_delta( bs, f_code[1]);}static void motion_fr_dmv( bs_transrate_t *bs, unsigned int f_code[2] ){ get_motion_delta( bs, f_code[0]); get_dmv( bs ); get_motion_delta( bs, f_code[1]); get_dmv( bs );}static void motion_fi_field( bs_transrate_t *bs, unsigned int f_code[2] ){ bs_copy( bs, 1); get_motion_delta( bs, f_code[0]); get_motion_delta( bs, f_code[1]);}static void motion_fi_16x8( bs_transrate_t *bs, unsigned int f_code[2] ){ bs_copy( bs, 1); get_motion_delta( bs, f_code[0]); get_motion_delta( bs, f_code[1]); bs_copy( bs, 1); get_motion_delta( bs, f_code[0]); get_motion_delta( bs, f_code[1]);}static void motion_fi_dmv( bs_transrate_t *bs, unsigned int f_code[2] ){ get_motion_delta( bs, f_code[0]); get_dmv( bs ); get_motion_delta( bs, f_code[1]); get_dmv( bs );}#define MOTION_CALL(routine,direction) \do { \ if ((direction) & MACROBLOCK_MOTION_FORWARD) \ routine( bs, tr->f_code[0]); \ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ routine( bs, tr->f_code[1]); \} while (0)#define NEXT_MACROBLOCK \do { \ tr->h_offset += 16; \ if( tr->h_offset == tr->horizontal_size_value) \ { \ tr->v_offset += 16; \ if (tr->v_offset > (tr->vertical_size_value - 16)) return; \ tr->h_offset = 0; \ } \} while (0)static void putmbdata( transrate_t *tr, int macroblock_modes ){ bs_transrate_t *bs = &tr->bs; bs_write( bs, mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].code, mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].len); switch ( tr->picture_coding_type) { case I_TYPE: if ((! (tr->frame_pred_frame_dct)) && (tr->picture_structure == FRAME_PICTURE)) bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); break; case P_TYPE: if (tr->picture_structure != FRAME_PICTURE) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); break; } else if (tr->frame_pred_frame_dct) break; else { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); break; } case B_TYPE: if (tr->picture_structure != FRAME_PICTURE) { if (! (macroblock_modes & MACROBLOCK_INTRA)) bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); break; } else if (tr->frame_pred_frame_dct) break; else { if (macroblock_modes & MACROBLOCK_INTRA) goto intra; bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { intra: bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); } break; } }}static inline void put_quantiser( transrate_t *tr ){ bs_transrate_t *bs = &tr->bs; bs_write( bs, tr->q_scale_type ? map_non_linear_mquant[tr->new_quantizer_scale] : tr->new_quantizer_scale >> 1, 5); tr->last_coded_scale = tr->new_quantizer_scale;}static int slice_init( transrate_t *tr, int code){ bs_transrate_t *bs = &tr->bs; int offset; const MBAtab * mba; tr->v_offset = (code - 1) * 16; tr->quantizer_scale = get_quantizer_scale( tr ); if ( tr->picture_coding_type == P_TYPE) { tr->new_quantizer_scale = tr->quantizer_scale; } else { tr->new_quantizer_scale = getNewQuant(tr, tr->quantizer_scale); } put_quantiser( tr ); /*LOGF("************************\nstart of slice %i in %s picture. ori quant: %i new quant: %i\n", code, (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), quantizer_scale, new_quantizer_scale);*/ /* ignore intra_slice and all the extra data */ while (bs->i_bit_in_cache & 0x80000000) { bs_flush( bs, 9 ); } /* decode initial macroblock address increment */ offset = 0; for( ;; ) { if (bs->i_bit_in_cache >= 0x08000000) { mba = MBA_5 + (UBITS (bs->i_bit_in_cache, 6) - 2); break; } else if (bs->i_bit_in_cache >= 0x01800000) { mba = MBA_11 + (UBITS (bs->i_bit_in_cache, 12) - 24); break; } else if( UBITS (bs->i_bit_in_cache, 12 ) == 8 ) { /* macroblock_escape */ offset += 33; bs_copy( bs, 11); } else { return -1; } } bs_copy( bs, mba->len + 1); tr->h_offset = (offset + mba->mba) << 4; while( tr->h_offset - (int)tr->horizontal_size_value >= 0) { tr->h_offset -= tr->horizontal_size_value; tr->v_offset += 16; } if( tr->v_offset > tr->vertical_size_value - 16 ) { return -1; } return 0;}static void mpeg2_slice( transrate_t *tr, const int code ){ bs_transrate_t *bs = &tr->bs; if( slice_init( tr, code ) ) { return; } for( ;; ) { int macroblock_modes; int mba_inc; const MBAtab * mba; macroblock_modes = get_macroblock_modes( tr ); if (macroblock_modes & MACROBLOCK_QUANT) tr->quantizer_scale = get_quantizer_scale( tr ); //LOGF("blk %i : ", h_offset >> 4); if (macroblock_modes & MACROBLOCK_INTRA) { //LOG("intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); tr->new_quantizer_scale = increment_quant( tr, tr->quantizer_scale); if (tr->last_coded_scale == tr->new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT else macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT putmbdata( tr, macroblock_modes); if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser( tr ); //if (macroblock_modes & MACROBLOCK_QUANT) LOGF("put new quant: %i ", new_quantizer_scale); if (tr->concealment_motion_vectors) { if (tr->picture_structure != FRAME_PICTURE) { bs_copy( bs, 1); /* remove field_select */ } /* like motion_frame, but parsing without actual motion compensation */ get_motion_delta( bs, tr->f_code[0][0]); get_motion_delta( bs, tr->f_code[0][1]); bs_copy( bs, 1); /* remove marker_bit */ } if( tr->intra_vlc_format ) { /* Luma */ get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); /* Chroma */ get_chroma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_chroma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); } else { /* Luma */ get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); /* Chroma */ get_chroma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); get_chroma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); } } else { RunLevel block[6][65]; // terminated by level = 0, so we need 64+1 int new_coded_block_pattern = 0; // begin saving data int batb; uint8_t p_n_ow[32], *p_n_w, *p_o_ow = bs->p_ow, *p_o_w = bs->p_w; uint32_t i_n_bit_out, i_n_bit_out_cache, i_o_bit_out = bs->i_bit_out, i_o_bit_out_cache = bs->i_bit_out_cache; bs->i_bit_out_cache = 0; bs->i_bit_out = BITS_IN_BUF; bs->p_ow = bs->p_w = p_n_ow; if (tr->picture_structure == FRAME_PICTURE) switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FRAME: MOTION_CALL (motion_fr_frame, macroblock_modes); break; case MC_FIELD: MOTION_CALL (motion_fr_field, macroblock_modes); break; case MC_DMV: MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); break; } else switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FIELD: MOTION_CALL (motion_fi_field, macroblock_modes); break; case MC_16X8: MOTION_CALL (motion_fi_16x8, macroblock_modes); break; case MC_DMV: MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); break; } assert(bs->p_w - bs->p_ow < 32); p_n_w = bs->p_w; i_n_bit_out = bs->i_bit_out; i_n_bit_out_cache = bs->i_bit_out_cache; assert(bs->p_ow == p_n_ow); bs->i_bit_out = i_o_bit_out ; bs->i_bit_out_cache = i_o_bit_out_cache; bs->p_ow = p_o_ow; bs->p_w = p_o_w; // end saving data if ( tr->picture_coding_type == P_TYPE) tr->new_quantizer_scale = tr->quantizer_scale; else tr->new_quantizer_scale = getNewQuant( tr, tr->quantizer_scale); //LOG("non intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); if (macroblock_modes & MACROBLOCK_PATTERN) { const int cbp = get_coded_block_pattern( bs ); if( tr->picture_coding_type == P_TYPE ) { if( cbp&0x20 ) get_non_intra_block_drop( tr, block[0] ); if( cbp&0x10 ) get_non_intra_block_drop( tr, block[1] ); if( cbp&0x08 ) get_non_intra_block_drop( tr, block[2] ); if( cbp&0x04 ) get_non_intra_block_drop( tr, block[3] ); if( cbp&0x02 ) get_non_intra_block_drop( tr, block[4] ); if( cbp&0x01 ) get_non_intra_block_drop( tr, block[5] ); new_coded_block_pattern = cbp; } else { if( cbp&0x20 ) { get_non_intra_block_rq( bs, block[0], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[0] ) ) new_coded_block_pattern |= 0x20; } if( cbp&0x10 ) { get_non_intra_block_rq( bs, block[1], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[1] ) ) new_coded_block_pattern |= 0x10; } if( cbp&0x08 ) { get_non_intra_block_rq( bs, block[2], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[2] ) ) new_coded_block_pattern |= 0x08; } if( cbp&0x04 ) { get_non_intra_block_rq( bs, block[3], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[3] ) ) new_coded_block_pattern |= 0x04; } if( cbp&0x02 ) { get_non_intra_block_rq( bs, block[4], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[4] ) ) new_coded_block_pattern |= 0x02; } if( cbp&0x01 ) { get_non_intra_block_rq( bs, block[5], tr->quantizer_scale, tr->new_quantizer_scale ); if( isNotEmpty( block[5] ) ) new_coded_block_pattern |= 0x01; } if( !new_coded_block_pattern) macroblock_modes &= 0xFFFFFFED; // remove MACROBLOCK_PATTERN and MACROBLOCK_QUANT flag } } if (tr->last_coded_scale == tr->new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT else if (macroblock_modes & MACROBLOCK_PATTERN) macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT assert( (macroblock_modes & MACROBLOCK_PATTERN) || !(macroblock_modes & MACROBLOCK_QUANT) ); putmbdata( tr, macroblock_modes); if( macroblock_modes & MACROBLOCK_QUANT ) { put_quantiser( tr ); } // put saved motion data... for (batb = 0; batb < (p_n_w - p_n_ow); batb++) { bs_write( bs, p_n_ow[batb], 8 ); } bs_write( bs, i_n_bit_out_cache, BITS_IN_BUF - i_n_bit_out); // end saved motion data... if (macroblock_modes & MACROBLOCK_PATTERN) { /* Write CBP */ bs_write( bs, cbptable[new_coded_block_pattern].code,cbptable[new_coded_block_pattern].len); if (new_coded_block_pattern & 0x20) putnonintrablk( bs, block[0]); if (new_coded_block_pattern & 0x10) putnonintrablk( bs, block[1]); if (new_coded_block_pattern & 0x08) putnonintrablk( bs, block[2]); if (new_coded_block_pattern & 0x04) putnonintrablk( bs, block[3]); if (new_coded_block_pattern & 0x02) putnonintrablk( bs, block[4]); if (new_coded_block_pattern & 0x01) putnonintrablk( bs, block[5]); } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?