]> git.sesse.net Git - ffmpeg/commitdiff
avutil/eval: add function to track variable use
authorGyan Doshi <ffmpeg@gyani.pro>
Sun, 17 Nov 2019 05:32:10 +0000 (11:02 +0530)
committerGyan Doshi <ffmpeg@gyani.pro>
Sun, 17 Nov 2019 05:37:05 +0000 (11:07 +0530)
1)Some filters allow cross-referenced expressions e.g. x=y+10. In
such cases, filters evaluate expressions multiple times for
successful evaluation of all expressions. If the expression for one or
more variables contains a RNG, the result may vary across evaluation
leading to inconsistent values across the cross-referenced expressions.

2)A related case is circular expressions e.g. x=y+10 and y=x+10 which
cannot be succesfully resolved.

3)Certain filter variables may only be applicable in specific eval modes
and lead to a failure of evaluation in other modes e.g. pts is only
relevant for frame eval mode.

At present, there is no reliable means to identify these occurrences and
thus the error messages provided are broad or inaccurate. The helper
function introduced - av_expr_count_vars - allows developers to identify
the use and count of variables in expressions and thus tailor the error
message, allow for a graceful fallback and/or decide evaluation order.

libavutil/eval.c
libavutil/eval.h
libavutil/version.h

index 48832979e2d6c9cabf1b9ecf0ae8ee6f86b654b4..62d2ae938b373aca31f63e70474ad1cad854c05f 100644 (file)
@@ -735,6 +735,22 @@ end:
     return ret;
 }
 
+int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
+{
+    int i;
+
+    if (!e || !counter || !size)
+        return AVERROR(EINVAL);
+
+    for (i = 0; e->type != e_const && i < 3 && e->param[i]; i++)
+        av_expr_count_vars(e->param[i], counter, size);
+
+    if (e->type == e_const && e->a.const_index < size)
+        counter[e->a.const_index]++;
+
+    return 0;
+}
+
 double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
 {
     Parser p = { 0 };
index dacd22b96e66cec8818f1b2f5c806df166eb9d86..9bdb10cca2b02a41245c2a0482ea76e344cce3dc 100644 (file)
@@ -86,6 +86,16 @@ int av_expr_parse(AVExpr **expr, const char *s,
  */
 double av_expr_eval(AVExpr *e, const double *const_values, void *opaque);
 
+/**
+ * Track the presence of variables and their number of occurrences in a parsed expression
+ *
+ * @param counter a zero-initialized array where the count of each variable will be stored
+ * @param size size of array
+ * @return 0 on success, a negative value indicates that no expression or array was passed
+ * or size was zero
+ */
+int av_expr_count_vars(AVExpr *e, unsigned *counter, int size);
+
 /**
  * Free a parsed expression previously created with av_expr_parse().
  */
index 27d663baf1aa5f1c5971e8189d64a05b9418c7c1..af3abf726596deed645222d19f08924bf37056b3 100644 (file)
@@ -79,8 +79,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  35
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR  36
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \