avutil/eval: Add av_expr_count_func() similar to av_expr_count_vars()
authorMichael Niedermayer <michael@niedermayer.cc>
Fri, 6 Dec 2019 16:18:16 +0000 (17:18 +0100)
committerMichael Niedermayer <michael@niedermayer.cc>
Sat, 28 Dec 2019 10:20:48 +0000 (11:20 +0100)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
doc/APIchanges
libavutil/eval.c
libavutil/eval.h
libavutil/version.h

index 5b8d801..3c24dc6 100644 (file)
@@ -15,6 +15,9 @@ libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2019-12-27 - xxxxxxxxxx - lavu 56.38.100 - eval.h
+  Add av_expr_count_func().
+
 2019-12-xx - xxxxxxxxxx - lavu 56.37.100 - buffer.h
   Add av_buffer_pool_buffer_get_opaque().
 
index 62d2ae9..d527f6a 100644 (file)
@@ -166,8 +166,8 @@ struct AVExpr {
         e_sgn,
     } type;
     double value; // is sign in other types
+    int const_index;
     union {
-        int const_index;
         double (*func0)(double);
         double (*func1)(void *, double);
         double (*func2)(void *, double, double);
@@ -185,7 +185,7 @@ static double eval_expr(Parser *p, AVExpr *e)
 {
     switch (e->type) {
         case e_value:  return e->value;
-        case e_const:  return e->value * p->const_values[e->a.const_index];
+        case e_const:  return e->value * p->const_values[e->const_index];
         case e_func0:  return e->value * e->a.func0(eval_expr(p, e->param[0]));
         case e_func1:  return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0]));
         case e_func2:  return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1]));
@@ -367,7 +367,7 @@ static int parse_primary(AVExpr **e, Parser *p)
         if (strmatch(p->s, p->const_names[i])) {
             p->s+= strlen(p->const_names[i]);
             d->type = e_const;
-            d->a.const_index = i;
+            d->const_index = i;
             *e = d;
             return 0;
         }
@@ -478,6 +478,7 @@ static int parse_primary(AVExpr **e, Parser *p)
             if (strmatch(next, p->func1_names[i])) {
                 d->a.func1 = p->funcs1[i];
                 d->type = e_func1;
+                d->const_index = i;
                 *e = d;
                 return 0;
             }
@@ -487,6 +488,7 @@ static int parse_primary(AVExpr **e, Parser *p)
             if (strmatch(next, p->func2_names[i])) {
                 d->a.func2 = p->funcs2[i];
                 d->type = e_func2;
+                d->const_index = i;
                 *e = d;
                 return 0;
             }
@@ -735,22 +737,32 @@ end:
     return ret;
 }
 
-int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
+static int expr_count(AVExpr *e, unsigned *counter, int size, int type)
 {
     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);
+    for (i = 0; e->type != type && i < 3 && e->param[i]; i++)
+        expr_count(e->param[i], counter, size, type);
 
-    if (e->type == e_const && e->a.const_index < size)
-        counter[e->a.const_index]++;
+    if (e->type == type && e->const_index < size)
+        counter[e->const_index]++;
 
     return 0;
 }
 
+int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
+{
+    return expr_count(e, counter, size, e_const);
+}
+
+int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg)
+{
+    return expr_count(e, counter, size, ((int[]){e_const, e_func1, e_func2})[arg]);
+}
+
 double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
 {
     Parser p = { 0 };
index 9bdb10c..068c62c 100644 (file)
@@ -96,6 +96,20 @@ double av_expr_eval(AVExpr *e, const double *const_values, void *opaque);
  */
 int av_expr_count_vars(AVExpr *e, unsigned *counter, int size);
 
+/**
+ * Track the presence of user provided functions and their number of occurrences
+ * in a parsed expression.
+ *
+ * @param counter a zero-initialized array where the count of each function will be stored
+ *                if you passed 5 functions with 2 arguments to av_expr_parse()
+ *                then for arg=2 this will use upto 5 entries.
+ * @param size size of array
+ * @param arg number of arguments the counted functions have
+ * @return 0 on success, a negative value indicates that no expression or array was passed
+ * or size was zero
+ */
+int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg);
+
 /**
  * Free a parsed expression previously created with av_expr_parse().
  */
index 4de0fa1..af8f614 100644 (file)
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  37
+#define LIBAVUTIL_VERSION_MINOR  38
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \