From c528b9b7777322c2b714aaa0bec40a1f3997ad06 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 26 Jan 2018 14:59:16 +0100 Subject: Fix T53003: IMB: Invalid framerate handling due to short integer overflow. FFMPEG uses int for the numerator, while Blender uses a short. So in cases people gave weird exotic framerate values and we cannot reduce enough the numerator, we'd get totally weird values (even negative frame rates sometimes!) Now we add checks for short overflow and approximate as best as possible in that case (error should not matter unless you have shots of at least several hundreds of hours ;) ). --- source/blender/imbuf/intern/IMB_anim.h | 4 ++-- source/blender/imbuf/intern/anim_movie.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index b10ae4f6fe9..c4c4f4405a5 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -99,8 +99,8 @@ struct anim { int curtype; int curposition; /* index 0 = 1e, 1 = 2e, enz. */ int duration; - short frs_sec; - float frs_sec_base; + int frs_sec; + double frs_sec_base; int x, y; /* for number */ diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 25b0c0d7b1a..4f535a26c3b 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -55,6 +55,7 @@ #include #include #include +#include #ifndef _WIN32 #include #else @@ -1365,15 +1366,28 @@ int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc) bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base) { + double frs_sec_base_double; if (anim->frs_sec) { - *frs_sec = anim->frs_sec; - *frs_sec_base = anim->frs_sec_base; + if (anim->frs_sec > SHRT_MAX) { + /* We cannot store original rational in our short/float format, + * we need to approximate it as best as we can... */ + *frs_sec = SHRT_MAX; + frs_sec_base_double = anim->frs_sec_base * (double)SHRT_MAX / (double)anim->frs_sec; + } + else { + *frs_sec = anim->frs_sec; + frs_sec_base_double = anim->frs_sec_base; + } #ifdef WITH_FFMPEG if (no_av_base) { - *frs_sec_base /= AV_TIME_BASE; + *frs_sec_base = (float)(frs_sec_base_double / AV_TIME_BASE); + } + else { + *frs_sec_base = (float)frs_sec_base_double; } #else UNUSED_VARS(no_av_base); + *frs_sec_base = (float)frs_sec_base_double; #endif return true; } -- cgit v1.2.3 From 47a3bbcc34185684813ba21d808f124c584a93ae Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 26 Jan 2018 15:13:35 +0100 Subject: IMB: Add asserts that returned fps and fps base are strictly positives. Forgot to add that in previous commit, also related to T53003. --- source/blender/imbuf/intern/anim_movie.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 4f535a26c3b..5472cae3ef2 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -1389,6 +1389,9 @@ bool IMB_anim_get_fps(struct anim *anim, UNUSED_VARS(no_av_base); *frs_sec_base = (float)frs_sec_base_double; #endif + BLI_assert(*frs_sec > 0); + BLI_assert(*frs_sec_base > 0.0f); + return true; } return false; -- cgit v1.2.3