changeset 11749:c6368258b694 libavcodec

Change eval API to take parent log context and log level offset. this is based on stefanos work, especially all bugs are his fault ;)
author michael
date Wed, 19 May 2010 22:55:29 +0000
parents 40911dc14bdc
children d7a5fc4b7aee
files eval.c eval.h opt.c ratecontrol.c
diffstat 4 files changed, 30 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/eval.c	Wed May 19 20:48:29 2010 +0000
+++ b/eval.c	Wed May 19 22:55:29 2010 +0000
@@ -30,6 +30,7 @@
 #include "eval.h"
 
 typedef struct Parser{
+    const AVClass *class;
     int stack_index;
     char *s;
     const double *const_value;
@@ -39,11 +40,14 @@
     double (* const *func2)(void *, double a, double b); // NULL terminated
     const char * const *func2_name;          // NULL terminated
     void *opaque;
-    const char **error;
+    int log_offset;
+    void *log_ctx;
 #define VARS 10
     double var[VARS];
 } Parser;
 
+static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) };
+
 static const int8_t si_prefixes['z' - 'E' + 1]={
     ['y'-'E']= -24,
     ['z'-'E']= -21,
@@ -201,7 +205,7 @@
 
     p->s= strchr(p->s, '(');
     if(p->s==NULL){
-        *p->error = "undefined constant or missing (";
+        av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n");
         p->s= next;
         ff_free_expr(d);
         return NULL;
@@ -211,7 +215,7 @@
         av_freep(&d);
         d = parse_expr(p);
         if(p->s[0] != ')'){
-            *p->error = "missing )";
+            av_log(p, AV_LOG_ERROR, "missing )\n");
             ff_free_expr(d);
             return NULL;
         }
@@ -224,7 +228,7 @@
         d->param[1] = parse_expr(p);
     }
     if(p->s[0] != ')'){
-        *p->error = "missing )";
+        av_log(p, AV_LOG_ERROR, "missing )\n");
         ff_free_expr(d);
         return NULL;
     }
@@ -273,7 +277,7 @@
             }
         }
 
-        *p->error = "unknown function";
+        av_log(p, AV_LOG_ERROR, "unknown function\n");
         ff_free_expr(d);
         return NULL;
     }
@@ -373,7 +377,8 @@
                       const char * const *const_name,
                       const char * const *func1_name, double (* const *func1)(void *, double),
                       const char * const *func2_name, double (* const *func2)(void *, double, double),
-               const char **error){
+                      int log_offset, void *log_ctx)
+{
     Parser p;
     AVExpr *e = NULL;
     char *w = av_malloc(strlen(s) + 1);
@@ -386,6 +391,7 @@
         if (!isspace(*s++)) *wp++ = s[-1];
     *wp++ = 0;
 
+    p.class      = &class;
     p.stack_index=100;
     p.s= w;
     p.const_name = const_name;
@@ -393,7 +399,8 @@
     p.func1_name = func1_name;
     p.func2      = func2;
     p.func2_name = func2_name;
-    p.error= error;
+    p.log_offset = log_offset;
+    p.log_ctx    = log_ctx;
 
     e = parse_expr(&p);
     if (!verify_expr(e)) {
@@ -417,8 +424,9 @@
                               const char * const *const_name, const double *const_value,
                               const char * const *func1_name, double (* const *func1)(void *, double),
                               const char * const *func2_name, double (* const *func2)(void *, double, double),
-               void *opaque, const char **error){
-    AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, error);
+                              void *opaque, int log_offset, void *log_ctx)
+{
+    AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, log_offset, log_ctx);
     double d;
     if (!e) return NAN;
     d = ff_eval_expr(e, const_value, opaque);
@@ -440,12 +448,12 @@
 };
 int main(void){
     int i;
-    printf("%f == 12.7\n", ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL));
+    printf("%f == 12.7\n", ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL));
     printf("%f == 0.931322575\n", ff_parse_and_eval_expr("80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL));
 
     for(i=0; i<1050; i++){
         START_TIMER
-            ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL);
+            ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL);
         STOP_TIMER("ff_parse_and_eval_expr")
     }
     return 0;
