diff --git a/doc/APIchanges b/doc/APIchanges index 79b684501e..c5a1000346 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-xx-xx - xxxxxxx - lavu 54.02.0 - opt.h + Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support + dictionary types being set as options. + 2014-xx-xx - xxxxxxx - lavf 56.01.0 - avformat.h Add AVFormatContext.event_flags and AVStream.event_flags for signaling to the user when events happen in the file/stream. diff --git a/libavutil/opt.c b/libavutil/opt.c index 2a06eb6f39..fec840bf71 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -680,6 +680,24 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c } #endif +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; @@ -927,6 +945,23 @@ int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int 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); @@ -1220,7 +1255,8 @@ void av_opt_set_defaults2(void *s, int mask, int flags) write_number(s, opt, dst, 1, 1, opt->default_val.i64); 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); @@ -1414,9 +1450,21 @@ int av_opt_set_from_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_dict2(void *obj, AVDictionary **options, int search_flags) diff --git a/libavutil/opt.h b/libavutil/opt.h index 7705990210..4905ee30c0 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -226,6 +226,7 @@ enum AVOptionType{ 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_DICT, AV_OPT_TYPE_CONST = 128, AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'), @@ -511,7 +512,7 @@ int av_opt_set_from_string(void *ctx, const char *opts, const char *const *shorthand, 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); @@ -735,16 +736,21 @@ 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_image_size(void *obj, const char *name, int w, int h, int search_flags); int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); +/** + * @note Any old dictionary present is discarded and replaced with a copy of the new one. The + * caller still owns val is and responsible for freeing it. + */ +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); /** * Set a binary option to an integer list. @@ -761,6 +767,7 @@ int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, in AVERROR(EINVAL) : \ av_opt_set_bin(obj, name, (const uint8_t *)(val), \ av_int_list_length(val, term) * sizeof(*(val)), flags)) + /** * @} */ @@ -780,15 +787,20 @@ int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, in /** * @note the returned string will be 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_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out); int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); +/** + * @param[out] out_val The returned dictionary is a copy of the actual value and must + * be freed with av_dict_free() by the caller + */ +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val); /** * @} */ diff --git a/libavutil/version.h b/libavutil/version.h index 23b331de24..43114c7899 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 54 -#define LIBAVUTIL_VERSION_MINOR 1 +#define LIBAVUTIL_VERSION_MINOR 2 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \