[FFmpeg-devel] [PATCH] avutil/opt: Support max > INT64_MAX in write_number() with AV_OPT_TYPE_INT64

Michael Niedermayer michaelni at gmx.at
Sun Oct 25 19:46:42 CET 2015


From: Michael Niedermayer <michael at niedermayer.cc>

This allows for example to set max to UINT64_MAX and set values in that
range

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 libavutil/opt.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 36eeeb0..157179c 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -102,7 +102,17 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
     case AV_OPT_TYPE_DURATION:
     case AV_OPT_TYPE_CHANNEL_LAYOUT:
-    case AV_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;
+    case AV_OPT_TYPE_INT64:
+        // We must special case uint64_t here as llrint() does not support values
+        // outside the int64_t range and there is no portable function which does
+        // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double
+        // while INT64_MAX is not
+        if (o->max > INT64_MAX + 1ULL && num/den > INT64_MAX + 1ULL) {
+            *(uint64_t *)dst = (llrint(num/den - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum;
+        } else {
+            *(int64_t  *)dst = llrint(num/den)*intnum;
+        }
+        break;
     case AV_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;
     case AV_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;
     case AV_OPT_TYPE_RATIONAL:
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list