summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-05-11 16:18:58 +0200
committerwm4 <wm4@nowhere>2016-05-11 16:20:13 +0200
commit70b35612704a992dac45856e069608216f41ea89 (patch)
tree6ed76d1cfc9f4dad857b0c8d56c7fd6db1bb24fc
parent2ec26b8396c8d44def148351ee370fde4b950cbf (diff)
downloadmpv-70b35612704a992dac45856e069608216f41ea89.tar.bz2
mpv-70b35612704a992dac45856e069608216f41ea89.tar.xz
video: add --hwdec=auto-copy mode
This uses the normal autoprobing rules like "auto", but rejects anything that isn't flagged as copying data back to system memory. The chunk in command.c was dead code, so remove it instead of updating it.
-rw-r--r--DOCS/man/options.rst8
-rw-r--r--options/options.c1
-rw-r--r--player/command.c2
-rw-r--r--video/decode/d3d11va.c1
-rw-r--r--video/decode/dxva2.c1
-rw-r--r--video/decode/lavc.h2
-rw-r--r--video/decode/vaapi.c1
-rw-r--r--video/decode/vd_lavc.c12
-rw-r--r--video/hwdec.h5
-rw-r--r--video/out/opengl/hwdec.c2
10 files changed, 28 insertions, 7 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index ab34e6468e..c61a556296 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -581,6 +581,7 @@ Video
:no: always use software decoding (default)
:auto: see below
+ :auto-copy: see below
:vdpau: requires ``--vo=vdpau`` or ``--vo=opengl`` (Linux only)
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux only)
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
@@ -600,6 +601,13 @@ Video
work, it will always fall back to software decoding, instead of trying the
next method (might matter on some Linux systems).
+ ``auto-copy`` selects only modes that copy the video data back to system
+ memory after decoding. Currently, this selects only one of the following
+ modes: ``vaapi-copy``, ``dxva2-copy``, ``d3d11va-copy``, ``mediacodec``.
+ If none of these work, hardware decoding is disabled. This mode is always
+ guaranteed to incur no additional loss compared to software decoding, and
+ will allow CPU processing with video filters.
+
The ``vaapi`` mode, if used with ``--vo=opengl``, requires Mesa 11 and most
likely works with Intel GPUs only. It also requires the opengl EGL backend
(automatically used if available). You can also try the old GLX backend by
diff --git a/options/options.c b/options/options.c
index 92acb42c81..bb2ccb5220 100644
--- a/options/options.c
+++ b/options/options.c
@@ -82,6 +82,7 @@ extern const struct m_obj_list ao_obj_list;
const struct m_opt_choice_alternatives mp_hwdec_names[] = {
{"no", HWDEC_NONE},
{"auto", HWDEC_AUTO},
+ {"auto-copy", HWDEC_AUTO_COPY},
{"vdpau", HWDEC_VDPAU},
{"videotoolbox",HWDEC_VIDEOTOOLBOX},
{"vaapi", HWDEC_VAAPI},
diff --git a/player/command.c b/player/command.c
index c8394c403c..7d143ea1f4 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2185,8 +2185,6 @@ static int mp_property_hwdec_current(void *ctx, struct m_property *prop,
case M_PROPERTY_GET: {
int current = HWDEC_NONE;
video_vd_control(vd, VDCTRL_GET_HWDEC, &current);
- if (current == HWDEC_AUTO)
- current = HWDEC_NONE;
*(int *)arg = current;
return M_PROPERTY_OK;
}
diff --git a/video/decode/d3d11va.c b/video/decode/d3d11va.c
index 9e300b1620..d631fff479 100644
--- a/video/decode/d3d11va.c
+++ b/video/decode/d3d11va.c
@@ -583,6 +583,7 @@ const struct vd_lavc_hwdec mp_vd_lavc_d3d11va = {
const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
.type = HWDEC_D3D11VA_COPY,
+ .copying = true,
.image_format = IMGFMT_D3D11VA,
.probe = d3d11va_probe,
.init = d3d11va_init,
diff --git a/video/decode/dxva2.c b/video/decode/dxva2.c
index 5d3afda86c..fe78a52e8c 100644
--- a/video/decode/dxva2.c
+++ b/video/decode/dxva2.c
@@ -499,6 +499,7 @@ const struct vd_lavc_hwdec mp_vd_lavc_dxva2 = {
const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy = {
.type = HWDEC_DXVA2_COPY,
+ .copying = true,
.image_format = IMGFMT_DXVA2,
.probe = dxva2_probe,
.init = dxva2_init,
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index dbefe79ad9..689222d872 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -49,6 +49,8 @@ struct vd_lavc_hwdec {
// If not-0: the IMGFMT_ format that should be accepted in the libavcodec
// get_format callback.
int image_format;
+ // Always returns a non-hwaccel image format.
+ bool copying;
// Setting this will queue the given number of frames before calling
// process_image() or returning them to the renderer. This can increase
// efficiency by not blocking on the hardware pipeline by reading back
diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c
index 4b098a8804..d108d50a8b 100644
--- a/video/decode/vaapi.c
+++ b/video/decode/vaapi.c
@@ -507,6 +507,7 @@ const struct vd_lavc_hwdec mp_vd_lavc_vaapi = {
const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = {
.type = HWDEC_VAAPI_COPY,
+ .copying = true,
.image_format = IMGFMT_VAAPI,
.probe = probe_copy,
.init = init_copy,
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 75ca1f0229..fbb04d1abd 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -138,6 +138,7 @@ static const struct vd_lavc_hwdec mp_vd_lavc_rpi = {
static const struct vd_lavc_hwdec mp_vd_lavc_mediacodec = {
.type = HWDEC_MEDIACODEC,
.lavc_suffix = "_mediacodec",
+ .copying = true,
};
static const struct vd_lavc_hwdec *const hwdec_list[] = {
@@ -347,7 +348,8 @@ static void reinit(struct dec_video *vd)
struct vd_lavc_hwdec *hwdec = NULL;
if (hwdec_codec_allowed(vd, codec)) {
- if (vd->opts->hwdec_api == HWDEC_AUTO) {
+ int api = vd->opts->hwdec_api;
+ if (HWDEC_IS_AUTO(api)) {
// If a specific decoder is forced, we should try a hwdec method
// that works with it, instead of simply failing later at runtime.
// This is good for avoiding trying "normal" hwaccels on wrapper
@@ -369,11 +371,15 @@ static void reinit(struct dec_video *vd)
MP_VERBOSE(vd, "This hwaccel is not compatible.\n");
continue;
}
+ if (api == HWDEC_AUTO_COPY && !hwdec->copying) {
+ MP_VERBOSE(vd, "Not using this for auto-copy mode.\n");
+ continue;
+ }
break;
}
}
- } else if (vd->opts->hwdec_api != HWDEC_NONE) {
- hwdec = probe_hwdec(vd, false, vd->opts->hwdec_api, codec);
+ } else if (api != HWDEC_NONE) {
+ hwdec = probe_hwdec(vd, false, api, codec);
}
} else {
MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
diff --git a/video/hwdec.h b/video/hwdec.h
index 48ec6a2a21..5d563c983b 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -9,6 +9,7 @@ struct mp_image_pool;
enum hwdec_type {
HWDEC_NONE = 0,
HWDEC_AUTO,
+ HWDEC_AUTO_COPY,
HWDEC_VDPAU,
HWDEC_VIDEOTOOLBOX,
HWDEC_VAAPI,
@@ -21,11 +22,13 @@ enum hwdec_type {
HWDEC_MEDIACODEC,
};
+#define HWDEC_IS_AUTO(x) ((x) == HWDEC_AUTO || (x) == HWDEC_AUTO_COPY)
+
// hwdec_type names (options.c)
extern const struct m_opt_choice_alternatives mp_hwdec_names[];
struct mp_hwdec_ctx {
- enum hwdec_type type; // (never HWDEC_NONE or HWDEC_AUTO)
+ enum hwdec_type type; // (never HWDEC_NONE or HWDEC_IS_AUTO)
const char *driver_name; // NULL if unknown/not loaded
// This is never NULL. Its meaning depends on the .type field:
diff --git a/video/out/opengl/hwdec.c b/video/out/opengl/hwdec.c
index 1f654fc1ec..fac0c3ff9a 100644
--- a/video/out/opengl/hwdec.c
+++ b/video/out/opengl/hwdec.c
@@ -88,7 +88,7 @@ struct gl_hwdec *gl_hwdec_load_api(struct mp_log *log, GL *gl,
struct mp_hwdec_devices *devs,
enum hwdec_type api)
{
- bool is_auto = api == HWDEC_AUTO;
+ bool is_auto = HWDEC_IS_AUTO(api);
for (int n = 0; mpgl_hwdec_drivers[n]; n++) {
const struct gl_hwdec_driver *drv = mpgl_hwdec_drivers[n];
if (is_auto || api == drv->api) {