Revision 9ace13b4

View differences:

libavcodec/avcodec.h
31 31

  
32 32
#define LIBAVCODEC_VERSION_MAJOR 52
33 33
#define LIBAVCODEC_VERSION_MINOR 72
34
#define LIBAVCODEC_VERSION_MICRO  0
34
#define LIBAVCODEC_VERSION_MICRO  1
35 35

  
36 36
#define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
37 37
                                               LIBAVCODEC_VERSION_MINOR, \
libavcodec/eval.c
167 167
    return NAN;
168 168
}
169 169

  
170
static AVExpr * parse_expr(Parser *p);
170
static int parse_expr(AVExpr **e, Parser *p);
171 171

  
172 172
void ff_free_expr(AVExpr * e) {
173 173
    if (!e) return;
......
176 176
    av_freep(&e);
177 177
}
178 178

  
179
static AVExpr * parse_primary(Parser *p) {
179
static int parse_primary(AVExpr **e, Parser *p)
180
{
180 181
    AVExpr * d = av_mallocz(sizeof(AVExpr));
181 182
    char *next= p->s;
182
    int i;
183
    int ret, i;
183 184

  
184 185
    if (!d)
185
        return NULL;
186
        return AVERROR(ENOMEM);
186 187

  
187 188
    /* number */
188 189
    d->value = av_strtod(p->s, &next);
189 190
    if(next != p->s){
190 191
        d->type = e_value;
191 192
        p->s= next;
192
        return d;
193
        *e = d;
194
        return 0;
193 195
    }
194 196
    d->value = 1;
195 197

  
......
199 201
            p->s+= strlen(p->const_name[i]);
200 202
            d->type = e_const;
201 203
            d->a.const_index = i;
202
            return d;
204
            *e = d;
205
            return 0;
203 206
        }
204 207
    }
205 208

  
......
208 211
        av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n");
209 212
        p->s= next;
210 213
        ff_free_expr(d);
211
        return NULL;
214
        return AVERROR(EINVAL);
212 215
    }
213 216
    p->s++; // "("
214 217
    if (*next == '(') { // special case do-nothing
215 218
        av_freep(&d);
216
        d = parse_expr(p);
219
        if ((ret = parse_expr(&d, p)) < 0)
220
            return ret;
217 221
        if(p->s[0] != ')'){
218 222
            av_log(p, AV_LOG_ERROR, "missing )\n");
219 223
            ff_free_expr(d);
220
            return NULL;
224
            return AVERROR(EINVAL);
221 225
        }
222 226
        p->s++; // ")"
223
        return d;
227
        *e = d;
228
        return 0;
229
    }
230
    if ((ret = parse_expr(&(d->param[0]), p)) < 0) {
231
        ff_free_expr(d);
232
        return ret;
224 233
    }
225
    d->param[0] = parse_expr(p);
226 234
    if(p->s[0]== ','){
227 235
        p->s++; // ","
228
        d->param[1] = parse_expr(p);
236
        parse_expr(&d->param[1], p);
229 237
    }
230 238
    if(p->s[0] != ')'){
231 239
        av_log(p, AV_LOG_ERROR, "missing )\n");
232 240
        ff_free_expr(d);
233
        return NULL;
241
        return AVERROR(EINVAL);
234 242
    }
235 243
    p->s++; // ")"
236 244

  
......
265 273
            if(strmatch(next, p->func1_name[i])){
266 274
                d->a.func1 = p->func1[i];
267 275
                d->type = e_func1;
268
                return d;
276
                *e = d;
277
                return 0;
269 278
            }
270 279
        }
271 280

  
......
273 282
            if(strmatch(next, p->func2_name[i])){
274 283
                d->a.func2 = p->func2[i];
275 284
                d->type = e_func2;
276
                return d;
285
                *e = d;
286
                return 0;
277 287
            }
278 288
        }
279 289

  
280 290
        av_log(p, AV_LOG_ERROR, "unknown function\n");
281 291
        ff_free_expr(d);
282
        return NULL;
292
        return AVERROR(EINVAL);
283 293
    }
284 294

  
285
    return d;
295
    *e = d;
296
    return 0;
