# HG changeset patch # User michael # Date 1274309729 0 # Node ID c6368258b694895f36d90b8f4bde75be2f9524cd # Parent 40911dc14bdc84ec840334d90edbd70c7ab9f507 Change eval API to take parent log context and log level offset. this is based on stefanos work, especially all bugs are his fault ;) diff -r 40911dc14bdc -r c6368258b694 eval.c --- 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; diff -r 40911dc14bdc -r c6368258b694 eval.h --- 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. diff -r 40911dc14bdc -r c6368258b694 opt.c --- 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){ diff -r 40911dc14bdc -r c6368258b694 ratecontrol.c --- 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; }