In order to support metadata being set as an option, it's necessary to be able to set dictionaries as values.
Relies on Diego Biurrun's change: https://lists.libav.org/pipermail/libav-devel/2014-June/060148.html --- libavutil/opt.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- libavutil/opt.h | 26 +++++++++++++++----------- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 9f9f1f2..ec6b300 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -307,6 +307,24 @@ int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int return 0; } +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags) +{ + void *target_obj; + AVDictionary **dst; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + dst = (AVDictionary**)(((uint8_t*)target_obj) + o->offset); + av_dict_free(dst); + av_dict_copy(dst, val, 0); + + return 0; +} + int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) { void *dst, *target_obj; @@ -410,6 +428,23 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_ return 0; } +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) +{ + void *target_obj; + AVDictionary *src; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_DICT) + return AVERROR(EINVAL); + + src = *(AVDictionary**)(((uint8_t*)target_obj) + o->offset); + av_dict_copy(out_val, src, 0); + + return 0; +} + int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); @@ -539,7 +574,8 @@ void av_opt_set_defaults(void *s) av_opt_set(s, opt->name, opt->default_val.str, 0); break; case AV_OPT_TYPE_BINARY: - /* Cannot set default for binary */ + case AV_OPT_TYPE_DICT: + /* Cannot set defaults for these types */ break; default: av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); @@ -621,9 +657,21 @@ int av_set_options_string(void *ctx, const char *opts, void av_opt_free(void *obj) { const AVOption *o = NULL; - while ((o = av_opt_next(obj, o))) - if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY) + while ((o = av_opt_next(obj, o))) { + switch (o->type) { + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_BINARY: av_freep((uint8_t *)obj + o->offset); + break; + + case AV_OPT_TYPE_DICT: + av_dict_free((AVDictionary**)(((uint8_t*)obj) + o->offset)); + break; + + default: + break; + } + } } int av_opt_set_dict(void *obj, AVDictionary **options) diff --git a/libavutil/opt.h b/libavutil/opt.h index b90feaa..3a712fe 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -223,7 +223,8 @@ enum AVOptionType{ AV_OPT_TYPE_FLOAT, AV_OPT_TYPE_STRING, AV_OPT_TYPE_RATIONAL, - AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length + AV_OPT_TYPE_BINARY, + AV_OPT_TYPE_DICT, ///< offset must point to a pointer immediately followed by an int for the length AV_OPT_TYPE_CONST = 128, }; @@ -253,6 +254,7 @@ typedef struct AVOption { int64_t i64; double dbl; const char *str; + AVDictionary *dict; /* TODO those are unused now */ AVRational q; } default_val; @@ -325,7 +327,7 @@ int av_set_options_string(void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep); /** - * Free all string and binary options in obj. + * Free all allocated objects in obj. */ void av_opt_free(void *obj); @@ -491,11 +493,12 @@ const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *pre * AVERROR(ERANGE) if the value is out of range * AVERROR(EINVAL) if the value is not valid */ -int av_opt_set (void *obj, const char *name, const char *val, int search_flags); -int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); -int av_opt_set_double(void *obj, const char *name, double val, int search_flags); -int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); -int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); +int av_opt_set (void *obj, const char *name, const char *val, int search_flags); +int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); +int av_opt_set_double (void *obj, const char *name, double val, int search_flags); +int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); /** * @} */ @@ -515,10 +518,11 @@ int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, /** * @note the returned string will av_malloc()ed and must be av_free()ed by the caller */ -int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); -int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); -int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val); -int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); +int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); +int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val); +int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val); /** * @} * @} -- 2.0.0.rc2 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
