[FFmpeg-devel] [PATCH] Detect CFR/VFR in libx264.c for proper i_fps_*
Måns Rullgård
mans
Fri Feb 11 22:15:59 CET 2011
Rudolf Polzer <divVerent at alientrap.org> writes:
> On Fri, Feb 11, 2011 at 08:30:21PM +0000, M?ns Rullg?rd wrote:
>> Rudolf Polzer <divVerent at alientrap.org> writes:
>>
>> > This change adds a detection of constant/variable frame rate by the same
>> > heuristics as libavformat/utils.c already uses (in performing or refusing
>> > frame duration calculation). The heuristics is basically to check whether
>> > the time base is larger than 1ms, and assume CFR then, VFR otherwise.
>> >
>> > Without it, x264 estimates a huge macroblock rate, and thus forces H.264 level
>> > 5.1 even if the input could perfectly fine pass as e.g. level 2.1.
>> >
>> > Signed-off-by: Rudolf Polzer <divVerent at alientrap.org>
>> > ---
>> > libavcodec/libx264.c | 23 +++++++++++++++++++++--
>> > 1 files changed, 21 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
>> > index 0dad5cd..02f7aca 100644
>> > --- a/libavcodec/libx264.c
>> > +++ b/libavcodec/libx264.c
>> > @@ -217,8 +217,27 @@ static av_cold int X264_init(AVCodecContext *avctx)
>> > x4->params.i_height = avctx->height;
>> > x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num;
>> > x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den;
>> > - x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den;
>> > - x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num;
>> > + x4->params.i_timebase_den = avctx->time_base.den;
>> > + x4->params.i_timebase_num = avctx->time_base.num;
>> > +
>> > + if (avctx->time_base.num * 1000LL > avctx->time_base.den) { // "if time base > 1ms"
>> > + // this is a heuristic to distinugish variable from constant frame rate
>> > + // encoding
>> > + // NOTE: this is not a new hack; compute_frame_duration() in
>> > + // libavformat/utils.c uses the same heuristics
>> > + x4->params.i_fps_num = avctx->time_base.den;
>> > + x4->params.i_fps_den = avctx->time_base.num;
>> > + // not doing VFR
>> > + x4->params.b_vfr_input = 0;
>> > + } else {
>> > + // set this to a sensible but guessed frame rate (x264 source also
>> > + // often uses this rate if none is available, but not in any occasion,
>> > + // so we cannot set these to 0/0)
>> > + x4->params.i_fps_num = 25;
>> > + x4->params.i_fps_den = 1;
>> > + // IMPORTANT: tell x264 rate control that we are doing VFR
>> > + x4->params.b_vfr_input = 1;
>> > + }
>>
>> This kind of thing doesn't really belong at the individual codec level.
>> An override if the heuristic makes a wrong guess might be nice too.
>
> True, but this would need a design change to ffmpeg, as it would need adding
> frame rate information to the structs (ideally, for best usefulness, three
> things: a VFR flag, peak fps, and average fps).
>
> My point is, though: this currently breaks VFR encoding with x264 - the one
> most useful codec today. I want this fixed, and don't really care much how it
> is fixed. I don't know ffmpeg internals (and policies) well enough to make my
> own patch "the way you guys want it", so someone else will have to take this on
> then.
I'm not insisting you do the work to support it properly, nor am I
rejecting this patch outright. I am merely requesting that we pause and
consider the best solution possible today, which may be a step towards
what we want as the ultimate goal. This could be as simple as adding a
generic flag indicating that time base != frame rate, for instance.
--
M?ns Rullg?rd
mans at mansr.com
More information about the ffmpeg-devel
mailing list