fixing hq mode with mpeg1 and 2-pass

Originally committed as revision 405 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2002-04-17 18:19:50 +00:00
parent 9dbf1dddbd
commit 1f0cd30fd9

View File

@ -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) 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<bytes; i++) put_bits(pb, 16, be2me_16(((uint16_t*)src)[i]));
put_bits(pb, bits, be2me_16(((uint16_t*)src)[i])>>(16-bits));
#else
int bytes= length>>3; int bytes= length>>3;
int bits= length&7; int bits= length&7;
int i; int i;
for(i=0; i<bytes; i++) put_bits(pb, 8, src[i]); for(i=0; i<bytes; i++) put_bits(pb, 8, src[i]);
put_bits(pb, bits, src[i]>>(8-bits)); put_bits(pb, bits, src[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) static void encode_picture(MpegEncContext *s, int picture_number)
{ {
int mb_x, mb_y, last_gob, pdif = 0; int mb_x, mb_y, last_gob, pdif = 0;
int i; int i;
int bits; 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 UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB
s->picture_number = picture_number; 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[3]+=2;
s->block_index[4]++; s->block_index[4]++;
s->block_index[5]++; s->block_index[5]++;
if(mb_type & (mb_type-1)){ // more than 1 MB type possible if(mb_type & (mb_type-1)){ // more than 1 MB type possible
pb= s->pb; pb= s->pb;
s->mv_dir = MV_DIR_FORWARD; s->mv_dir = MV_DIR_FORWARD;
copy_context_before_encode(&backup_s, s, -1);
if(mb_type&MB_TYPE_INTER){ if(mb_type&MB_TYPE_INTER){
int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
s->mv_type = MV_TYPE_16X16; s->mv_type = MV_TYPE_16X16;
@ -1603,18 +1666,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
if(d<dmin){ if(d<dmin){
flush_put_bits(&s->pb); flush_put_bits(&s->pb);
dmin=d; dmin=d;
best_s.mv[0][0][0]= s->mv[0][0][0]; copy_context_after_encode(&best_s, s, MB_TYPE_INTER);
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;
best=1; 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->mv_type = MV_TYPE_8X8;
s->mb_intra= 0; s->mb_intra= 0;
for(i=0; i<4; i++){ for(i=0; i<4; i++){
@ -1629,20 +1686,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
if(d<dmin && 0){ if(d<dmin && 0){
flush_put_bits(&s->pb); flush_put_bits(&s->pb);
dmin=d; dmin=d;
for(i=0; i<4; i++){ copy_context_after_encode(&best_s, s, MB_TYPE_INTER4V);
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;
best=2; 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){ if(mb_type&MB_TYPE_INTRA){
copy_context_before_encode(s, &backup_s, MB_TYPE_INTRA);
s->mv_type = MV_TYPE_16X16; s->mv_type = MV_TYPE_16X16;
s->mb_intra= 1; s->mb_intra= 1;
s->mv[0][0][0] = 0; s->mv[0][0][0] = 0;
@ -1655,29 +1704,15 @@ static void encode_picture(MpegEncContext *s, int picture_number)
if(d<dmin){ if(d<dmin){
flush_put_bits(&s->pb); flush_put_bits(&s->pb);
dmin=d; dmin=d;
best_s.mv[0][0][0]= 0; copy_context_after_encode(&best_s, s, MB_TYPE_INTRA);
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];
best=0; best=0;
} }
/* force cleaning of ac/dc if needed ... */ /* force cleaning of ac/dc pred stuff if needed ... */
s->mbintra_table[mb_x + mb_y*s->mb_width]=1; if(s->h263_pred || s->h263_aic)
s->mbintra_table[mb_x + mb_y*s->mb_width]=1;
} }
for(i=0; i<4; i++){ copy_context_after_encode(s, &best_s, -1);
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_bits(&pb, bit_buf[best], dmin); copy_bits(&pb, bit_buf[best], dmin);
s->block= best_s.block;
s->pb= pb; s->pb= pb;
} else { } else {
int motion_x, motion_y; int motion_x, motion_y;