Mercurial > libavcodec.hg
diff mpeg12.c @ 1708:dea5b2946999 libavcodec
interlaced motion estimation
interlaced mpeg2 encoding
P & B frames
rate distored interlaced mb decission
alternate scantable support
4mv encoding fixes (thats also why the regression tests change)
passing height to most dsp functions
interlaced mpeg4 encoding (no direct mode MBs yet)
various related cleanups
disabled old motion estimaton algorithms (log, full, ...) they will either be fixed or removed
author | michael |
---|---|
date | Tue, 30 Dec 2003 16:07:57 +0000 |
parents | 3ba5c493db6f |
children | 4a68b20eeb2c |
line wrap: on
line diff
--- a/mpeg12.c Tue Dec 30 15:29:38 2003 +0000 +++ b/mpeg12.c Tue Dec 30 16:07:57 2003 +0000 @@ -29,6 +29,9 @@ #include "mpeg12data.h" +//#undef NDEBUG +//#include <assert.h> + /* Start codes. */ #define SEQ_END_CODE 0x000001b7 @@ -476,12 +479,12 @@ } static inline void put_mb_modes(MpegEncContext *s, int n, int bits, - int has_mv) + int has_mv, int field_motion) { put_bits(&s->pb, n, bits); if (!s->frame_pred_frame_dct) { if (has_mv) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ + put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */ put_bits(&s->pb, 1, s->interlaced_dct); } } @@ -501,9 +504,9 @@ if (s->block_last_index[i] >= 0) cbp |= 1 << (5 - i); } - + if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && - ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) || + ((s->pict_type == P_TYPE && s->mv_type == MV_TYPE_16X16 && (motion_x | motion_y) == 0) || (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { s->mb_skip_run++; @@ -511,6 +514,10 @@ s->skip_count++; s->misc_bits++; s->last_bits++; + if(s->pict_type == P_TYPE){ + s->last_mv[0][1][0]= s->last_mv[0][0][0]= + s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; + } } else { if(first_mb){ assert(s->mb_skip_run == 0); @@ -521,150 +528,167 @@ if (s->pict_type == I_TYPE) { if(s->dquant && cbp){ - put_mb_modes(s, 2, 1, 0); /* macroblock_type : macroblock_quant = 1 */ + put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ put_bits(&s->pb, 5, s->qscale); }else{ - put_mb_modes(s, 1, 1, 0); /* macroblock_type : macroblock_quant = 0 */ + put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ s->qscale -= s->dquant; } s->misc_bits+= get_bits_diff(s); s->i_count++; } else if (s->mb_intra) { if(s->dquant && cbp){ - put_mb_modes(s, 6, 0x01, 0); + put_mb_modes(s, 6, 0x01, 0, 0); put_bits(&s->pb, 5, s->qscale); }else{ - put_mb_modes(s, 5, 0x03, 0); + put_mb_modes(s, 5, 0x03, 0, 0); s->qscale -= s->dquant; } s->misc_bits+= get_bits_diff(s); s->i_count++; - s->last_mv[0][0][0] = - s->last_mv[0][0][1] = 0; + memset(s->last_mv, 0, sizeof(s->last_mv)); } else if (s->pict_type == P_TYPE) { + if(s->mv_type == MV_TYPE_16X16){ if (cbp != 0) { - if (motion_x == 0 && motion_y == 0) { + if ((motion_x|motion_y) == 0) { if(s->dquant){ - put_mb_modes(s, 5, 1, 0); /* macroblock_pattern & quant */ + put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ put_bits(&s->pb, 5, s->qscale); }else{ - put_mb_modes(s, 2, 1, 0); /* macroblock_pattern only */ + put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ } s->misc_bits+= get_bits_diff(s); - put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); } else { if(s->dquant){ - put_mb_modes(s, 5, 2, 1); /* motion + cbp */ + put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ put_bits(&s->pb, 5, s->qscale); }else{ - put_mb_modes(s, 1, 1, 1); /* motion + cbp */ + put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ } s->misc_bits+= get_bits_diff(s); mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added s->mv_bits+= get_bits_diff(s); - put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); } } else { put_bits(&s->pb, 3, 1); /* motion only */ if (!s->frame_pred_frame_dct) put_bits(&s->pb, 2, 2); /* motion_type: frame */ + s->misc_bits+= get_bits_diff(s); mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added s->qscale -= s->dquant; s->mv_bits+= get_bits_diff(s); } - s->f_count++; - } else - { // RAL: All the following bloc added for B frames: - if (cbp != 0) - { // With coded bloc pattern - if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD)) - { // Bi-directional motion - if (s->dquant) { - put_mb_modes(s, 5, 2, 1); - put_bits(&s->pb, 5, s->qscale); - } else { - put_mb_modes(s, 2, 3, 1); - } - s->misc_bits += get_bits_diff(s); - mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->b_count++; - s->f_count++; - s->mv_bits += get_bits_diff(s); - put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); - } - else if (s->mv_dir == MV_DIR_BACKWARD) - { // Backward motion - if (s->dquant) { - put_mb_modes(s, 6, 2, 1); - put_bits(&s->pb, 5, s->qscale); - } else { - put_mb_modes(s, 3, 3, 1); - } - s->misc_bits += get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); - s->b_count++; - s->mv_bits += get_bits_diff(s); - put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); - } - else if (s->mv_dir == MV_DIR_FORWARD) - { // Forward motion - if (s->dquant) { - put_mb_modes(s, 6, 3, 1); - put_bits(&s->pb, 5, s->qscale); - } else { - put_mb_modes(s, 4, 3, 1); - } - s->misc_bits += get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); - s->f_count++; - s->mv_bits += get_bits_diff(s); - put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); - } + s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; + s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; + }else{ + assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); + + if (cbp) { + if(s->dquant){ + put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ + put_bits(&s->pb, 5, s->qscale); + }else{ + put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ + } + } else { + put_bits(&s->pb, 3, 1); /* motion only */ + put_bits(&s->pb, 2, 1); /* motion_type: field */ + s->qscale -= s->dquant; + } + s->misc_bits+= get_bits_diff(s); + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[0][i]); + mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); + mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + } + s->mv_bits+= get_bits_diff(s); + } + if(cbp) + put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); + s->f_count++; + } else{ + static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi + + if(s->mv_type == MV_TYPE_16X16){ + if (cbp){ // With coded bloc pattern + if (s->dquant) { + if(s->mv_dir == MV_DIR_FORWARD) + put_mb_modes(s, 6, 3, 1, 0); + else + put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0); + put_bits(&s->pb, 5, s->qscale); + } else { + put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0); } - else - { // No coded bloc pattern - if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD)) - { // Bi-directional motion - put_bits(&s->pb, 2, 2); /* backward & forward motion */ - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->b_count++; - s->f_count++; - } - else if (s->mv_dir == MV_DIR_BACKWARD) - { // Backward motion - put_bits(&s->pb, 3, 2); /* backward motion only */ - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); - s->b_count++; - } - else if (s->mv_dir == MV_DIR_FORWARD) - { // Forward motion - put_bits(&s->pb, 4, 2); /* forward motion only */ - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); - s->f_count++; - } + }else{ // No coded bloc pattern + put_bits(&s->pb, mb_type_len[s->mv_dir], 2); + if (!s->frame_pred_frame_dct) + put_bits(&s->pb, 2, 2); /* motion_type: frame */ s->qscale -= s->dquant; - s->mv_bits += get_bits_diff(s); + } + s->misc_bits += get_bits_diff(s); + if (s->mv_dir&MV_DIR_FORWARD){ + mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); + mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); + s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0]; + s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1]; + s->f_count++; + } + if (s->mv_dir&MV_DIR_BACKWARD){ + mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); + mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); + s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0]; + s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1]; + s->b_count++; + } + }else{ + assert(s->mv_type == MV_TYPE_FIELD); + assert(!s->frame_pred_frame_dct); + if (cbp){ // With coded bloc pattern + if (s->dquant) { + if(s->mv_dir == MV_DIR_FORWARD) + put_mb_modes(s, 6, 3, 1, 1); + else + put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1); + put_bits(&s->pb, 5, s->qscale); + } else { + put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1); } - // End of bloc from RAL + }else{ // No coded bloc pattern + put_bits(&s->pb, mb_type_len[s->mv_dir], 2); + put_bits(&s->pb, 2, 1); /* motion_type: field */ + s->qscale -= s->dquant; + } + s->misc_bits += get_bits_diff(s); + if (s->mv_dir&MV_DIR_FORWARD){ + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[0][i]); + mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); + mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + } + s->f_count++; + } + if (s->mv_dir&MV_DIR_BACKWARD){ + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[1][i]); + mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); + mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0]; + s->last_mv[1][i][1]= 2*s->mv[1][i][1]; + } + s->b_count++; + } } + s->mv_bits += get_bits_diff(s); + if(cbp) + put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); + } for(i=0;i<6;i++) { if (cbp & (1 << (5 - i))) { mpeg1_encode_block(s, block[i], i); @@ -676,18 +700,6 @@ else s->p_tex_bits+= get_bits_diff(s); } - - // RAL: By this: - if (s->mv_dir & MV_DIR_FORWARD) - { - s->last_mv[0][0][0]= s->mv[0][0][0]; - s->last_mv[0][0][1]= s->mv[0][0][1]; - } - if (s->mv_dir & MV_DIR_BACKWARD) - { - s->last_mv[1][0][0]= s->mv[1][0][0]; - s->last_mv[1][0][1]= s->mv[1][0][1]; - } } // RAL: Parameter added: f_or_b_code @@ -1952,7 +1964,7 @@ s->repeat_first_field = get_bits1(&s->gb); s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); - + if(s->picture_structure == PICT_FRAME) s->first_field=0; else{ @@ -1963,13 +1975,9 @@ if(s->alternate_scan){ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); }else{ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); } /* composite display not parsed */ @@ -2103,10 +2111,10 @@ s->qscale = get_qscale(s); if (s->first_slice && (s->first_field || s->picture_structure==PICT_FRAME)) { if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1], s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), - s->progressive_sequence ? "pro" :"", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", + s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); }