--- a/eval.h	Wed May 19 20:48:29 2010 +0000
+++ b/eval.h	Wed May 19 22:55:29 2010 +0000
@@ -39,15 +39,15 @@
  * @param func1 NULL terminated array of function pointers for functions which take 1 argument
  * @param func2_name NULL terminated array of zero terminated strings of func2 identifers
  * @param func2 NULL terminated array of function pointers for functions which take 2 arguments
- * @param error pointer to a char* which is set to an error message if something goes wrong
  * @param opaque a pointer which will be passed to all functions from func1 and func2
+ * @param log_ctx parent logging context
  * @return the value of the expression
  */
 double ff_parse_and_eval_expr(const char *s,
                               const char * const *const_name, const double *const_value,
                               const char * const *func1_name, double (* const *func1)(void *, double),
                               const char * const *func2_name, double (* const *func2)(void *, double, double),
-               void *opaque, const char **error);
+                              void *opaque, int log_offset, void *log_ctx);
 
 /**
  * Parses an expression.
@@ -58,7 +58,7 @@
  * @param func1 NULL terminated array of function pointers for functions which take 1 argument
  * @param func2_name NULL terminated array of zero terminated strings of func2 identifers
  * @param func2 NULL terminated array of function pointers for functions which take 2 arguments
- * @param error pointer to a char* which is set to an error message if something goes wrong
+ * @param log_ctx parent logging context
  * @return AVExpr which must be freed with ff_free_expr() by the user when it is not needed anymore
  *         NULL if anything went wrong
  */
@@ -66,7 +66,7 @@
                       const char * const *const_name,
                       const char * const *func1_name, double (* const *func1)(void *, double),
                       const char * const *func2_name, double (* const *func2)(void *, double, double),
-               const char **error);
+                      int log_offset, void *log_ctx);
 
 /**
  * Evaluates a previously parsed expression.
--- a/opt.c	Wed May 19 20:48:29 2010 +0000
+++ b/opt.c	Wed May 19 22:55:29 2010 +0000
@@ -147,7 +147,6 @@
             char buf[256];
             int cmd=0;
             double d;
-            const char *error = NULL;
 
             if(*val == '+' || *val == '-')
                 cmd= *(val++);
@@ -156,8 +155,7 @@
                 buf[i]= val[i];
             buf[i]=0;
 
-            d = ff_parse_and_eval_expr(buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, &error);
-            if(isnan(d)) {
+            {
                 const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
                 if(o_named && o_named->type == FF_OPT_TYPE_CONST)
                     d= o_named->default_val;
@@ -167,9 +165,11 @@
                 else if(!strcmp(buf, "none"   )) d= 0;
                 else if(!strcmp(buf, "all"    )) d= ~0;
                 else {
-                    if (error)
-                        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
+                    d = ff_parse_and_eval_expr(buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
+                    if (isnan(d)){
+                        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
                     return AVERROR(EINVAL);
+                    }
                 }
             }
             if(o->type == FF_OPT_TYPE_FLAGS){
--- a/ratecontrol.c	Wed May 19 20:48:29 2010 +0000
+++ b/ratecontrol.c	Wed May 19 22:55:29 2010 +0000
@@ -67,7 +67,6 @@
 {
     RateControlContext *rcc= &s->rc_context;
     int i;
-    const char *error = NULL;
     static const char * const const_names[]={
         "PI",
         "E",
@@ -107,9 +106,9 @@
     };
     emms_c();
 
-    rcc->rc_eq_eval = ff_parse_expr(s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, &error);
+    rcc->rc_eq_eval = ff_parse_expr(s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx);
     if (!rcc->rc_eq_eval) {
-        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : "");
+        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
         return -1;
     }