286 297
}
287 298

  
288 299
static AVExpr * new_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1){
......
296 307
    return e;
297 308
}
298 309

  
299
static AVExpr * parse_pow(Parser *p, int *sign){
310
static int parse_pow(AVExpr **e, Parser *p, int *sign)
311
{
300 312
    *sign= (*p->s == '+') - (*p->s == '-');
301 313
    p->s += *sign&1;
302
    return parse_primary(p);
314
    return parse_primary(e, p);
303 315
}
304 316

  
305
static AVExpr * parse_factor(Parser *p){
306
    int sign, sign2;
307
    AVExpr * e = parse_pow(p, &sign);
317
static int parse_factor(AVExpr **e, Parser *p)
318
{
319
    int sign, sign2, ret;
320
    AVExpr *e0, *e1, *e2;
321
    if ((ret = parse_pow(&e0, p, &sign)) < 0)
322
        return ret;
308 323
    while(p->s[0]=='^'){
324
        e1 = e0;
309 325
        p->s++;
310
        e= new_eval_expr(e_pow, 1, e, parse_pow(p, &sign2));
311
        if (!e)
312
            return NULL;
313
        if (e->param[1]) e->param[1]->value *= (sign2|1);
326
        if ((ret = parse_pow(&e2, p, &sign2)) < 0) {
327
            ff_free_expr(e1);
328
            return ret;
329
        }
330
        e0 = new_eval_expr(e_pow, 1, e1, e2);
331
        if (!e0) {
332
            ff_free_expr(e1);
333
            ff_free_expr(e2);
334
            return AVERROR(ENOMEM);
335
        }
336
        if (e0->param[1]) e0->param[1]->value *= (sign2|1);
314 337
    }
315
    if (e) e->value *= (sign|1);
316
    return e;
338
    if (e0) e0->value *= (sign|1);
339

  
340
    *e = e0;
341
    return 0;
317 342
}
318 343

  
319
static AVExpr * parse_term(Parser *p){
320
    AVExpr * e = parse_factor(p);
344
static int parse_term(AVExpr **e, Parser *p)
345
{
346
    int ret;
347
    AVExpr *e0, *e1, *e2;
348
    if ((ret = parse_factor(&e0, p)) < 0)
349
        return ret;
321 350
    while(p->s[0]=='*' || p->s[0]=='/'){
322 351
        int c= *p->s++;
323
        e= new_eval_expr(c == '*' ? e_mul : e_div, 1, e, parse_factor(p));
324
        if (!e)
325
            return NULL;
352
        e1 = e0;
353
        if ((ret = parse_factor(&e2, p)) < 0) {
354
            ff_free_expr(e1);
355
            return ret;
356
        }
357
        e0 = new_eval_expr(c == '*' ? e_mul : e_div, 1, e1, e2);
358
        if (!e0) {
359
            ff_free_expr(e1);
360
            ff_free_expr(e2);
361
            return AVERROR(ENOMEM);
362
        }
326 363
    }
327
    return e;
364
    *e = e0;
365
    return 0;
328 366
}
329 367

  
330
static AVExpr * parse_subexpr(Parser *p) {
331
    AVExpr * e = parse_term(p);
368
static int parse_subexpr(AVExpr **e, Parser *p)
369
{
370
    int ret;
371
    AVExpr *e0, *e1, *e2;
372
    if ((ret = parse_term(&e0, p)) < 0)
373
        return ret;
332 374
    while(*p->s == '+' || *p->s == '-') {
333
        e= new_eval_expr(e_add, 1, e, parse_term(p));
334
        if (!e)
335
            return NULL;
375
        e1 = e0;
376
        if ((ret = parse_term(&e2, p)) < 0) {
377
            ff_free_expr(e1);
378
            return ret;
379
        }
380
        e0 = new_eval_expr(e_add, 1, e1, e2);
381
        if (!e0) {
382
            ff_free_expr(e1);
383
            ff_free_expr(e2);
384
            return AVERROR(ENOMEM);
385
        }
336 386
    };
337 387

  
338
    return e;
388
    *e = e0;
389
    return 0;
339 390
}
340 391

  
341
static AVExpr * parse_expr(Parser *p) {
342
    AVExpr * e;
343

  
392
static int parse_expr(AVExpr **e, Parser *p)
393
{
394
    int ret;
395
    AVExpr *e0, *e1, *e2;
344 396
    if(p->stack_index <= 0) //protect against stack overflows
345
        return NULL;
397
        return AVERROR(EINVAL);
346 398
    p->stack_index--;
347 399

  
348
    e = parse_subexpr(p);
349

  
400
    if ((ret = parse_subexpr(&e0, p)) < 0)
401
        return ret;
350 402
    while(*p->s == ';') {
403
        e1 = e0;
404
        if ((ret = parse_subexpr(&e2, p)) < 0) {
405
            ff_free_expr(e1);
406
            return ret;
407
        }
351 408
        p->s++;
352
        e= new_eval_expr(e_last, 1, e, parse_subexpr(p));
353
        if (!e)
354
            return NULL;
409
        e0 = new_eval_expr(e_last, 1, e1, e2);
410
        if (!e0) {
411
            ff_free_expr(e1);
412
            ff_free_expr(e2);
413
            return AVERROR(ENOMEM);
414
        }
355 415
    };
356 416

  
357 417
    p->stack_index++;
358

  
359
    return e;
418
    *e = e0;
419
    return 0;
360 420
}
361 421

  
362 422
static int verify_expr(AVExpr * e) {
......
373 433
    }
374 434
}
375 435

  
376
AVExpr *ff_parse_expr(const char *s,
436
int ff_parse_expr(AVExpr **expr, const char *s,
377 437
                      const char * const *const_name,
378 438
                      const char * const *func1_name, double (* const *func1)(void *, double),
379 439
                      const char * const *func2_name, double (* const *func2)(void *, double, double),
......
383 443
    AVExpr *e = NULL;
384 444
    char *w = av_malloc(strlen(s) + 1);
385 445
    char *wp = w;
446
    int ret = 0;
386 447

  
387 448
    if (!w)
388
        goto end;
449
        return AVERROR(ENOMEM);
389 450

  
390 451
    while (*s)
391 452
        if (!isspace(*s++)) *wp++ = s[-1];
......
402 463
    p.log_offset = log_offset;
403 464
    p.log_ctx    = log_ctx;
404 465

  
405
    e = parse_expr(&p);
466
    if ((ret = parse_expr(&e, &p)) < 0)
467
        goto end;
406 468
    if (!verify_expr(e)) {
407 469
        ff_free_expr(e);
408
        e = NULL;
470
        ret = AVERROR(EINVAL);
471
        goto end;
409 472
    }
473
    *expr = e;
410 474
end:
411 475
    av_free(w);
412
    return e;
476
    return ret;
413 477
}
414 478

  
415 479
double ff_eval_expr(AVExpr * e, const double *const_value, void *opaque) {
......
420 484
    return eval_expr(&p, e);
421 485
}
422 486

  
423
double ff_parse_and_eval_expr(const char *s,
487
int ff_parse_and_eval_expr(double *d, const char *s,
424 488
                              const char * const *const_name, const double *const_value,
425 489
                              const char * const *func1_name, double (* const *func1)(void *, double),
426 490
                              const char * const *func2_name, double (* const *func2)(void *, double, double),
427 491
                              void *opaque, int log_offset, void *log_ctx)
428 492
{
429
    AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, log_offset, log_ctx);
430
    double d;
431
    if (!e) return NAN;
432
    d = ff_eval_expr(e, const_value, opaque);
493
    AVExpr *e = NULL;
494
    int ret = ff_parse_expr(&e, s, const_name, func1_name, func1, func2_name, func2, log_offset, log_ctx);
495

  
496
    if (ret < 0) {
497
        *d = NAN;
498
        return ret;
499
    }
500
    *d = ff_eval_expr(e, const_value, opaque);
433 501
    ff_free_expr(e);
434
    return d;
502
    return isnan(*d) ? AVERROR(EINVAL) : 0;
435 503
}
436 504

  
437 505
#ifdef TEST
......
448 516
};
449 517
int main(void){
450 518
    int i;
451
    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));
452
    printf("%f == 0.931322575\n", ff_parse_and_eval_expr("80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL));
519
    double d;
520
    ff_parse_and_eval_expr(&d, "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);
521
    printf("%f == 12.7\n", d);
522
    ff_parse_and_eval_expr(&d, "80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL);
523
    printf("%f == 0.931322575\n", d);
453 524

  
454 525
    for(i=0; i<1050; i++){
455 526
        START_TIMER
456
            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);
527
            ff_parse_and_eval_expr(&d, "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);
457 528
        STOP_TIMER("ff_parse_and_eval_expr")
458 529
    }
459 530
    return 0;
libavcodec/eval.h
32 32
 * Parses and evaluates an expression.
33 33
 * Note, this is significantly slower than ff_eval_expr().
34 34
 *
35
 * @param res a pointer to a double where is put the result value of
36
 * the expression, or NAN in case of error
35 37
 * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)"
36 38
 * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0}
37 39
 * @param const_value a zero terminated array of values for the identifers from const_name
......
41 43
 * @param func2 NULL terminated array of function pointers for functions which take 2 arguments
42 44
 * @param opaque a pointer which will be passed to all functions from func1 and func2
43 45
 * @param log_ctx parent logging context
44
 * @return the value of the expression
46
 * @return 0 in case of success, a negative value corresponding to an
47
 * AVERROR code otherwise
45 48
 */
46
double ff_parse_and_eval_expr(const char *s,
49
int ff_parse_and_eval_expr(double *res, const char *s,
47 50
                              const char * const *const_name, const double *const_value,
48 51
                              const char * const *func1_name, double (* const *func1)(void *, double),
49 52
                              const char * const *func2_name, double (* const *func2)(void *, double, double),
......
52 55
/**
53 56
 * Parses an expression.
54 57
 *
58
 * @param expr a pointer where is put an AVExpr containing the parsed
59
 * value in case of successfull parsing, or NULL otherwise.
60
 * The pointed to AVExpr must be freed with ff_free_expr() by the user
61
 * when it is not needed anymore.
55 62
 * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)"
56 63
 * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0}
57 64
 * @param func1_name NULL terminated array of zero terminated strings of func1 identifers
......
59 66
 * @param func2_name NULL terminated array of zero terminated strings of func2 identifers
60 67
 * @param func2 NULL terminated array of function pointers for functions which take 2 arguments
61 68
 * @param log_ctx parent logging context
62
 * @return AVExpr which must be freed with ff_free_expr() by the user when it is not needed anymore
63
 *         NULL if anything went wrong
69
 * @return 0 in case of success, a negative value corresponding to an
70
 * AVERROR code otherwise
64 71
 */
65
AVExpr *ff_parse_expr(const char *s,
72
int ff_parse_expr(AVExpr **expr, const char *s,
66 73
                      const char * const *const_name,
67 74
                      const char * const *func1_name, double (* const *func1)(void *, double),
68 75
                      const char * const *func2_name, double (* const *func2)(void *, double, double),
libavcodec/opt.c
165 165
                else if(!strcmp(buf, "none"   )) d= 0;
166 166
                else if(!strcmp(buf, "all"    )) d= ~0;
167 167
                else {
168
                    d = ff_parse_and_eval_expr(buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
169
                    if (isnan(d)){
168
                    int res = ff_parse_and_eval_expr(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
169
                    if (res < 0) {
170 170
                        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
171
                    return AVERROR(EINVAL);
171
                        return res;
172 172
                    }
173 173
                }
174 174
            }
libavcodec/ratecontrol.c
66 66
int ff_rate_control_init(MpegEncContext *s)
67 67
{
68 68
    RateControlContext *rcc= &s->rc_context;
69
    int i;
69
    int i, res;
70 70
    static const char * const const_names[]={
71 71
        "PI",
72 72
        "E",
......
106 106
    };
107 107
    emms_c();
108 108

  
109
    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);
110
    if (!rcc->rc_eq_eval) {
109
    res = ff_parse_expr(&rcc->rc_eq_eval, s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx);
110
    if (res < 0) {
111 111
        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
112
        return -1;
112
        return res;
113 113
    }
114 114

  
115 115
    for(i=0; i<5; i++){

Also available in: Unified diff