diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2003-12-30 16:07:57 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2003-12-30 16:07:57 +0000 |
commit | bb198e198abc42753274edc376fdd15543694315 (patch) | |
tree | e263990eeb4624e54be714b7a494b7511d5dc13f /libavcodec/mpeg12.c | |
parent | b846b231b353048693ef457285a23b0c21fc577f (diff) | |
download | ffmpeg-bb198e198abc42753274edc376fdd15543694315.tar.gz |
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
Originally committed as revision 2638 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r-- | libavcodec/mpeg12.c | 254 |
1 files changed, 131 insertions, 123 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 4cc164de31..81cd9619c1 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -29,6 +29,9 @@ #include "mpeg12data.h" +//#undef NDEBUG +//#include <assert.h> + /* Start codes. */ #define SEQ_END_CODE 0x000001b7 @@ -476,12 +479,12 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) } 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 @@ void mpeg1_encode_mb(MpegEncContext *s, 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 @@ void mpeg1_encode_mb(MpegEncContext *s, 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 @@ void mpeg1_encode_mb(MpegEncContext *s, 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 - { // 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 { + put_bits(&s->pb, 3, 1); /* motion only */ + put_bits(&s->pb, 2, 1); /* motion_type: field */ s->qscale -= s->dquant; - s->mv_bits += get_bits_diff(s); + } + 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 + 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->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 @@ void mpeg1_encode_mb(MpegEncContext *s, 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 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) 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 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) 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 @@ static int mpeg_decode_slice(AVCodecContext *avctx, 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" :""); } |