# HG changeset patch # User michaelni # Date 1044705657 0 # Node ID e5a9dbf597d4ba2bd749e2117aa6adb64c6a35bb # Parent 8d686fbb6a8c78c1eeb390a446bcb7d93738e87a mpeg1 bframe encoding patch by (Rapha¸«³l LEGRAND) with some modifications by me diff -r 8d686fbb6a8c -r e5a9dbf597d4 motion_est.c --- a/motion_est.c Fri Feb 07 16:44:48 2003 +0000 +++ b/motion_est.c Sat Feb 08 12:00:57 2003 +0000 @@ -1493,12 +1493,13 @@ fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor; //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); { - int score= dmin; - type=MB_TYPE_DIRECT; + int score= fmin; + type = MB_TYPE_FORWARD; - if(fmincodec_id != CODEC_ID_MPEG1VIDEO && dmin <= score){ + score = dmin; + type = MB_TYPE_DIRECT; } if(bminfcode_tab; + // RAL: 8 in MPEG-1, 16 in MPEG-4 + int range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code); + /* clip / convert to intra 16x16 type MVs */ for(y=0; ymb_height; y++){ int x; int xy= (y+1)* (s->mb_width+2)+1; int i= y*s->mb_width; - for(x=0; xmb_width; x++){ - if( fcode_tab[mv_table[xy][0] + MAX_MV] > f_code - || fcode_tab[mv_table[xy][0] + MAX_MV] == 0){ - if(mv_table[xy][0]>0) mv_table[xy][0]= (16<mb_width; x++) + { + if (s->mb_type[i] & type) // RAL: "type" test added... + { + if (fcode_tab[mv_table[xy][0] + MAX_MV] > f_code || fcode_tab[mv_table[xy][0] + MAX_MV] == 0) + { + if(mv_table[xy][0]>0) + mv_table[xy][0]= range-1; + else + mv_table[xy][0]= -range; + } + if (fcode_tab[mv_table[xy][1] + MAX_MV] > f_code || fcode_tab[mv_table[xy][1] + MAX_MV] == 0) + { + if(mv_table[xy][1]>0) + mv_table[xy][1]= range-1; + else + mv_table[xy][1]= -range; } - if( fcode_tab[mv_table[xy][1] + MAX_MV] > f_code - || fcode_tab[mv_table[xy][1] + MAX_MV] == 0){ - if(mv_table[xy][1]>0) mv_table[xy][1]= (16<pb, 10, (s->fake_picture_number - + + // RAL: s->picture_number instead of s->fake_picture_number + put_bits(&s->pb, 10, (s->picture_number - s->gop_picture_number) & 0x3ff); s->fake_picture_number++; put_bits(&s->pb, 3, s->pict_type); put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */ - if (s->pict_type == P_TYPE) { + // RAL: Forward f_code also needed for B frames + if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { put_bits(&s->pb, 1, 0); /* half pel coordinates */ put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ } + // RAL: Backward f_code necessary for B frames + if (s->pict_type == B_TYPE) { + put_bits(&s->pb, 1, 0); /* half pel coordinates */ + put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ + } + put_bits(&s->pb, 1, 0); /* extra bit picture */ /* only one slice */ @@ -368,10 +377,11 @@ cbp |= 1 << (5 - i); } - /* skip macroblock, except if first or last macroblock of a slice */ - if ((cbp | motion_x | motion_y) == 0 && - (!((mb_x | mb_y) == 0 || - (mb_x == s->mb_width - 1 && mb_y == s->mb_height - 1)))) { + // RAL: Skipped macroblocks for B frames... + if (cbp == 0 && (!((mb_x | mb_y) == 0 || (mb_x == s->mb_width - 1 && mb_y == s->mb_height - 1))) && + ((s->pict_type == P_TYPE && (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_incr++; s->qscale -= s->dquant; s->skip_count++; @@ -398,18 +408,19 @@ } s->misc_bits+= get_bits_diff(s); s->i_count++; - } else { - if (s->mb_intra) { - if(s->dquant && cbp){ - put_bits(&s->pb, 6, 0x01); - put_bits(&s->pb, 5, s->qscale); - }else{ - put_bits(&s->pb, 5, 0x03); - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - s->i_count++; - } else { + } else if (s->mb_intra) { + if(s->dquant && cbp){ + put_bits(&s->pb, 6, 0x01); + put_bits(&s->pb, 5, s->qscale); + }else{ + put_bits(&s->pb, 5, 0x03); + 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; + } else if (s->pict_type == P_TYPE) { if (cbp != 0) { if (motion_x == 0 && motion_y == 0) { if(s->dquant){ @@ -428,21 +439,106 @@ put_bits(&s->pb, 1, 1); /* motion + cbp */ } s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]); - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]); + 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 */ - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]); - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]); + 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) + { // With QScale + put_bits(&s->pb, 5, 2); + put_bits(&s->pb, 5, s->qscale); + } + else // Without QScale + put_bits(&s->pb, 2, 3); + 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) + { // With QScale + put_bits(&s->pb, 6, 2); + put_bits(&s->pb, 5, s->qscale); + } + else // Without QScale + put_bits(&s->pb, 3, 3); + 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) + { // With QScale + put_bits(&s->pb, 6, 3); + put_bits(&s->pb, 5, s->qscale); + } + else // Without QScale + put_bits(&s->pb, 4, 3); + 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]); + } + } + 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 */ + 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 */ + 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 */ + 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->qscale -= s->dquant; + s->mv_bits += get_bits_diff(s); + } + // End of bloc from RAL } - } for(i=0;i<6;i++) { if (cbp & (1 << (5 - i))) { mpeg1_encode_block(s, block[i], i); @@ -454,11 +550,22 @@ else s->p_tex_bits+= get_bits_diff(s); } - s->last_mv[0][0][0] = motion_x; - s->last_mv[0][0][1] = motion_y; + + // 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]; + } } -static void mpeg1_encode_motion(MpegEncContext *s, int val) +// RAL: Parameter added: f_or_b_code +static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) { int code, bit_size, l, m, bits, range, sign; @@ -469,7 +576,7 @@ mbMotionVectorTable[0][1], mbMotionVectorTable[0][0]); } else { - bit_size = s->f_code - 1; + bit_size = f_or_b_code - 1; range = 1 << bit_size; /* modulo encoding */ l = 16 * range; @@ -492,9 +599,13 @@ bits = val & (range - 1); sign = 1; } + + assert(code > 0 && code <= 16); + put_bits(&s->pb, mbMotionVectorTable[code][1], mbMotionVectorTable[code][0]); + put_bits(&s->pb, 1, sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); diff -r 8d686fbb6a8c -r e5a9dbf597d4 mpegvideo.c --- a/mpegvideo.c Fri Feb 07 16:44:48 2003 +0000 +++ b/mpegvideo.c Sat Feb 08 12:00:57 2003 +0000 @@ -2872,7 +2872,8 @@ #ifdef CONFIG_RISKY /* we need to initialize some time vars before we can encode b-frames */ - if (s->h263_pred && !s->h263_msmpeg4) + // RAL: Condition added for MPEG1VIDEO + if (s->codec_id == CODEC_ID_MPEG1VIDEO || (s->h263_pred && !s->h263_msmpeg4)) ff_set_mpeg4_time(s, s->picture_number); #endif @@ -2965,12 +2966,24 @@ //printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); } - if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) + if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) { s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER); + + // RAL: Next call moved into that bloc ff_fix_long_p_mvs(s); + } + + // RAL: All this bloc changed if(s->pict_type==B_TYPE){ - s->f_code= ff_get_best_fcode(s, s->b_forw_mv_table, MB_TYPE_FORWARD); - s->b_code= ff_get_best_fcode(s, s->b_back_mv_table, MB_TYPE_BACKWARD); + int a, b; + + a = ff_get_best_fcode(s, s->b_forw_mv_table, MB_TYPE_FORWARD); + b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, MB_TYPE_BIDIR); + s->f_code = FFMAX(a, b); + + a = ff_get_best_fcode(s, s->b_back_mv_table, MB_TYPE_BACKWARD); + b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, MB_TYPE_BIDIR); + s->b_code = FFMAX(a, b); ff_fix_long_b_mvs(s, s->b_forw_mv_table, s->f_code, MB_TYPE_FORWARD); ff_fix_long_b_mvs(s, s->b_back_mv_table, s->b_code, MB_TYPE_BACKWARD); @@ -3064,6 +3077,10 @@ s->mb_incr = 1; s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; + s->last_mv[1][0][0] = 0; + s->last_mv[1][0][1] = 0; + + s->last_mv_dir = 0; #ifdef CONFIG_RISKY if (s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P) @@ -3227,7 +3244,7 @@ &dmin, &next_block, mx, my); } if(mb_type&MB_TYPE_INTRA){ - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = 0; s->mv_type = MV_TYPE_16X16; s->mb_intra= 1; s->mv[0][0][0] = 0; @@ -3348,7 +3365,7 @@ switch(mb_type){ case MB_TYPE_INTRA: - s->mv_dir = MV_DIR_FORWARD; + s->mv_dir = 0; s->mb_intra= 1; motion_x= s->mv[0][0][0] = 0; motion_y= s->mv[0][0][1] = 0; @@ -3405,8 +3422,13 @@ motion_x=motion_y=0; //gcc warning fix printf("illegal MB type\n"); } + encode_mb(s, motion_x, motion_y); + + // RAL: Update last macrobloc type + s->last_mv_dir = s->mv_dir; } + /* clean the MV table in IPS frames for direct mode in B frames */ if(s->mb_intra /* && I,P,S_TYPE */){ s->p_mv_table[xy][0]=0; diff -r 8d686fbb6a8c -r e5a9dbf597d4 mpegvideo.h --- a/mpegvideo.h Fri Feb 07 16:44:48 2003 +0000 +++ b/mpegvideo.h Sat Feb 08 12:00:57 2003 +0000 @@ -508,6 +508,7 @@ /* Mpeg1 specific */ int fake_picture_number; /* picture number at the bitstream frame rate */ int gop_picture_number; /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */ + int last_mv_dir; /* last mv_dir, used for b frame encoding */ /* MPEG2 specific - I wish I had not to support this mess. */ int progressive_sequence;