Mercurial > libavutil.hg
comparison opt.c @ 1028:5dbb12a37c3d libavutil tip
Move av_set_options_string() from libavfilter to libavutil.
author | stefano |
---|---|
date | Mon, 27 Sep 2010 22:09:53 +0000 |
parents | 580d47a2f015 |
children |
comparison
equal
deleted
inserted
replaced
1027:7d79d41d152e | 1028:5dbb12a37c3d |
---|---|
24 * AVOptions | 24 * AVOptions |
25 * @author Michael Niedermayer <michaelni@gmx.at> | 25 * @author Michael Niedermayer <michaelni@gmx.at> |
26 */ | 26 */ |
27 | 27 |
28 #include "avutil.h" | 28 #include "avutil.h" |
29 #include "avstring.h" | |
29 #include "opt.h" | 30 #include "opt.h" |
30 #include "eval.h" | 31 #include "eval.h" |
31 | 32 |
32 //FIXME order them and do a bin search | 33 //FIXME order them and do a bin search |
33 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) | 34 const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) |
450 void av_opt_set_defaults(void *s) | 451 void av_opt_set_defaults(void *s) |
451 { | 452 { |
452 av_opt_set_defaults2(s, 0, 0); | 453 av_opt_set_defaults2(s, 0, 0); |
453 } | 454 } |
454 | 455 |
456 /** | |
457 * Store the value in the field in ctx that is named like key. | |
458 * ctx must be an AVClass context, storing is done using AVOptions. | |
459 * | |
460 * @param buf the string to parse, buf will be updated to point at the | |
461 * separator just after the parsed key/value pair | |
462 * @param key_val_sep a 0-terminated list of characters used to | |
463 * separate key from value | |
464 * @param pairs_sep a 0-terminated list of characters used to separate | |
465 * two pairs from each other | |
466 * @return 0 if the key/value pair has been successfully parsed and | |
467 * set, or a negative value corresponding to an AVERROR code in case | |
468 * of error: | |
469 * AVERROR(EINVAL) if the key/value pair cannot be parsed, | |
470 * the error code issued by av_set_string3() if the key/value pair | |
471 * cannot be set | |
472 */ | |
473 static int parse_key_value_pair(void *ctx, const char **buf, | |
474 const char *key_val_sep, const char *pairs_sep) | |
475 { | |
476 char *key = av_get_token(buf, key_val_sep); | |
477 char *val; | |
478 int ret; | |
479 | |
480 if (*key && strspn(*buf, key_val_sep)) { | |
481 (*buf)++; | |
482 val = av_get_token(buf, pairs_sep); | |
483 } else { | |
484 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); | |
485 av_free(key); | |
486 return AVERROR(EINVAL); | |
487 } | |
488 | |
489 av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key); | |
490 | |
491 ret = av_set_string3(ctx, key, val, 1, NULL); | |
492 if (ret == AVERROR(ENOENT)) | |
493 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); | |
494 | |
495 av_free(key); | |
496 av_free(val); | |
497 return ret; | |
498 } | |
499 | |
500 int av_set_options_string(void *ctx, const char *opts, | |
501 const char *key_val_sep, const char *pairs_sep) | |
502 { | |
503 int ret, count = 0; | |
504 | |
505 while (*opts) { | |
506 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) | |
507 return ret; | |
508 count++; | |
509 | |
510 if (*opts) | |
511 opts++; | |
512 } | |
513 | |
514 return count; | |
515 } | |
516 | |
517 #ifdef TEST | |
518 | |
519 #undef printf | |
520 | |
521 typedef struct TestContext | |
522 { | |
523 const AVClass *class; | |
524 int num; | |
525 int toggle; | |
526 char *string; | |
527 int flags; | |
528 AVRational rational; | |
529 } TestContext; | |
530 | |
531 #define OFFSET(x) offsetof(TestContext, x) | |
532 | |
533 #define TEST_FLAG_COOL 01 | |
534 #define TEST_FLAG_LAME 02 | |
535 #define TEST_FLAG_MU 04 | |
536 | |
537 static const AVOption test_options[]= { | |
538 {"num", "set num", OFFSET(num), FF_OPT_TYPE_INT, 0, 0, 100 }, | |
539 {"toggle", "set toggle", OFFSET(toggle), FF_OPT_TYPE_INT, 0, 0, 1 }, | |
540 {"rational", "set rational", OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0, 0, 10 }, | |
541 {"string", "set string", OFFSET(string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, | |
542 {"flags", "set flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, 0, 0, INT_MAX, 0, "flags" }, | |
543 {"cool", "set cool flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_COOL, INT_MIN, INT_MAX, 0, "flags" }, | |
544 {"lame", "set lame flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_LAME, INT_MIN, INT_MAX, 0, "flags" }, | |
545 {"mu", "set mu flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_MU, INT_MIN, INT_MAX, 0, "flags" }, | |
546 {NULL}, | |
547 }; | |
548 | |
549 static const char *test_get_name(void *ctx) | |
550 { | |
551 return "test"; | |
552 } | |
553 | |
554 static const AVClass test_class = { | |
555 "TestContext", | |
556 test_get_name, | |
557 test_options | |
558 }; | |
559 | |
560 int main(void) | |
561 { | |
562 int i; | |
563 | |
564 printf("\nTesting av_set_options_string()\n"); | |
565 { | |
566 TestContext test_ctx; | |
567 const char *options[] = { | |
568 "", | |
569 ":", | |
570 "=", | |
571 "foo=:", | |
572 ":=foo", | |
573 "=foo", | |
574 "foo=", | |
575 "foo", | |
576 "foo=val", | |
577 "foo==val", | |
578 "toggle=:", | |
579 "string=:", | |
580 "toggle=1 : foo", | |
581 "toggle=100", | |
582 "toggle==1", | |
583 "flags=+mu-lame : num=42: toggle=0", | |
584 "num=42 : string=blahblah", | |
585 "rational=0 : rational=1/2 : rational=1/-1", | |
586 "rational=-1/0", | |
587 }; | |
588 | |
589 test_ctx.class = &test_class; | |
590 av_opt_set_defaults2(&test_ctx, 0, 0); | |
591 test_ctx.string = av_strdup("default"); | |
592 | |
593 av_log_set_level(AV_LOG_DEBUG); | |
594 | |
595 for (i=0; i < FF_ARRAY_ELEMS(options); i++) { | |
596 av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); | |
597 if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) | |
598 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); | |
599 printf("\n"); | |
600 } | |
601 } | |
602 | |
603 return 0; | |
604 } | |
605 | |
606 #endif |