diff options
author | Henrik Gramner <gramner@twoorioles.com> | 2020-05-10 23:44:33 +0300 |
---|---|---|
committer | Jean-Baptiste Kempf <jb@videolan.org> | 2020-05-11 10:17:49 +0300 |
commit | a0678eac0ee1a67ff871247b551e42fa448591b7 (patch) | |
tree | e5eb25f7391505661e463f552e510553ad46018a /tools | |
parent | 4d97f5a9d959679d472e7aa9f68503a69eb47202 (diff) |
cli: Reduce fps fraction in ivf parsing
Also avoid integer overflows by using 64-bit intermediate precision.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/input/ivf.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/tools/input/ivf.c b/tools/input/ivf.c index 746391d..7b572ee 100644 --- a/tools/input/ivf.c +++ b/tools/input/ivf.c @@ -28,6 +28,7 @@ #include "config.h" #include <errno.h> +#include <limits.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -92,8 +93,27 @@ static int ivf_open(IvfInputContext *const c, const char *const file, break; // EOF fseeko(c->f, rl32(data) + 8, SEEK_CUR); } - fps[0] = timebase[0] * *num_frames; - fps[1] = timebase[1] * duration; + + uint64_t fps_num = (uint64_t) timebase[0] * *num_frames; + uint64_t fps_den = (uint64_t) timebase[1] * duration; + if (fps_num && fps_den) { /* Reduce fraction */ + uint64_t gcd = fps_num; + for (uint64_t a = fps_den, b; (b = a % gcd); a = gcd, gcd = b); + fps_num /= gcd; + fps_den /= gcd; + + while ((fps_num | fps_den) > UINT_MAX) { + fps_num >>= 1; + fps_den >>= 1; + } + } + if (fps_num && fps_den) { + fps[0] = (unsigned) fps_num; + fps[1] = (unsigned) fps_den; + } else { + fps[0] = fps[1] = 0; + } + fseeko(c->f, 32, SEEK_SET); return 0; |