Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2019-06-11 16:51:39 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2019-06-11 16:51:39 +0300
commitc5b1e7cd4e86f9aff010fa84192d783b895ce6c7 (patch)
treed5813813e4c6fac596dbc7bfed31737b7ddece0b /source/blender/blenkernel/intern/writeffmpeg.c
parentbbba447d54b3f81dde82610d27925fa429e35870 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern/writeffmpeg.c')
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c9
1 files changed, 7 insertions, 2 deletions
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;