[PR] avutil/opt: ignore range check on default values (PR #24301)
Niklas Haas via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24301 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24301
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24301.patch
Filters may want to deliberately set a default value that is outside the
range of permissible values. One use case for this is AV_OPT_TYPE_RATIONAL,
which does not currently permit a value of { .dbl = NAN } by default, even
though the semi-equivalent AV_OPT_TYPE_FLOAT/DOUBLE do.
This is a genuine inconsistency, and universally rejecting the range check
for default options is probably the right way to solve it.
Signed-off-by: Niklas Haas <[email protected]>
# Summary of changes
Briefly describe what this PR does and why.
<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).
Attached filenames must match the sample's filename:
```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->
>From 0ade1d2e1d09dcd87bcf92f442c9a44c79c4ba02 Mon Sep 17 00:00:00 2001
From: Niklas Haas <[email protected]>
Date: Fri, 28 Aug 2026 13:18:32 +0200
Subject: [PATCH] avutil/opt: ignore range check on default values
Filters may want to deliberately set a default value that is outside the
range of permissible values. One use case for this is AV_OPT_TYPE_RATIONAL,
which does not currently permit a value of { .dbl = NAN } by default, even
though the semi-equivalent AV_OPT_TYPE_FLOAT/DOUBLE do.
This is a genuine inconsistency, and universally rejecting the range check
for default options is probably the right way to solve it.
Signed-off-by: Niklas Haas <[email protected]>
---
libavutil/opt.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 6fa1ec9929..17bd453dad 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -272,19 +272,21 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den
return AVERROR(EINVAL);
}
-static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
+static int write_number(void *obj, const AVOption *o, void *dst,
+ double num, int den, int64_t intnum,
+ int ignore_range)
{
void *logctx = dst ? obj : NULL;
const enum AVOptionType type = TYPE_BASE(o->type);
- if (type != AV_OPT_TYPE_FLAGS &&
+ if (!ignore_range && type != AV_OPT_TYPE_FLAGS &&
(!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
num, o->name, o->min, o->max);
return AVERROR(ERANGE);
}
- if (type == AV_OPT_TYPE_FLAGS) {
+ if (!ignore_range && type == AV_OPT_TYPE_FLAGS) {
double d = num*intnum/den;
if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
av_log(logctx, AV_LOG_ERROR,
@@ -433,7 +435,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
int num, den;
char c;
if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
- if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
+ if ((ret = write_number(obj, o, dst, 1, den, num, 0)) >= 0)
return ret;
ret = 0;
}
@@ -510,7 +512,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
d = intnum &~(int64_t)d;
}
- if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
+ if ((ret = write_number(obj, o, dst, d, 1, 1, 0)) < 0)
return ret;
val += i;
if (!i || !*val)
@@ -761,7 +763,7 @@ static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
ret = set_string_video_rate(obj, o, val, &tmp);
if (ret < 0)
return ret;
- return write_number(obj, o, dst, 1, tmp.den, tmp.num);
+ return write_number(obj, o, dst, 1, tmp.den, tmp.num, 0);
}
case AV_OPT_TYPE_PIXEL_FMT:
return set_string_pixel_fmt(obj, o, val, dst);
@@ -928,7 +930,7 @@ static int set_number(void *obj, const char *name, double num, int den, int64_t
if (ret < 0)
return ret;
if (dst)
- ret = write_number(obj, o, dst, num, den, intnum);
+ ret = write_number(obj, o, dst, num, den, intnum, 0);
return ret;
}
@@ -1798,19 +1800,19 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
- write_number(s, opt, dst, 1, 1, opt->default_val.i64);
+ write_number(s, opt, dst, 1, 1, opt->default_val.i64, 1);
break;
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_FLOAT: {
double val;
val = opt->default_val.dbl;
- write_number(s, opt, dst, val, 1, 1);
+ write_number(s, opt, dst, val, 1, 1, 1);
}
break;
case AV_OPT_TYPE_RATIONAL: {
AVRational val;
val = av_d2q(opt->default_val.dbl, INT_MAX);
- write_number(s, opt, dst, 1, val.den, val.num);
+ write_number(s, opt, dst, 1, val.den, val.num, 1);
}
break;
case AV_OPT_TYPE_COLOR:
@@ -2482,7 +2484,7 @@ int av_opt_set_array(void *obj, const char *name, int search_flags,
default: av_assert0(0);
}
- ret = write_number(obj, o, dst, num, den, intnum);
+ ret = write_number(obj, o, dst, num, den, intnum, 0);
if (ret < 0)
goto fail;
} else {
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]