summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2019-12-28 12:58:39 -0800
committerPhilip Langdale <github.philipl@overt.org>2019-12-29 14:32:47 -0800
commit9c05be8999a77deea056c8c4952ab37756d05ce2 (patch)
tree9e5e7eb1e606adb7882175f5e7e8c164e13c3386
parentf0d0822595c7dc3e2a20aa3e153a94f08f1d88dd (diff)
downloadmpv-9c05be8999a77deea056c8c4952ab37756d05ce2.tar.bz2
mpv-9c05be8999a77deea056c8c4952ab37756d05ce2.tar.xz
video: cuda: add explicit context creation for copy hwaccels
In the distant past, the cuviddec backed copy hwaccel could be configured directly using lavc options. However, since that time, we gained support for automatic hw ctx creation which ended up bypassing the lavc options. Rather than trying to find a way to pass those options again, a better idea is to make the 'cuda-decode-device' option, used by the interop hwaccels, work for the copy hwaccels too. And that's pretty simple: we have to add a create function that checks the option and passes it on to ffmpeg. Note that this does require a slight re-jig to the configuration flags, as we now have a scenario where we want to build with support for the cuda copy hwaccels but not the interop ones. So we need a distinct configuration flag for that combination. Fixes #7295.
-rw-r--r--DOCS/man/options.rst17
-rw-r--r--video/cuda.c47
-rw-r--r--video/hwdec.c3
-rw-r--r--video/hwdec.h1
-rw-r--r--video/out/gpu/hwdec.c2
-rw-r--r--wscript9
-rw-r--r--wscript_build.py7
7 files changed, 72 insertions, 14 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 3362cd142a..ce3bea5a15 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1233,17 +1233,18 @@ Video
``--cuda-decode-device=<auto|0..>``
Choose the GPU device used for decoding when using the ``cuda`` or
- ``nvdec`` hwdecs with the OpenGL GPU backend.
+ ``nvdec`` hwdecs with the OpenGL GPU backend, and with the ``cuda-copy``
+ or ``nvdec-copy`` hwdecs in all cases.
- By default, the device that is being used to provide ``gpu`` output will
- also be used for decoding (and in the vast majority of cases, only one
- GPU will be present).
+ For the OpenGL GPU backend, the default device used for decoding is the one
+ being used to provide ``gpu`` output (and in the vast majority of cases,
+ only one GPU will be present).
- Note that when using the ``cuda-copy`` or ``nvdec-copy`` hwdec, a
- different option must be passed: ``--vd-lavc-o=gpu=<0..>``.
+ For the ``copy`` hwdecs, the default device will be the first device
+ enumerated by the CUDA libraries - however that is done.
- Note that this option is not available with the Vulkan GPU backend. With
- Vulkan, decoding must always happen on the display device.
+ For the Vulkan GPU backend, decoding must always happen on the display
+ device, and this option has no effect.
``--vaapi-device=<device file>``
Choose the DRM device for ``vaapi-copy``. This should be the path to a
diff --git a/video/cuda.c b/video/cuda.c
new file mode 100644
index 0000000000..2f3f51e061
--- /dev/null
+++ b/video/cuda.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "hwdec.h"
+#include "options/m_config.h"
+
+#include <libavutil/hwcontext.h>
+
+static struct AVBufferRef *cuda_create_standalone(struct mpv_global *global,
+ struct mp_log *log, struct hwcontext_create_dev_params *params)
+{
+ int decode_dev_idx;
+ mp_read_option_raw(global, "cuda-decode-device", &m_option_type_choice,
+ &decode_dev_idx);
+
+ char *decode_dev = NULL;
+ if (decode_dev_idx != -1) {
+ decode_dev = talloc_asprintf(NULL, "%d", decode_dev_idx);
+ }
+
+ AVBufferRef* ref = NULL;
+ av_hwdevice_ctx_create(&ref, AV_HWDEVICE_TYPE_CUDA, decode_dev, NULL, 0);
+
+ ta_free(decode_dev);
+ return ref;
+}
+
+const struct hwcontext_fns hwcontext_fns_cuda = {
+ .av_hwdevice_type = AV_HWDEVICE_TYPE_CUDA,
+ .create_dev = cuda_create_standalone,
+};
diff --git a/video/hwdec.c b/video/hwdec.c
index b3c2131791..97b984db18 100644
--- a/video/hwdec.c
+++ b/video/hwdec.c
@@ -119,6 +119,9 @@ char *hwdec_devices_get_names(struct mp_hwdec_devices *devs)
}
static const struct hwcontext_fns *const hwcontext_fns[] = {
+#if HAVE_CUDA_HWACCEL
+ &hwcontext_fns_cuda,
+#endif
#if HAVE_D3D_HWACCEL
&hwcontext_fns_d3d11,
#endif
diff --git a/video/hwdec.h b/video/hwdec.h
index 0aa33a05ba..b2ca8ca894 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -89,6 +89,7 @@ struct hwcontext_fns {
// recursive includes). May return NULL for unknown device types.
const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type);
+extern const struct hwcontext_fns hwcontext_fns_cuda;
extern const struct hwcontext_fns hwcontext_fns_d3d11;
extern const struct hwcontext_fns hwcontext_fns_dxva2;
extern const struct hwcontext_fns hwcontext_fns_vaapi;
diff --git a/video/out/gpu/hwdec.c b/video/out/gpu/hwdec.c
index f1c941cdc9..c07dbf9fd0 100644
--- a/video/out/gpu/hwdec.c
+++ b/video/out/gpu/hwdec.c
@@ -64,7 +64,7 @@ const struct ra_hwdec_driver *const ra_hwdec_drivers[] = {
#if HAVE_GL_DXINTEROP_D3D9
&ra_hwdec_dxva2gldx,
#endif
-#if HAVE_CUDA_HWACCEL
+#if HAVE_CUDA_INTEROP
&ra_hwdec_cuda,
#endif
#if HAVE_VDPAU_GL_X11
diff --git a/wscript b/wscript
index a0f6583de5..1da8054f95 100644
--- a/wscript
+++ b/wscript
@@ -887,8 +887,13 @@ hwaccel_features = [
'func': check_pkg_config('ffnvcodec >= 8.2.15.7'),
}, {
'name': '--cuda-hwaccel',
- 'desc': 'CUDA hwaccel',
- 'deps': '(gl || vulkan) && ffnvcodec',
+ 'desc': 'CUDA acceleration',
+ 'deps': 'ffnvcodec',
+ 'func': check_true,
+ }, {
+ 'name': '--cuda-interop',
+ 'desc': 'CUDA with graphics interop',
+ 'deps': '(gl || vulkan) && cuda-hwaccel',
'func': check_true,
}, {
'name': '--rpi-mmal',
diff --git a/wscript_build.py b/wscript_build.py
index 3d772a31fb..3d901df3fb 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -410,6 +410,7 @@ def build(ctx):
## Video
( "video/csputils.c" ),
+ ( "video/cuda.c", "cuda-hwaccel" ),
( "video/d3d.c", "d3d-hwaccel" ),
( "video/decode/vd_lavc.c" ),
( "video/filter/refqueue.c" ),
@@ -460,9 +461,9 @@ def build(ctx):
( "video/out/gpu/utils.c" ),
( "video/out/gpu/video.c" ),
( "video/out/gpu/video_shaders.c" ),
- ( "video/out/hwdec/hwdec_cuda.c", "cuda-hwaccel" ),
- ( "video/out/hwdec/hwdec_cuda_gl.c", "cuda-hwaccel && gl" ),
- ( "video/out/hwdec/hwdec_cuda_vk.c", "cuda-hwaccel && vulkan" ),
+ ( "video/out/hwdec/hwdec_cuda.c", "cuda-interop" ),
+ ( "video/out/hwdec/hwdec_cuda_gl.c", "cuda-interop && gl" ),
+ ( "video/out/hwdec/hwdec_cuda_vk.c", "cuda-interop && vulkan" ),
( "video/out/hwdec/hwdec_vaapi.c", "vaapi-egl || vaapi-vulkan" ),
( "video/out/hwdec/hwdec_vaapi_gl.c", "vaapi-egl" ),
( "video/out/hwdec/hwdec_vaapi_vk.c", "vaapi-vulkan" ),