static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
{
- int ret;
- if (!val) {
- ret = AVERROR(EINVAL);
- } else {
- ret = av_parse_video_rate(dst, val);
- }
+ int ret = av_parse_video_rate(dst, val);
if (ret < 0)
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
return ret;
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) {
+ av_dict_free(&options);
+ 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;
return AVERROR_OPTION_NOT_FOUND;
if (!val && (o->type != AV_OPT_TYPE_STRING &&
o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
- o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
+ o->type != AV_OPT_TYPE_IMAGE_SIZE &&
o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
return AVERROR(EINVAL);
case AV_OPT_TYPE_SAMPLE_FMT:
return set_string_sample_fmt(obj, o, val, dst);
case AV_OPT_TYPE_DURATION:
- if (!val) {
- *(int64_t *)dst = 0;
+ {
+ int64_t usecs = 0;
+ if (val) {
+ if ((ret = av_parse_time(&usecs, val, 1)) < 0) {
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
+ return ret;
+ }
+ }
+ if (usecs < o->min || usecs > o->max) {
+ av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
+ usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0);
+ return AVERROR(ERANGE);
+ }
+ *(int64_t *)dst = usecs;
return 0;
- } else {
- if ((ret = av_parse_time(dst, val, 1)) < 0)
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
- return ret;
}
- break;
case AV_OPT_TYPE_COLOR:
return set_string_color(obj, o, val, dst);
case AV_OPT_TYPE_CHANNEL_LAYOUT:
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");
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);
}
return res & flag->default_val.i64;
}
+static void log_int_value(void *av_log_obj, int level, int64_t i)
+{
+ if (i == INT_MAX) {
+ av_log(av_log_obj, level, "INT_MAX");
+ } else if (i == INT_MIN) {
+ av_log(av_log_obj, level, "INT_MIN");
+ } else if (i == UINT32_MAX) {
+ av_log(av_log_obj, level, "UINT32_MAX");
+ } else if (i == INT64_MAX) {
+ av_log(av_log_obj, level, "I64_MAX");
+ } else if (i == INT64_MIN) {
+ av_log(av_log_obj, level, "I64_MIN");
+ } else {
+ av_log(av_log_obj, level, "%"PRId64, i);
+ }
+}
+
static void log_value(void *av_log_obj, int level, double d)
{
if (d == INT_MAX) {
}
static void opt_list(void *obj, void *av_log_obj, const char *unit,
- int req_flags, int rej_flags)
+ int req_flags, int rej_flags, enum AVOptionType parent_type)
{
const AVOption *opt = NULL;
AVOptionRanges *r;
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;
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
break;
case AV_OPT_TYPE_CONST:
+ if (parent_type == AV_OPT_TYPE_INT)
+ av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64);
+ else
+ av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
+ break;
default:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
break;
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.');
av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.');
+ av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.');
if (opt->help)
av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
!((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 ");
if (def_const)
av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
else
- log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
+ log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
break;
}
case AV_OPT_TYPE_DOUBLE:
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;
av_log(av_log_obj, AV_LOG_INFO, "\n");
if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
- opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
+ opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type);
}
}
av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name);
- opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
+ opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1);
return 0;
}
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);
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) {
+ av_dict_free(&dict1);
+ 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;