summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst12
-rw-r--r--core/cfg-mplayer.h1
-rw-r--r--core/defaultopts.c2
-rw-r--r--core/options.h1
-rw-r--r--video/decode/vd_lavc.c19
5 files changed, 32 insertions, 3 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index c805e04002..53c04f48fc 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -874,6 +874,18 @@
:vda: OSX
:crystalhd: Broadcom Crystal HD
+--hwdec-codecs=<codec1,codec2,...|all>
+ Allow hardware decoding for a given list of codecs only. The default is the
+ special value ``all``, which always allows all codecs.
+
+ This is usually only needed with broken GPUs, where fallback to software
+ decoding doesn't work properly.
+
+ *EXAMPLE*:
+
+ - ``mpv --hwdec=vdpau --vo=vdpau --hwdec-codecs=h264,mpeg2video``
+ Enable vdpau decoding for h264 and mpeg2 only.
+
--identify
Deprecated. Use ``TOOLS/mpv_identify.sh``.
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 7414d561bd..570c403f9c 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -449,6 +449,7 @@ const m_option_t common_opts[] = {
{"vdpau", 1},
{"vda", 2},
{"crystalhd", 3})),
+ OPT_STRING("hwdec-codecs", hwdec_codecs, 0),
// postprocessing:
{"pp", &divx_quality, CONF_TYPE_INT, 0, 0, 0, NULL},
diff --git a/core/defaultopts.c b/core/defaultopts.c
index 3231c8142d..03d697d732 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -86,6 +86,8 @@ void set_default_mplayer_options(struct MPOpts *opts)
.ass_style_override = 1,
.use_embedded_fonts = 1,
+ .hwdec_codecs = "all",
+
.lavc_param = {
.workaround_bugs = 1, // autodetect
.error_concealment = 3,
diff --git a/core/options.h b/core/options.h
index 8806a66211..4729d7ca6a 100644
--- a/core/options.h
+++ b/core/options.h
@@ -185,6 +185,7 @@ typedef struct MPOpts {
int ass_hinting;
int hwdec_api;
+ char *hwdec_codecs;
struct lavc_param {
int workaround_bugs;
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 59eba1166b..c3e9ce5860 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -135,6 +135,18 @@ static struct hwdec *find_hwcodec(enum hwdec_type api, const char *codec)
return NULL;
}
+static bool hwdec_codec_allowed(sh_video_t *sh, struct hwdec *hwdec)
+{
+ bstr s = bstr0(sh->opts->hwdec_codecs);
+ while (s.len) {
+ bstr item;
+ bstr_split_tok(s, ",", &item, &s);
+ if (bstr_equals0(item, "all") || bstr_equals0(item, hwdec->codec))
+ return true;
+ }
+ return false;
+}
+
static enum AVDiscard str2AVDiscard(char *str)
{
if (!str) return AVDISCARD_DEFAULT;
@@ -155,19 +167,20 @@ static int init(sh_video_t *sh, const char *decoder)
ctx->non_dr1_pool = talloc_steal(ctx, mp_image_pool_new(16));
struct hwdec *hwdec = find_hwcodec(sh->opts->hwdec_api, decoder);
- if (hwdec) {
+ struct hwdec *use_hwdec = NULL;
+ if (hwdec && hwdec_codec_allowed(sh, hwdec)) {
AVCodec *lavc_hwcodec = avcodec_find_decoder_by_name(hwdec->hw_codec);
if (lavc_hwcodec) {
ctx->software_fallback_decoder = talloc_strdup(ctx, decoder);
decoder = lavc_hwcodec->name;
+ use_hwdec = hwdec;
} else {
mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Decoder '%s' not found in "
"libavcodec, using software decoding.\n", hwdec->hw_codec);
- hwdec = NULL;
}
}
- init_avctx(sh, decoder, hwdec);
+ init_avctx(sh, decoder, use_hwdec);
if (!ctx->avctx) {
if (ctx->software_fallback_decoder) {
mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error initializing hardware "