PR #23497 opened by Bogdan Lisman (bogdanpydev)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23497
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23497.patch

The leading sign of a (sub)expression is stored as +-1 in each node's
value field (parse_factor) and every other function multiplies its
result by it. print, squish, gauss and lerp ignored it, so e.g.
-print(1) evaluated to 1 instead of -1 and -gauss(0) to 0.398942
instead of -0.398942, while -1*print(1) was correct.

Fixes: ticket #9833
Reported-by: Player701
Signed-off-by: Bogdan Lisman <[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 4a1420f6d57006c58893ac987a0123c0738f61f3 Mon Sep 17 00:00:00 2001
From: Bogdan Lisman <[email protected]>
Date: Mon, 15 Jun 2026 01:48:35 +0300
Subject: [PATCH] avutil/eval: apply unary sign to print, squish, gauss and
 lerp

The leading sign of a (sub)expression is stored as +-1 in each node's
value field (parse_factor) and every other function multiplies its
result by it. print, squish, gauss and lerp ignored it, so e.g.
-print(1) evaluated to 1 instead of -1 and -gauss(0) to 0.398942
instead of -0.398942, while -1*print(1) was correct.

Fixes: ticket #9833
Reported-by: Player701
Signed-off-by: Bogdan Lisman <[email protected]>
---
 libavutil/eval.c       |  8 ++++----
 libavutil/tests/eval.c |  5 +++++
 tests/ref/fate/eval    | 15 +++++++++++++++
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/libavutil/eval.c b/libavutil/eval.c
index 56123a3831..2bd07b98c1 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -201,8 +201,8 @@ static double eval_expr(Parser *p, AVExpr *e)
         case e_func0:  return e->value * e->func0(eval_expr(p, e->param[0]));
         case e_func1:  return e->value * e->func1(p->opaque, eval_expr(p, 
e->param[0]));
         case e_func2:  return e->value * e->func2(p->opaque, eval_expr(p, 
e->param[0]), eval_expr(p, e->param[1]));
-        case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0])));
-        case e_gauss: { double d = eval_expr(p, e->param[0]); return 
exp(-d*d/2)/sqrt(2*M_PI); }
+        case e_squish: return e->value/(1+exp(4*eval_expr(p, e->param[0])));
+        case e_gauss: { double d = eval_expr(p, e->param[0]); return e->value 
* exp(-d*d/2)/sqrt(2*M_PI); }
         case e_ld:     return e->value * p->var[av_clip(eval_expr(p, 
e->param[0]), 0, VARS-1)];
         case e_isnan:  return e->value * !!isnan(eval_expr(p, e->param[0]));
         case e_isinf:  return e->value * !!isinf(eval_expr(p, e->param[0]));
@@ -233,13 +233,13 @@ static double eval_expr(Parser *p, AVExpr *e)
             double v0 = eval_expr(p, e->param[0]);
             double v1 = eval_expr(p, e->param[1]);
             double f  = eval_expr(p, e->param[2]);
-            return v0 + (v1 - v0) * f;
+            return e->value * (v0 + (v1 - v0) * f);
         }
         case e_print: {
             double x = eval_expr(p, e->param[0]);
             int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), 
INT_MIN, INT_MAX) : AV_LOG_INFO;
             av_log(p, level, "%f\n", x);
-            return x;
+            return e->value * x;
         }
 
 #define COMPUTE_NEXT_RANDOM()                                        \
diff --git a/libavutil/tests/eval.c b/libavutil/tests/eval.c
index b64c6d635d..1014e2b936 100644
--- a/libavutil/tests/eval.c
+++ b/libavutil/tests/eval.c
@@ -126,9 +126,14 @@ int main(int argc, char **argv)
         "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
         "7000000B*random(0)",
         "squish(2)",
+        "-squish(2)",
         "gauss(0.1)",
+        "-gauss(0.1)",
         "hypot(4,3)",
         "gcd(30,55)*print(min(9,1))",
+        "-print(42)",
+        "lerp(0, 100, 0.5)",
+        "-lerp(0, 100, 0.5)",
         "bitor(42, 12)",
         "bitand(42, 12)",
         "bitand(NAN, 1)",
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
index 441f9846c4..196c1b5c86 100644
--- a/tests/ref/fate/eval
+++ b/tests/ref/fate/eval
@@ -262,15 +262,30 @@ Evaluating '7000000B*random(0)'
 Evaluating 'squish(2)'
 'squish(2)' -> 0.000335
 
+Evaluating '-squish(2)'
+'-squish(2)' -> -0.000335
+
 Evaluating 'gauss(0.1)'
 'gauss(0.1)' -> 0.396953
 
+Evaluating '-gauss(0.1)'
+'-gauss(0.1)' -> -0.396953
+
 Evaluating 'hypot(4,3)'
 'hypot(4,3)' -> 5.000000
 
 Evaluating 'gcd(30,55)*print(min(9,1))'
 'gcd(30,55)*print(min(9,1))' -> 5.000000
 
+Evaluating '-print(42)'
+'-print(42)' -> -42.000000
+
+Evaluating 'lerp(0, 100, 0.5)'
+'lerp(0, 100, 0.5)' -> 50.000000
+
+Evaluating '-lerp(0, 100, 0.5)'
+'-lerp(0, 100, 0.5)' -> -50.000000
+
 Evaluating 'bitor(42, 12)'
 'bitor(42, 12)' -> 46.000000
 
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to