mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
stuffing to stay above min_bitrate
Originally committed as revision 2602 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
fb0666392c
commit
11dffbe1da
@ -1715,7 +1715,7 @@ int MPV_encode_picture(AVCodecContext *avctx,
|
|||||||
{
|
{
|
||||||
MpegEncContext *s = avctx->priv_data;
|
MpegEncContext *s = avctx->priv_data;
|
||||||
AVFrame *pic_arg = data;
|
AVFrame *pic_arg = data;
|
||||||
int i;
|
int i, stuffing_count;
|
||||||
|
|
||||||
if(avctx->pix_fmt != PIX_FMT_YUV420P){
|
if(avctx->pix_fmt != PIX_FMT_YUV420P){
|
||||||
av_log(avctx, AV_LOG_ERROR, "this codec supports only YUV420P\n");
|
av_log(avctx, AV_LOG_ERROR, "this codec supports only YUV420P\n");
|
||||||
@ -1767,11 +1767,35 @@ int MPV_encode_picture(AVCodecContext *avctx,
|
|||||||
|
|
||||||
flush_put_bits(&s->pb);
|
flush_put_bits(&s->pb);
|
||||||
s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
|
s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
|
||||||
|
|
||||||
|
stuffing_count= ff_vbv_update(s, s->frame_bits);
|
||||||
|
if(stuffing_count){
|
||||||
|
switch(s->codec_id){
|
||||||
|
case CODEC_ID_MPEG1VIDEO:
|
||||||
|
case CODEC_ID_MPEG2VIDEO:
|
||||||
|
while(stuffing_count--){
|
||||||
|
put_bits(&s->pb, 8, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CODEC_ID_MPEG4:
|
||||||
|
put_bits(&s->pb, 16, 0);
|
||||||
|
put_bits(&s->pb, 16, 0x1C3);
|
||||||
|
stuffing_count -= 4;
|
||||||
|
while(stuffing_count--){
|
||||||
|
put_bits(&s->pb, 8, 0xFF);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");
|
||||||
|
}
|
||||||
|
flush_put_bits(&s->pb);
|
||||||
|
s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
s->total_bits += s->frame_bits;
|
s->total_bits += s->frame_bits;
|
||||||
avctx->frame_bits = s->frame_bits;
|
avctx->frame_bits = s->frame_bits;
|
||||||
|
|
||||||
return pbBufPtr(&s->pb) - s->pb.buf;
|
return s->frame_bits/8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //CONFIG_ENCODERS
|
#endif //CONFIG_ENCODERS
|
||||||
|
@ -897,6 +897,7 @@ double ff_eval(char *s, double *const_value, const char **const_name,
|
|||||||
double (**func1)(void *, double), const char **func1_name,
|
double (**func1)(void *, double), const char **func1_name,
|
||||||
double (**func2)(void *, double, double), char **func2_name,
|
double (**func2)(void *, double, double), char **func2_name,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
int ff_vbv_update(MpegEncContext *s, int frame_size);
|
||||||
|
|
||||||
|
|
||||||
#endif /* AVCODEC_MPEGVIDEO_H */
|
#endif /* AVCODEC_MPEGVIDEO_H */
|
||||||
|
@ -195,7 +195,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits){
|
|||||||
return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
|
return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_rc_buffer(MpegEncContext *s, int frame_size){
|
int ff_vbv_update(MpegEncContext *s, int frame_size){
|
||||||
RateControlContext *rcc= &s->rc_context;
|
RateControlContext *rcc= &s->rc_context;
|
||||||
const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
|
const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
|
||||||
const double buffer_size= s->avctx->rc_buffer_size;
|
const double buffer_size= s->avctx->rc_buffer_size;
|
||||||
@ -216,10 +216,19 @@ static void update_rc_buffer(MpegEncContext *s, int frame_size){
|
|||||||
rcc->buffer_index += clip(left, min_rate, max_rate);
|
rcc->buffer_index += clip(left, min_rate, max_rate);
|
||||||
|
|
||||||
if(rcc->buffer_index > s->avctx->rc_buffer_size){
|
if(rcc->buffer_index > s->avctx->rc_buffer_size){
|
||||||
av_log(s->avctx, AV_LOG_ERROR, "rc buffer overflow\n");
|
int stuffing= ceil((rcc->buffer_index - s->avctx->rc_buffer_size)/8);
|
||||||
rcc->buffer_index= s->avctx->rc_buffer_size;
|
|
||||||
|
if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4)
|
||||||
|
stuffing=4;
|
||||||
|
rcc->buffer_index -= 8*stuffing;
|
||||||
|
|
||||||
|
if(s->avctx->debug & FF_DEBUG_RC)
|
||||||
|
av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
|
||||||
|
|
||||||
|
return stuffing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -619,9 +628,6 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
|
|||||||
rce->b_code = s->b_code;
|
rce->b_code = s->b_code;
|
||||||
rce->misc_bits= 1;
|
rce->misc_bits= 1;
|
||||||
|
|
||||||
if(picture_number>0)
|
|
||||||
update_rc_buffer(s, s->frame_bits);
|
|
||||||
|
|
||||||
bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
|
bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
|
||||||
if(pict_type== I_TYPE){
|
if(pict_type== I_TYPE){
|
||||||
rce->i_count = s->mb_num;
|
rce->i_count = s->mb_num;
|
||||||
@ -814,7 +820,7 @@ static int init_pass2(MpegEncContext *s)
|
|||||||
rce->new_qscale= modify_qscale(s, rce, blured_qscale[i], i);
|
rce->new_qscale= modify_qscale(s, rce, blured_qscale[i], i);
|
||||||
bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
|
bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
|
||||||
//printf("%d %f\n", rce->new_bits, blured_qscale[i]);
|
//printf("%d %f\n", rce->new_bits, blured_qscale[i]);
|
||||||
update_rc_buffer(s, bits);
|
bits += 8*ff_vbv_update(s, bits);
|
||||||
|
|
||||||
rce->expected_bits= expected_bits;
|
rce->expected_bits= expected_bits;
|
||||||
expected_bits += bits;
|
expected_bits += bits;
|
||||||
|
Loading…
Reference in New Issue
Block a user