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