diff options
author | James Almer <jamrial@gmail.com> | 2024-04-12 19:10:25 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2024-04-23 23:54:46 -0300 |
commit | 8616cfe0890e49437d2b373f97a9c791eb1b7c4c (patch) | |
tree | 1ae274c18177a035880b37baaf8c26ed20100298 /libavutil/opt.c | |
parent | 855d4b52547b2f8fc38b400e5d18cf44e621e163 (diff) | |
download | ffmpeg-8616cfe0890e49437d2b373f97a9c791eb1b7c4c.tar.gz |
avutil/opt: add support for children objects in av_opt_serialize
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavutil/opt.c')
-rw-r--r-- | libavutil/opt.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index d11e9d2ac5..ecbf7efe5f 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -2386,26 +2386,22 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla return av_opt_is_set_to_default(target, o); } -int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, - const char key_val_sep, const char pairs_sep) +static int opt_serialize(void *obj, int opt_flags, int flags, int *cnt, + AVBPrint *bprint, const char key_val_sep, const char pairs_sep) { const AVOption *o = NULL; + void *child = NULL; uint8_t *buf; - AVBPrint bprint; - int ret, cnt = 0; + int ret; const char special_chars[] = {pairs_sep, key_val_sep, '\0'}; - if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || - pairs_sep == '\\' || key_val_sep == '\\') { - av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); - return AVERROR(EINVAL); - } - - if (!obj || !buffer) - return AVERROR(EINVAL); - - *buffer = NULL; - av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + if (flags & AV_OPT_SERIALIZE_SEARCH_CHILDREN) + while (child = av_opt_child_next(obj, child)) { + ret = opt_serialize(child, opt_flags, flags, cnt, bprint, + key_val_sep, pairs_sep); + if (ret < 0) + return ret; + } while (o = av_opt_next(obj, o)) { if (o->type == AV_OPT_TYPE_CONST) @@ -2417,18 +2413,45 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) continue; if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { - av_bprint_finalize(&bprint, NULL); + av_bprint_finalize(bprint, NULL); return ret; } if (buf) { - if (cnt++) - av_bprint_append_data(&bprint, &pairs_sep, 1); - av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); - av_bprint_append_data(&bprint, &key_val_sep, 1); - av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + if ((*cnt)++) + av_bprint_append_data(bprint, &pairs_sep, 1); + av_bprint_escape(bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_bprint_append_data(bprint, &key_val_sep, 1); + av_bprint_escape(bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); av_freep(&buf); } } + + return 0; +} + +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep) +{ + AVBPrint bprint; + int ret, cnt = 0; + + if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || + pairs_sep == '\\' || key_val_sep == '\\') { + av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); + return AVERROR(EINVAL); + } + + if (!obj || !buffer) + return AVERROR(EINVAL); + + *buffer = NULL; + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + + ret = opt_serialize(obj, opt_flags, flags, &cnt, &bprint, + key_val_sep, pairs_sep); + if (ret < 0) + return ret; + ret = av_bprint_finalize(&bprint, buffer); if (ret < 0) return ret; |