summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/decode/ad_lavc.c13
-rw-r--r--audio/filter/af_lavfi.c12
-rw-r--r--audio/filter/af_lavrresample.c10
-rw-r--r--common/av_common.c36
-rw-r--r--common/av_common.h3
-rw-r--r--common/av_opts.c55
-rw-r--r--common/av_opts.h30
-rw-r--r--demux/demux_lavf.c19
-rw-r--r--old-makefile1
-rw-r--r--stream/stream_lavf.c6
-rw-r--r--video/decode/vd_lavc.c14
-rw-r--r--video/filter/vf_lavfi.c15
-rw-r--r--wscript_build.py1
13 files changed, 66 insertions, 149 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index 4ff69c3f20..c4372ba4b3 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -33,7 +33,6 @@
#include "common/codecs.h"
#include "common/msg.h"
#include "options/options.h"
-#include "common/av_opts.h"
#include "ad.h"
#include "audio/fmt-conversion.h"
@@ -55,7 +54,7 @@ struct ad_lavc_params {
float ac3drc;
int downmix;
int threads;
- char *avopt;
+ char **avopts;
};
const struct m_sub_options ad_lavc_conf = {
@@ -63,7 +62,7 @@ const struct m_sub_options ad_lavc_conf = {
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 2),
OPT_FLAG("downmix", downmix, 0),
OPT_INTRANGE("threads", threads, 0, 1, 16),
- OPT_STRING("o", avopt, 0),
+ OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
.size = sizeof(struct ad_lavc_params),
@@ -228,13 +227,7 @@ static int init(struct dec_audio *da, const char *decoder)
av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc,
AV_OPT_SEARCH_CHILDREN);
- if (opts->avopt) {
- if (parse_avopts(lavc_context, opts->avopt) < 0) {
- MP_ERR(da, "setting AVOptions '%s' failed.\n", opts->avopt);
- uninit(da);
- return 0;
- }
- }
+ mp_set_avopts(da->log, lavc_context, opts->avopts);
lavc_context->codec_tag = sh->format;
lavc_context->sample_rate = sh_audio->samplerate;
diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c
index a565e202f4..0b7a619e56 100644
--- a/audio/filter/af_lavfi.c
+++ b/audio/filter/af_lavfi.c
@@ -38,8 +38,9 @@
#include "audio/fmt-conversion.h"
#include "af.h"
+#include "common/av_common.h"
+
#include "options/m_option.h"
-#include "common/av_opts.h"
// FFmpeg and Libav have slightly different APIs, just enough to cause us
// unnecessary pain. <Expletive deleted.>
@@ -62,7 +63,7 @@ struct priv {
// options
char *cfg_graph;
- char *cfg_avopts;
+ char **cfg_avopts;
};
static void destroy_graph(struct af_instance *af)
@@ -90,11 +91,8 @@ static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
if (!graph)
goto error;
- if (parse_avopts(graph, p->cfg_avopts) < 0) {
- MP_FATAL(af, "lavfi: could not set opts: '%s'\n",
- p->cfg_avopts);
+ if (mp_set_avopts(af->log, graph, p->cfg_avopts) < 0)
goto error;
- }
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
@@ -306,7 +304,7 @@ const struct af_info af_info_lavfi = {
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
OPT_STRING("graph", cfg_graph, 0),
- OPT_STRING("o", cfg_avopts, 0),
+ OPT_KEYVALUELIST("o", cfg_avopts, 0),
{0}
},
};
diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c
index 8e33f3b23c..26bbd56de0 100644
--- a/audio/filter/af_lavrresample.c
+++ b/audio/filter/af_lavrresample.c
@@ -52,9 +52,9 @@
#error "config.h broken or no resampler found"
#endif
+#include "common/av_common.h"
#include "common/msg.h"
#include "options/m_option.h"
-#include "common/av_opts.h"
#include "audio/filter/af.h"
#include "audio/fmt-conversion.h"
@@ -74,7 +74,7 @@ struct af_resample_opts {
struct af_resample {
int allow_detach;
- char *avopts;
+ char **avopts;
struct AVAudioResampleContext *avrctx;
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
struct af_resample_opts ctx; // opts in the context
@@ -164,10 +164,8 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
av_opt_set_double(s->avrctx, "cutoff", s->ctx.cutoff, 0);
- if (parse_avopts(s->avrctx, s->avopts) < 0) {
- MP_FATAL(af, "af_lavrresample: could not set opts: '%s'\n", s->avopts);
+ if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
return AF_ERROR;
- }
struct mp_chmap map_in = in->channels;
struct mp_chmap map_out = out->channels;
@@ -402,7 +400,7 @@ const struct af_info af_info_lavrresample = {
OPT_FLAG("linear", opts.linear, 0),
OPT_DOUBLE("cutoff", opts.cutoff, M_OPT_RANGE, .min = 0, .max = 1),
OPT_FLAG("detach", allow_detach, 0),
- OPT_STRING("o", avopts, 0),
+ OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
};
diff --git a/common/av_common.c b/common/av_common.c
index d090ccfc50..e0a5da7726 100644
--- a/common/av_common.c
+++ b/common/av_common.c
@@ -20,6 +20,8 @@
#include <libavutil/common.h>
#include <libavutil/log.h>
#include <libavutil/dict.h>
+#include <libavutil/opt.h>
+#include <libavutil/error.h>
#include <libavcodec/avcodec.h>
#include "common/common.h"
@@ -189,3 +191,37 @@ void mp_set_avdict(AVDictionary **dict, char **kv)
for (int n = 0; kv && kv[n * 2]; n++)
av_dict_set(dict, kv[n * 2 + 0], kv[n * 2 + 1], 0);
}
+
+// For use with libav* APIs that take AVDictionaries of options.
+// Print options remaining in the dict as unset.
+void mp_avdict_print_unset(struct mp_log *log, int msgl, AVDictionary *dict)
+{
+ AVDictionaryEntry *t = NULL;
+ while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX)))
+ mp_msg(log, msgl, "Could not set AVOption %s='%s'\n", t->key, t->value);
+}
+
+// kv is in the format as by OPT_KEYVALUELIST(): kv[0]=key0, kv[1]=val0, ...
+// Set these options on given avobj (using av_opt_set..., meaning avobj must
+// point to a struct that has AVClass as first member).
+// Options which fail to set (error or not found) are printed to log.
+// Returns: >=0 success, <0 failed to set an option
+int mp_set_avopts(struct mp_log *log, void *avobj, char **kv)
+{
+ int success = 0;
+ for (int n = 0; kv && kv[n * 2]; n++) {
+ char *k = kv[n * 2 + 0];
+ char *v = kv[n * 2 + 1];
+ int r = av_opt_set(avobj, k, v, AV_OPT_SEARCH_CHILDREN);
+ if (r == AVERROR_OPTION_NOT_FOUND) {
+ mp_err(log, "AVOption '%s' not found.\n", k);
+ success = -1;
+ } else if (r < 0) {
+ char errstr[80];
+ av_strerror(r, errstr, sizeof(errstr));
+ mp_err(log, "Could not set AVOption %s='%s' (%s)\n", k, v, errstr);
+ success = -1;
+ }
+ }
+ return success;
+}
diff --git a/common/av_common.h b/common/av_common.h
index 4afebe6662..3168d5310d 100644
--- a/common/av_common.h
+++ b/common/av_common.h
@@ -27,6 +27,7 @@
struct mp_decoder_list;
struct demux_packet;
struct AVDictionary;
+struct mp_log;
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size);
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
@@ -38,5 +39,7 @@ void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type);
int mp_codec_to_av_codec_id(const char *codec);
const char *mp_codec_from_av_codec_id(int codec_id);
void mp_set_avdict(struct AVDictionary **dict, char **kv);
+void mp_avdict_print_unset(struct mp_log *log, int msgl, struct AVDictionary *d);
+int mp_set_avopts(struct mp_log *log, void *avobj, char **kv);
#endif
diff --git a/common/av_opts.c b/common/av_opts.c
deleted file mode 100644
index 777a1eec5a..0000000000
--- a/common/av_opts.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * AVOption parsing helper
- * Copyright (C) 2008 Michael Niedermayer
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <libavutil/opt.h>
-
-#include "av_opts.h"
-
-int parse_avopts(void *v, char *str){
- char *start;
-
- if (!str)
- return 0;
-
- start= str= strdup(str);
-
- while(str && *str){
- char *next_opt, *arg;
-
- next_opt= strchr(str, ',');
- if(next_opt) *next_opt++= 0;
-
- arg = strchr(str, '=');
- if(arg) *arg++= 0;
-
- if (av_opt_set(v, str, arg, AV_OPT_SEARCH_CHILDREN) < 0) {
- free(start);
- return -1;
- }
- str= next_opt;
- }
-
- free(start);
- return 0;
-}
diff --git a/common/av_opts.h b/common/av_opts.h
deleted file mode 100644
index 640443a352..0000000000
--- a/common/av_opts.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * AVOption parsing helper
- * Copyright (C) 2008 Michael Niedermayer
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_AV_OPTS_H
-#define MPLAYER_AV_OPTS_H
-
-/**
- * Parses str and sets AVOptions in v accordingly.
- */
-int parse_avopts(void *v, char *str);
-
-#endif /* MPLAYER_AV_OPTS_H */
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 3ccda55d8e..0987508a14 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -44,7 +44,6 @@
#include "options/options.h"
#include "common/msg.h"
#include "common/tags.h"
-#include "common/av_opts.h"
#include "common/av_common.h"
#include "bstr/bstr.h"
@@ -71,7 +70,7 @@ struct demux_lavf_opts {
int allow_mimetype;
char *format;
char *cryptokey;
- char *avopt;
+ char **avopts;
int genptsmode;
};
@@ -87,7 +86,7 @@ const struct m_sub_options demux_lavf_conf = {
OPT_STRING("cryptokey", cryptokey, 0),
OPT_CHOICE("genpts-mode", genptsmode, 0,
({"lavf", 1}, {"no", 0})),
- OPT_STRING("o", avopt, 0),
+ OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
.size = sizeof(struct demux_lavf_opts),
@@ -674,14 +673,6 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
"analyzeduration to %f\n", analyze_duration);
}
- if (lavfdopts->avopt) {
- if (parse_avopts(avfc, lavfdopts->avopt) < 0) {
- MP_ERR(demuxer, "Your options /%s/ look like gibberish to me pal\n",
- lavfdopts->avopt);
- return -1;
- }
- }
-
if ((priv->avif->flags & AVFMT_NOFILE) ||
demuxer->stream->type == STREAMTYPE_AVDEVICE)
{
@@ -715,15 +706,15 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
av_dict_set(&dopts, "rtsp_transport", transport, 0);
}
+ mp_set_avdict(&dopts, lavfdopts->avopts);
+
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
MP_ERR(demuxer, "avformat_open_input() failed\n");
av_dict_free(&dopts);
return -1;
}
- t = NULL;
- while ((t = av_dict_get(dopts, "", t, AV_DICT_IGNORE_SUFFIX)))
- MP_VERBOSE(demuxer, "Could not set demux option %s=%s\n", t->key, t->value);
+ mp_avdict_print_unset(demuxer->log, MSGL_V, dopts);
av_dict_free(&dopts);
priv->avfc = avfc;
diff --git a/old-makefile b/old-makefile
index aac2379a3d..49078ea0e6 100644
--- a/old-makefile
+++ b/old-makefile
@@ -149,7 +149,6 @@ SOURCES = audio/audio.c \
bstr/bstr.c \
common/av_common.c \
common/av_log.c \
- common/av_opts.c \
common/codecs.c \
common/common.c \
common/msg.c \
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 8d8ceb3f94..c84945eba7 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -229,11 +229,7 @@ static int open_f(stream_t *stream)
goto out;
}
- AVDictionaryEntry *t = NULL;
- while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
- MP_VERBOSE(stream, "Could not set stream option %s=%s\n",
- t->key, t->value);
- }
+ mp_avdict_print_unset(stream->log, MSGL_V, dict);
if (avio->av_class) {
uint8_t *mt = NULL;
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index a59fffa790..75f66ce1f1 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -35,7 +35,6 @@
#include "common/msg.h"
#include "options/options.h"
#include "bstr/bstr.h"
-#include "common/av_opts.h"
#include "common/av_common.h"
#include "common/codecs.h"
@@ -79,7 +78,7 @@ struct vd_lavc_params {
int threads;
int bitexact;
int check_hw_profile;
- char *avopt;
+ char **avopts;
};
static const struct m_opt_choice_alternatives discard_names[] = {
@@ -105,7 +104,7 @@ const struct m_sub_options vd_lavc_conf = {
OPT_INTRANGE("threads", threads, 0, 0, 16),
OPT_FLAG("bitexact", bitexact, 0),
OPT_FLAG("check-hw-profile", check_hw_profile, 0),
- OPT_STRING("o", avopt, 0),
+ OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
.size = sizeof(struct vd_lavc_params),
@@ -383,14 +382,7 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
avctx->skip_idct = lavc_param->skip_idct;
avctx->skip_frame = lavc_param->skip_frame;
- if (lavc_param->avopt) {
- if (parse_avopts(avctx, lavc_param->avopt) < 0) {
- MP_ERR(vd, "Your options /%s/ look like gibberish to me pal\n",
- lavc_param->avopt);
- uninit_avctx(vd);
- return;
- }
- }
+ mp_set_avopts(vd->log, avctx, lavc_param->avopts);
// Do this after the above avopt handling in case it changes values
ctx->skip_frame = avctx->skip_frame;
diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c
index c6f0783460..8f1ee243a2 100644
--- a/video/filter/vf_lavfi.c
+++ b/video/filter/vf_lavfi.c
@@ -37,9 +37,9 @@
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
+#include "common/av_common.h"
#include "common/msg.h"
#include "options/m_option.h"
-#include "common/av_opts.h"
#include "common/tags.h"
#include "video/img_format.h"
@@ -78,7 +78,7 @@ struct vf_priv_s {
// options
char *cfg_graph;
int64_t cfg_sws_flags;
- char *cfg_avopts;
+ char **cfg_avopts;
};
static const struct vf_priv_s vf_priv_dflt = {
@@ -143,11 +143,8 @@ static bool recreate_graph(struct vf_instance *vf, int width, int height,
if (!graph)
goto error;
- if (parse_avopts(graph, p->cfg_avopts) < 0) {
- MP_FATAL(vf, "lavfi: could not set opts: '%s'\n",
- p->cfg_avopts);
+ if (mp_set_avopts(vf->log, graph, p->cfg_avopts) < 0)
goto error;
- }
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
@@ -426,7 +423,7 @@ static void print_help(struct mp_log *log)
static const m_option_t vf_opts_fields[] = {
OPT_STRING("graph", cfg_graph, M_OPT_MIN, .min = 1),
OPT_INT64("sws-flags", cfg_sws_flags, 0),
- OPT_STRING("o", cfg_avopts, 0),
+ OPT_KEYVALUELIST("o", cfg_avopts, 0),
{0}
};
@@ -445,7 +442,7 @@ const vf_info_t vf_info_lavfi = {
struct vf_lw_opts {
int enable;
int64_t sws_flags;
- char *avopts;
+ char **avopts;
};
#undef OPT_BASE_STRUCT
@@ -454,7 +451,7 @@ const struct m_sub_options vf_lw_conf = {
.opts = (const m_option_t[]) {
OPT_FLAG("lavfi", enable, 0),
OPT_INT64("lavfi-sws-flags", sws_flags, 0),
- OPT_STRING("lavfi-o", avopts, 0),
+ OPT_KEYVALUELIST("lavfi-o", avopts, 0),
{0}
},
.defaults = &(const struct vf_lw_opts){
diff --git a/wscript_build.py b/wscript_build.py
index 9496977340..87bf54de43 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -161,7 +161,6 @@ def build(ctx):
## Core
( "common/av_common.c" ),
( "common/av_log.c" ),
- ( "common/av_opts.c" ),
( "common/codecs.c" ),
( "common/encode_lavc.c", "encoding" ),
( "common/common.c" ),