1
mirror of https://git.videolan.org/git/ffmpeg.git synced 2024-09-07 00:20:09 +02:00

better min/max rate handling

cleanup

Originally committed as revision 952 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2002-09-18 18:28:11 +00:00
parent 946c8a1281
commit 6a1f7e7b6b

View File

@ -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 */