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.
This commit is contained in:
Philip Langdale 2019-12-28 12:58:39 -08:00 committed by Philip Langdale
parent f0d0822595
commit 9c05be8999
7 changed files with 72 additions and 14 deletions

View File

@ -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

47
video/cuda.c Normal file
View File

@ -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,
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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',

View File

@ -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" ),