diff options
author | Anton Khirnov <anton@khirnov.net> | 2011-10-03 19:49:12 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2011-10-12 16:51:16 +0200 |
commit | 641c7afe3c17334b81e3e2eef88f1751eb68f89f (patch) | |
tree | 27ff55b88d052b7947b40a40834f80f0c2c99083 /libavutil/opt.c | |
parent | 1bca8f4bc596d286dc50e572f5f8d52e4fc3a8dc (diff) | |
download | ffmpeg-641c7afe3c17334b81e3e2eef88f1751eb68f89f.tar.gz |
AVOptions: add new API for enumerating children.
This will allow the caller to enumerate child contexts in a generic way
and since the API is recursive, it also allows for deeper nesting (e.g.
AVFormatContext->AVIOContext->URLContext)
This will also allow the new setting/reading API to transparently apply
to children contexts.
Diffstat (limited to 'libavutil/opt.c')
-rw-r--r-- | libavutil/opt.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index 78fdf63a32..b732703c6d 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -583,22 +583,60 @@ int av_opt_set_dict(void *obj, AVDictionary **options) const AVOption *av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags) { - AVClass *c = *(AVClass**)obj; + return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); +} + +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj) +{ + const AVClass *c = *(AVClass**)obj; const AVOption *o = NULL; - if (c->opt_find && search_flags & AV_OPT_SEARCH_CHILDREN && - (o = c->opt_find(obj, name, unit, opt_flags, search_flags))) - return o; + if (search_flags & AV_OPT_SEARCH_CHILDREN) { + if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { + const AVClass *child = NULL; + while (child = av_opt_child_class_next(c, child)) + if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) + return o; + } else { + void *child = NULL; + while (child = av_opt_child_next(obj, child)) + if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) + return o; + } + } while (o = av_next_option(obj, o)) { if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && ((!unit && o->type != FF_OPT_TYPE_CONST) || - (unit && o->unit && !strcmp(o->unit, unit)))) + (unit && o->unit && !strcmp(o->unit, unit)))) { + if (target_obj) { + if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) + *target_obj = obj; + else + *target_obj = NULL; + } return o; + } } return NULL; } +void *av_opt_child_next(void *obj, void *prev) +{ + const AVClass *c = *(AVClass**)obj; + if (c->child_next) + return c->child_next(obj, prev); + return NULL; +} + +const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) +{ + if (parent->child_class_next) + return parent->child_class_next(prev); + return NULL; +} + #ifdef TEST #undef printf |