+ parse_arg_function(optctx, opt);
+ }
+ }
+}
+
+int parse_optgroup(void *optctx, OptionGroup *g)
+{
+ int i, ret;
+
+ av_log(NULL, AV_LOG_DEBUG, "Parsing a group of options: %s %s.\n",
+ g->group_def->name, g->arg);
+
+ for (i = 0; i < g->nb_opts; i++) {
+ Option *o = &g->opts[i];
+
+ if (g->group_def->flags &&
+ !(g->group_def->flags & o->opt->flags)) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s (%s) cannot be applied to "
+ "%s %s -- you are trying to apply an input option to an "
+ "output file or vice versa. Move this option before the "
+ "file it belongs to.\n", o->key, o->opt->help,
+ g->group_def->name, g->arg);
+ return AVERROR(EINVAL);
+ }
+
+ av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
+ o->key, o->opt->help, o->val);
+
+ ret = write_option(optctx, o->opt, o->key, o->val);
+ if (ret < 0)
+ return ret;
+ }
+
+ av_log(NULL, AV_LOG_DEBUG, "Successfully parsed a group of options.\n");
+
+ return 0;
+}
+
+int locate_option(int argc, char **argv, const OptionDef *options,
+ const char *optname)
+{
+ const OptionDef *po;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ const char *cur_opt = argv[i];
+
+ if (*cur_opt++ != '-')
+ continue;
+
+ po = find_option(options, cur_opt);
+ if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
+ po = find_option(options, cur_opt + 2);
+
+ if ((!po->name && !strcmp(cur_opt, optname)) ||
+ (po->name && !strcmp(optname, po->name)))
+ return i;
+
+ if (!po || po->flags & HAS_ARG)
+ i++;
+ }
+ return 0;
+}
+
+void parse_loglevel(int argc, char **argv, const OptionDef *options)
+{
+ int idx = locate_option(argc, argv, options, "loglevel");
+ if (!idx)
+ idx = locate_option(argc, argv, options, "v");
+ if (idx && argv[idx + 1])
+ opt_loglevel(NULL, "loglevel", argv[idx + 1]);
+}
+
+#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
+int opt_default(void *optctx, const char *opt, const char *arg)
+{
+ const AVOption *o;
+ char opt_stripped[128];
+ const char *p;
+ const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
+#if CONFIG_AVRESAMPLE
+ const AVClass *rc = avresample_get_class();
+#endif
+#if CONFIG_SWSCALE
+ const AVClass *sc = sws_get_class();
+#endif
+
+ if (!(p = strchr(opt, ':')))
+ p = opt + strlen(opt);
+ av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
+
+ if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
+ ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
+ (o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
+ av_dict_set(&codec_opts, opt, arg, FLAGS);
+ else if ((o = av_opt_find(&fc, opt, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
+ av_dict_set(&format_opts, opt, arg, FLAGS);
+#if CONFIG_AVRESAMPLE
+ else if ((o = av_opt_find(&rc, opt, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
+ av_dict_set(&resample_opts, opt, arg, FLAGS);
+#endif
+#if CONFIG_SWSCALE
+ else if ((o = av_opt_find(&sc, opt, NULL, 0,
+ AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
+ // XXX we only support sws_flags, not arbitrary sws options
+ int ret = av_opt_set(sws_opts, opt, arg, 0);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
+ return ret;