[Bf-blender-cvs] [c5b1e7cd4e8] master: FFmpeg: Fix integer overflow when writing custom FPS with high denominator

Sybren A. Stüvel noreply at git.blender.org
Tue Jun 11 15:52:43 CEST 2019


Commit: c5b1e7cd4e86f9aff010fa84192d783b895ce6c7
Author: Sybren A. Stüvel
Date:   Tue Jun 11 15:51:39 2019 +0200
Branches: master
https://developer.blender.org/rBc5b1e7cd4e86f9aff010fa84192d783b895ce6c7

FFmpeg: Fix integer overflow when writing custom FPS with high denominator

FFmpeg uses a fraction of integers to indicate the frame rate, whereas
Blender uses `int / float`. When a custom frame rate is used with
non-integer base, the FPS and Base settings were multiplied with 100000
before passing to FFmpeg as `int`. This could overflow when a high
enough FPS setting was used, which is the case when importing a video of
almost-but-not-quite-integer frame rate into the VSE. The overflow
caused FFmpeg to return an error "The encoder timebase is not set",
which is rather cryptic for users.

The new solution is to take the max int and divide that by the frame
rate, and use that ratio to pass to FFmpeg. This won't overflow, and
thus allows exporting arbitrary frame rates.

===================================================================

M	source/blender/blenkernel/intern/writeffmpeg.c

===================================================================

diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index ae41b8f3272..fb8bfa1dfd9 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -589,8 +589,13 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
     c->time_base.num = (int)rd->frs_sec_base;
   }
   else {
-    c->time_base.den = rd->frs_sec * 100000;
-    c->time_base.num = ((double)rd->frs_sec_base) * 100000;
+    // This calculates a fraction (DENUM_MAX / num) which approximates the scene
+    // frame rate (frs_sec / frs_sec_base).
+    const double DENUM_MAX = 2147483647;
+    const double num = (DENUM_MAX / (double)rd->frs_sec) * rd->frs_sec_base;
+
+    c->time_base.den = (int)DENUM_MAX;
+    c->time_base.num = (int)num;
   }
 
   c->gop_size = context->ffmpeg_gop_size;



More information about the Bf-blender-cvs mailing list