[FFmpeg-devel] [PATCH] Detect CFR/VFR in libx264.c for proper i_fps_*

Rudolf Polzer divVerent
Fri Feb 11 21:16:49 CET 2011


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;
+    }
 
     x4->params.analyse.inter    = 0;
     if (avctx->partitions) {
-- 
1.7.4




More information about the ffmpeg-devel mailing list