aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/opt.c
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2019-12-24 00:19:47 +0100
committerMarton Balint <cus@passwd.hu>2019-12-27 21:52:21 +0100
commit5edacc46099725f59ac81bdbff991b0daf4b3a7c (patch)
tree03c75d042e9737a581a94d213f8637db27dfa8c4 /libavutil/opt.c
parent6c883e214a1120938bb61caccb40e6ef62078add (diff)
downloadffmpeg-5edacc46099725f59ac81bdbff991b0daf4b3a7c.tar.gz
avutil/opt: add full support for AV_OPT_TYPE_DICT
Now it is possible to set them from a string, to serialize them and to use a default value. Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavutil/opt.c')
-rw-r--r--libavutil/opt.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 9081a593a1..60161d4a80 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -446,6 +446,22 @@ static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val,
AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
}
+static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
+{
+ AVDictionary *options = NULL;
+
+ if (val) {
+ int ret = av_dict_parse_string(&options, val, "=", ":", 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ av_dict_free((AVDictionary **)dst);
+ *dst = (uint8_t *)options;
+
+ return 0;
+}
+
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
int ret = 0;
@@ -527,6 +543,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
return ret;
}
break;
+ case AV_OPT_TYPE_DICT:
+ return set_string_dict(obj, o, val, dst);
}
av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@@ -855,6 +873,12 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
i64 = *(int64_t *)dst;
ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
break;
+ case AV_OPT_TYPE_DICT:
+ if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
+ *out_val = NULL;
+ return 0;
+ }
+ return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
default:
return AVERROR(EINVAL);
}
@@ -1174,6 +1198,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_BINARY:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
break;
+ case AV_OPT_TYPE_DICT:
+ av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
+ break;
case AV_OPT_TYPE_IMAGE_SIZE:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
break;
@@ -1247,6 +1274,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
!((opt->type == AV_OPT_TYPE_COLOR ||
opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
opt->type == AV_OPT_TYPE_STRING ||
+ opt->type == AV_OPT_TYPE_DICT ||
opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
!opt->default_val.str)) {
av_log(av_log_obj, AV_LOG_INFO, " (default ");
@@ -1297,6 +1325,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_COLOR:
case AV_OPT_TYPE_IMAGE_SIZE:
case AV_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_DICT:
case AV_OPT_TYPE_VIDEO_RATE:
av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
break;
@@ -1386,8 +1415,8 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
set_string_binary(s, opt, opt->default_val.str, dst);
break;
case AV_OPT_TYPE_DICT:
- /* Cannot set defaults for these types */
- break;
+ set_string_dict(s, opt, opt->default_val.str, dst);
+ break;
default:
av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
opt->type, opt->name);
@@ -1971,9 +2000,21 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
av_free(tmp.data);
return ret;
}
- case AV_OPT_TYPE_DICT:
- /* Binary and dict have not default support yet. Any pointer is not default. */
- return !!(*(void **)dst);
+ case AV_OPT_TYPE_DICT: {
+ AVDictionary *dict1 = NULL;
+ AVDictionary *dict2 = *(AVDictionary **)dst;
+ AVDictionaryEntry *en1 = NULL;
+ AVDictionaryEntry *en2 = NULL;
+ ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0);
+ if (ret < 0)
+ return ret;
+ do {
+ en1 = av_dict_get(dict1, "", en1, AV_DICT_IGNORE_SUFFIX);
+ en2 = av_dict_get(dict2, "", en2, AV_DICT_IGNORE_SUFFIX);
+ } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value));
+ av_dict_free(&dict1);
+ return (!en1 && !en2);
+ }
case AV_OPT_TYPE_IMAGE_SIZE:
if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
w = h = 0;