Commit 0f99fad9 authored by michael's avatar michael

Change eval API to take parent log context and log level offset.

this is based on stefanos work, especially all bugs are his fault ;)


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@23201 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 57976bc8
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "eval.h" #include "eval.h"
typedef struct Parser{ typedef struct Parser{
const AVClass *class;
int stack_index; int stack_index;
char *s; char *s;
const double *const_value; const double *const_value;
...@@ -39,11 +40,14 @@ typedef struct Parser{ ...@@ -39,11 +40,14 @@ typedef struct Parser{
double (* const *func2)(void *, double a, double b); // NULL terminated double (* const *func2)(void *, double a, double b); // NULL terminated
const char * const *func2_name; // NULL terminated const char * const *func2_name; // NULL terminated
void *opaque; void *opaque;
const char **error; int log_offset;
void *log_ctx;
#define VARS 10 #define VARS 10
double var[VARS]; double var[VARS];
} Parser; } 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]={ static const int8_t si_prefixes['z' - 'E' + 1]={
['y'-'E']= -24, ['y'-'E']= -24,
['z'-'E']= -21, ['z'-'E']= -21,
...@@ -201,7 +205,7 @@ static AVExpr * parse_primary(Parser *p) { ...@@ -201,7 +205,7 @@ static AVExpr * parse_primary(Parser *p) {
p->s= strchr(p->s, '('); p->s= strchr(p->s, '(');
if(p->s==NULL){ if(p->s==NULL){
*p->error = "undefined constant or missing ("; av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n");
p->s= next; p->s= next;
ff_free_expr(d); ff_free_expr(d);
return NULL; return NULL;
...@@ -211,7 +215,7 @@ static AVExpr * parse_primary(Parser *p) { ...@@ -211,7 +215,7 @@ static AVExpr * parse_primary(Parser *p) {
av_freep(&d); av_freep(&d);
d = parse_expr(p); d = parse_expr(p);
if(p->s[0] != ')'){ if(p->s[0] != ')'){
*p->error = "missing )"; av_log(p, AV_LOG_ERROR, "missing )\n");
ff_free_expr(d); ff_free_expr(d);
return NULL; return NULL;
} }
...@@ -224,7 +228,7 @@ static AVExpr * parse_primary(Parser *p) { ...@@ -224,7 +228,7 @@ static AVExpr * parse_primary(Parser *p) {
d->param[1] = parse_expr(p); d->param[1] = parse_expr(p);
} }
if(p->s[0] != ')'){ if(p->s[0] != ')'){
*p->error = "missing )"; av_log(p, AV_LOG_ERROR, "missing )\n");
ff_free_expr(d); ff_free_expr(d);
return NULL; return NULL;
} }
...@@ -273,7 +277,7 @@ static AVExpr * parse_primary(Parser *p) { ...@@ -273,7 +277,7 @@ static AVExpr * parse_primary(Parser *p) {
} }
} }
*p->error = "unknown function"; av_log(p, AV_LOG_ERROR, "unknown function\n");
ff_free_expr(d); ff_free_expr(d);
return NULL; return NULL;
} }
...@@ -373,7 +377,8 @@ AVExpr *ff_parse_expr(const char *s, ...@@ -373,7 +377,8 @@ AVExpr *ff_parse_expr(const char *s,
const char * const *const_name, const char * const *const_name,
const char * const *func1_name, double (* const *func1)(void *, double), const char * const *func1_name, double (* const *func1)(void *, double),
const char * const *func2_name, double (* const *func2)(void *, double, double), const char * const *func2_name, double (* const *func2)(void *, double, double),
const char **error){ int log_offset, void *log_ctx)
{
Parser p; Parser p;
AVExpr *e = NULL; AVExpr *e = NULL;
char *w = av_malloc(strlen(s) + 1); char *w = av_malloc(strlen(s) + 1);
...@@ -386,6 +391,7 @@ AVExpr *ff_parse_expr(const char *s, ...@@ -386,6 +391,7 @@ AVExpr *ff_parse_expr(const char *s,
if (!isspace(*s++)) *wp++ = s[-1]; if (!isspace(*s++)) *wp++ = s[-1];
*wp++ = 0; *wp++ = 0;
p.class = &class;
p.stack_index=100; p.stack_index=100;
p.s= w; p.s= w;
p.const_name = const_name; p.const_name = const_name;
...@@ -393,7 +399,8 @@ AVExpr *ff_parse_expr(const char *s, ...@@ -393,7 +399,8 @@ AVExpr *ff_parse_expr(const char *s,
p.func1_name = func1_name; p.func1_name = func1_name;
p.func2 = func2; p.func2 = func2;
p.func2_name = func2_name; p.func2_name = func2_name;
p.error= error; p.log_offset = log_offset;
p.log_ctx = log_ctx;
e = parse_expr(&p); e = parse_expr(&p);
if (!verify_expr(e)) { if (!verify_expr(e)) {
...@@ -417,8 +424,9 @@ double ff_parse_and_eval_expr(const char *s, ...@@ -417,8 +424,9 @@ double ff_parse_and_eval_expr(const char *s,
const char * const *const_name, const double *const_value, const char * const *const_name, const double *const_value,
const char * const *func1_name, double (* const *func1)(void *, double), const char * const *func1_name, double (* const *func1)(void *, double),
const char * const *func2_name, double (* const *func2)(void *, double, 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)
AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, error); {
AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, log_offset, log_ctx);
double d; double d;
if (!e) return NAN; if (!e) return NAN;
d = ff_eval_expr(e, const_value, opaque); d = ff_eval_expr(e, const_value, opaque);
...@@ -440,12 +448,12 @@ static const char *const_names[]={ ...@@ -440,12 +448,12 @@ static const char *const_names[]={
}; };
int main(void){ int main(void){
int i; 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)); 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++){ for(i=0; i<1050; i++){
START_TIMER 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") STOP_TIMER("ff_parse_and_eval_expr")
} }
return 0; return 0;
......
...@@ -39,15 +39,15 @@ typedef struct AVExpr AVExpr; ...@@ -39,15 +39,15 @@ typedef struct AVExpr AVExpr;
* @param func1 NULL terminated array of function pointers for functions which take 1 argument * @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_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 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 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 * @return the value of the expression
*/ */
double ff_parse_and_eval_expr(const char *s, double ff_parse_and_eval_expr(const char *s,
const char * const *const_name, const double *const_value, const char * const *const_name, const double *const_value,
const char * const *func1_name, double (* const *func1)(void *, double), const char * const *func1_name, double (* const *func1)(void *, double),
const char * const *func2_name, double (* const *func2)(void *, double, 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. * Parses an expression.
...@@ -58,7 +58,7 @@ double ff_parse_and_eval_expr(const char *s, ...@@ -58,7 +58,7 @@ double ff_parse_and_eval_expr(const char *s,
* @param func1 NULL terminated array of function pointers for functions which take 1 argument * @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_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 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 * @return AVExpr which must be freed with ff_free_expr() by the user when it is not needed anymore
* NULL if anything went wrong * NULL if anything went wrong
*/ */
...@@ -66,7 +66,7 @@ AVExpr *ff_parse_expr(const char *s, ...@@ -66,7 +66,7 @@ AVExpr *ff_parse_expr(const char *s,
const char * const *const_name, const char * const *const_name,
const char * const *func1_name, double (* const *func1)(void *, double), const char * const *func1_name, double (* const *func1)(void *, double),
const char * const *func2_name, double (* const *func2)(void *, double, 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. * Evaluates a previously parsed expression.
......
...@@ -147,7 +147,6 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons ...@@ -147,7 +147,6 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
char buf[256]; char buf[256];
int cmd=0; int cmd=0;
double d; double d;
const char *error = NULL;
if(*val == '+' || *val == '-') if(*val == '+' || *val == '-')
cmd= *(val++); cmd= *(val++);
...@@ -156,8 +155,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons ...@@ -156,8 +155,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
buf[i]= val[i]; buf[i]= val[i];
buf[i]=0; 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); const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
if(o_named && o_named->type == FF_OPT_TYPE_CONST) if(o_named && o_named->type == FF_OPT_TYPE_CONST)
d= o_named->default_val; d= o_named->default_val;
...@@ -167,9 +165,11 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons ...@@ -167,9 +165,11 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
else if(!strcmp(buf, "none" )) d= 0; else if(!strcmp(buf, "none" )) d= 0;
else if(!strcmp(buf, "all" )) d= ~0; else if(!strcmp(buf, "all" )) d= ~0;
else { else {
if (error) d = ff_parse_and_eval_expr(buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); if (isnan(d)){
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
return AVERROR(EINVAL); return AVERROR(EINVAL);
}
} }
} }
if(o->type == FF_OPT_TYPE_FLAGS){ if(o->type == FF_OPT_TYPE_FLAGS){
......
...@@ -67,7 +67,6 @@ int ff_rate_control_init(MpegEncContext *s) ...@@ -67,7 +67,6 @@ int ff_rate_control_init(MpegEncContext *s)
{ {
RateControlContext *rcc= &s->rc_context; RateControlContext *rcc= &s->rc_context;
int i; int i;
const char *error = NULL;
static const char * const const_names[]={ static const char * const const_names[]={
"PI", "PI",
"E", "E",
...@@ -107,9 +106,9 @@ int ff_rate_control_init(MpegEncContext *s) ...@@ -107,9 +106,9 @@ int ff_rate_control_init(MpegEncContext *s)
}; };
emms_c(); 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) { 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; return -1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment