mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Change eval API to take parent log context and log level offset.
this is based on stefanos work, especially all bugs are his fault ;) Originally committed as revision 23201 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
4880cfd952
commit
2b65bb45b5
@ -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{
|
|||||||
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) {
|
|||||||
|
|
||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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[]={
|
|||||||
};
|
};
|
||||||
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;
|
|||||||
* @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,
|
|||||||
* @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,
|
|||||||
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
|
|||||||
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
|
|||||||
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,11 +165,13 @@ 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){
|
||||||
if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
|
if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
|
||||||
else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
|
else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
|
||||||
|
@ -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)
|
|||||||
};
|
};
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user