From 6a1f7e7b6b6d75d785cba932f8d8d1db228e716d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 18 Sep 2002 18:28:11 +0000 Subject: [PATCH] better min/max rate handling cleanup Originally committed as revision 952 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/ratecontrol.c | 68 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 252ce7f7f6..5c8f14ccdd 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -64,9 +64,6 @@ int ff_rate_control_init(MpegEncContext *s) } rcc->buffer_index= s->avctx->rc_buffer_size/2; - rcc->next_non_b_qscale=10; - rcc->next_p_qscale=10; - if(s->flags&CODEC_FLAG_PASS2){ int i; char *p; @@ -231,7 +228,6 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f const int pict_type= rce->new_pict_type; const double mb_num= s->mb_num; int i; - const double last_q= rcc->last_qscale_for[pict_type]; double const_values[]={ M_PI, @@ -324,13 +320,34 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset; else if(pict_type==B_TYPE && s->avctx->b_quant_factor<0.0) q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset; - + + return q; +} + +static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){ + RateControlContext *rcc= &s->rc_context; + AVCodecContext *a= s->avctx; + const int pict_type= rce->new_pict_type; + const double last_p_q = rcc->last_qscale_for[P_TYPE]; + const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type]; + + if (pict_type==I_TYPE && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==P_TYPE)) + q= last_p_q *ABS(a->i_quant_factor) + a->i_quant_offset; + else if(pict_type==B_TYPE && a->b_quant_factor>0.0) + q= last_non_b_q* a->b_quant_factor + a->b_quant_offset; + /* last qscale / qdiff stuff */ - if (q > last_q + s->max_qdiff) q= last_q + s->max_qdiff; - else if(q < last_q - s->max_qdiff) q= last_q - s->max_qdiff; + if(rcc->last_non_b_pict_type==pict_type || pict_type!=I_TYPE){ + double last_q= rcc->last_qscale_for[pict_type]; + if (q > last_q + a->max_qdiff) q= last_q + a->max_qdiff; + else if(q < last_q - a->max_qdiff) q= last_q - a->max_qdiff; + } rcc->last_qscale_for[pict_type]= q; //Note we cant do that after blurring + if(pict_type!=B_TYPE) + rcc->last_non_b_pict_type= pict_type; + return q; } @@ -380,13 +397,15 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, //printf("q:%f\n", q); /* buffer overflow/underflow protection */ if(buffer_size){ - double expected_size= rcc->buffer_index - bits; + double expected_size= rcc->buffer_index; if(min_rate){ - double d= 2*(buffer_size - (expected_size + min_rate))/buffer_size; + double d= 2*(buffer_size - expected_size)/buffer_size; if(d>1.0) d=1.0; else if(d<0.0001) d=0.0001; q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); + + q= MIN(q, bits2qp(rce, MAX((min_rate - buffer_size + rcc->buffer_index)*2, 1))); } if(max_rate){ @@ -394,6 +413,8 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, if(d>1.0) d=1.0; else if(d<0.0001) d=0.0001; q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); + + q= MAX(q, bits2qp(rce, MAX(rcc->buffer_index/2, 1))); } } //printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity); @@ -529,10 +550,7 @@ int ff_rate_estimate_qscale(MpegEncContext *s) assert(q>0.0); //printf("%f ", q); - if (pict_type==I_TYPE && s->avctx->i_quant_factor>0.0) - q= rcc->next_p_qscale*s->avctx->i_quant_factor + s->avctx->i_quant_offset; - else if(pict_type==B_TYPE && s->avctx->b_quant_factor>0.0) - q= rcc->next_non_b_qscale*s->avctx->b_quant_factor + s->avctx->b_quant_offset; + q= get_diff_limited_q(s, rce, q); //printf("%f ", q); assert(q>0.0); @@ -553,9 +571,6 @@ int ff_rate_estimate_qscale(MpegEncContext *s) rcc->pass1_wanted_bits+= s->bit_rate/fps; assert(q>0.0); - - if(pict_type != B_TYPE) rcc->next_non_b_qscale= q; - if(pict_type == P_TYPE) rcc->next_p_qscale= q; } //printf("qmin:%d, qmax:%d, q:%f\n", qmin, qmax, q); @@ -565,13 +580,11 @@ int ff_rate_estimate_qscale(MpegEncContext *s) // printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits); - //printf("%f %f %f\n", q, br_compensation, short_term_q); qscale= (int)(q + 0.5); -//printf("%d ", qscale); -//printf("q:%d diff:%d comp:%f st_q:%f last_size:%d\n", qscale, (int)diff, br_compensation, -// short_term_q, s->frame_bits); +//printf("q:%d diff:%d comp:%f st_q:%f last_size:%d type:%d\n", qscale, (int)diff, br_compensation, +// short_term_q, s->frame_bits, pict_type); //printf("%d %d\n", s->bit_rate, (int)fps); rcc->last_qscale= qscale; @@ -693,21 +706,10 @@ static int init_pass2(MpegEncContext *s) assert(filter_size%2==1); /* fixed I/B QP relative to P mode */ - rcc->next_non_b_qscale= 10; - rcc->next_p_qscale= 10; for(i=rcc->num_entries-1; i>=0; i--){ RateControlEntry *rce= &rcc->entry[i]; - const int pict_type= rce->new_pict_type; - - if (pict_type==I_TYPE && s->avctx->i_quant_factor>0.0) - qscale[i]= rcc->next_p_qscale*s->avctx->i_quant_factor + s->avctx->i_quant_offset; - else if(pict_type==B_TYPE && s->avctx->b_quant_factor>0.0) - qscale[i]= rcc->next_non_b_qscale*s->avctx->b_quant_factor + s->avctx->b_quant_offset; - - if(pict_type!=B_TYPE) - rcc->next_non_b_qscale= qscale[i]; - if(pict_type==P_TYPE) - rcc->next_p_qscale= qscale[i]; + + qscale[i]= get_diff_limited_q(s, rce, qscale[i]); } /* smooth curve */