diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index f1725ccdaf..af1d1c3396 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1393,20 +1393,81 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) static void copy_bits(PutBitContext *pb, UINT8 *src, int length) { +#if 1 + int bytes= length>>4; + int bits= length&15; + int i; + + for(i=0; i>(16-bits)); +#else int bytes= length>>3; int bits= length&7; int i; for(i=0; i>(8-bits)); +#endif } +static void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ + int i; + + memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? + + /* mpeg1 */ + d->mb_incr= s->mb_incr; + for(i=0; i<3; i++) + d->last_dc[i]= s->last_dc[i]; + + /* statistics */ + d->mv_bits= s->mv_bits; + d->i_tex_bits= s->i_tex_bits; + d->p_tex_bits= s->p_tex_bits; + d->i_count= s->i_count; + d->p_count= s->p_count; + d->skip_count= s->skip_count; + d->misc_bits= s->misc_bits; + d->last_bits= s->last_bits; +} + +static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){ + int i; + + memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); + memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? + + /* mpeg1 */ + d->mb_incr= s->mb_incr; + for(i=0; i<3; i++) + d->last_dc[i]= s->last_dc[i]; + + /* statistics */ + d->mv_bits= s->mv_bits; + d->i_tex_bits= s->i_tex_bits; + d->p_tex_bits= s->p_tex_bits; + d->i_count= s->i_count; + d->p_count= s->p_count; + d->skip_count= s->skip_count; + d->misc_bits= s->misc_bits; + d->last_bits= s->last_bits; + + d->mb_intra= s->mb_intra; + d->mv_type= s->mv_type; + d->mv_dir= s->mv_dir; + d->pb= s->pb; + d->block= s->block; + for(i=0; i<6; i++) + d->block_last_index[i]= s->block_last_index[i]; +} + + static void encode_picture(MpegEncContext *s, int picture_number) { int mb_x, mb_y, last_gob, pdif = 0; int i; int bits; - MpegEncContext best_s; + MpegEncContext best_s, backup_s; UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB s->picture_number = picture_number; @@ -1585,10 +1646,12 @@ static void encode_picture(MpegEncContext *s, int picture_number) s->block_index[3]+=2; s->block_index[4]++; s->block_index[5]++; - if(mb_type & (mb_type-1)){ // more than 1 MB type possible pb= s->pb; s->mv_dir = MV_DIR_FORWARD; + + copy_context_before_encode(&backup_s, s, -1); + if(mb_type&MB_TYPE_INTER){ int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; s->mv_type = MV_TYPE_16X16; @@ -1603,18 +1666,12 @@ static void encode_picture(MpegEncContext *s, int picture_number) if(dpb); dmin=d; - best_s.mv[0][0][0]= s->mv[0][0][0]; - best_s.mv[0][0][1]= s->mv[0][0][1]; - best_s.mb_intra= 0; - best_s.mv_type = MV_TYPE_16X16; - best_s.pb=s->pb; - best_s.block= s->block; + copy_context_after_encode(&best_s, s, MB_TYPE_INTER); best=1; - for(i=0; i<6; i++) - best_s.block_last_index[i]= s->block_last_index[i]; } } - if(mb_type&MB_TYPE_INTER4V){ + if(mb_type&MB_TYPE_INTER4V){ + copy_context_before_encode(s, &backup_s, MB_TYPE_INTER4V); s->mv_type = MV_TYPE_8X8; s->mb_intra= 0; for(i=0; i<4; i++){ @@ -1629,20 +1686,12 @@ static void encode_picture(MpegEncContext *s, int picture_number) if(dpb); dmin=d; - for(i=0; i<4; i++){ - best_s.mv[0][i][0] = s->mv[0][i][0]; - best_s.mv[0][i][1] = s->mv[0][i][1]; - } - best_s.mb_intra= 0; - best_s.mv_type = MV_TYPE_8X8; - best_s.pb=s->pb; - best_s.block= s->block; + copy_context_after_encode(&best_s, s, MB_TYPE_INTER4V); best=2; - for(i=0; i<6; i++) - best_s.block_last_index[i]= s->block_last_index[i]; } } if(mb_type&MB_TYPE_INTRA){ + copy_context_before_encode(s, &backup_s, MB_TYPE_INTRA); s->mv_type = MV_TYPE_16X16; s->mb_intra= 1; s->mv[0][0][0] = 0; @@ -1655,29 +1704,15 @@ static void encode_picture(MpegEncContext *s, int picture_number) if(dpb); dmin=d; - best_s.mv[0][0][0]= 0; - best_s.mv[0][0][1]= 0; - best_s.mb_intra= 1; - best_s.mv_type = MV_TYPE_16X16; - best_s.pb=s->pb; - best_s.block= s->block; - for(i=0; i<6; i++) - best_s.block_last_index[i]= s->block_last_index[i]; + copy_context_after_encode(&best_s, s, MB_TYPE_INTRA); best=0; } - /* force cleaning of ac/dc if needed ... */ - s->mbintra_table[mb_x + mb_y*s->mb_width]=1; + /* force cleaning of ac/dc pred stuff if needed ... */ + if(s->h263_pred || s->h263_aic) + s->mbintra_table[mb_x + mb_y*s->mb_width]=1; } - for(i=0; i<4; i++){ - s->mv[0][i][0] = best_s.mv[0][i][0]; - s->mv[0][i][1] = best_s.mv[0][i][1]; - } - s->mb_intra= best_s.mb_intra; - s->mv_type= best_s.mv_type; - for(i=0; i<6; i++) - s->block_last_index[i]= best_s.block_last_index[i]; + copy_context_after_encode(s, &best_s, -1); copy_bits(&pb, bit_buf[best], dmin); - s->block= best_s.block; s->pb= pb; } else { int motion_x, motion_y;