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 + -
显示快捷键?