mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
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 ;) ).
This commit is contained in:
parent
0e37c98257
commit
a73b390f48
2 changed files with 19 additions and 5 deletions
|
|
@ -105,8 +105,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 */
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#ifndef _WIN32
|
||||
#include <dirent.h>
|
||||
#else
|
||||
|
|
@ -1398,15 +1399,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue