mirror of
https://github.com/mpv-player/mpv
synced 2025-02-05 14:42:24 +00:00
hwdec/dmabuf_interop: use AVDRMFrameDescriptor to describe dmabufs
Annoyingly, libva and libdrm use different structs to describe dmabufs and if we are going to support drmprime, we must pick one format and do some shuffling in the other case. I've decided to use AVDRMFrameDescriptor as our internal format as this removes the libva dependency from dmabuf_interop. That means that the future drmprime hwdec will be able to populate it directly and the existing hwdec_vaapi needs to copy the struct members around, but that's cheap and not a concern.
This commit is contained in:
parent
e9e5059589
commit
64f4249604
24
meson.build
24
meson.build
@ -1474,7 +1474,6 @@ vaapi_egl = {
|
||||
if vaapi_egl['use']
|
||||
dependencies += [vaapi_wayland['deps'], vaapi_drm['deps']]
|
||||
features += vaapi_egl['name']
|
||||
sources += files('video/out/hwdec/dmabuf_interop_gl.c')
|
||||
endif
|
||||
|
||||
vaapi_libplacebo = {
|
||||
@ -1483,13 +1482,32 @@ vaapi_libplacebo = {
|
||||
}
|
||||
if vaapi_libplacebo['use']
|
||||
features += vaapi_libplacebo['name']
|
||||
sources += files('video/out/hwdec/dmabuf_interop_pl.c')
|
||||
endif
|
||||
|
||||
if vaapi_egl['use'] or vaapi_libplacebo['use']
|
||||
sources += files('video/out/hwdec/hwdec_vaapi.c')
|
||||
endif
|
||||
|
||||
dmabuf_interop_gl = {
|
||||
'name': 'dmabuf-interop-gl',
|
||||
'use': egl['use'] and drm['use']
|
||||
}
|
||||
|
||||
if dmabuf_interop_gl['use']
|
||||
features += dmabuf_interop_gl['name']
|
||||
sources += files('video/out/hwdec/dmabuf_interop_gl.c')
|
||||
endif
|
||||
|
||||
dmabuf_interop_pl = {
|
||||
'name': 'dmabuf-interop-pl',
|
||||
'use': vaapi_libplacebo['use']
|
||||
}
|
||||
|
||||
if dmabuf_interop_pl['use']
|
||||
features += dmabuf_interop_pl['name']
|
||||
sources += files('video/out/hwdec/dmabuf_interop_pl.c')
|
||||
endif
|
||||
|
||||
vdpau_opt = get_option('vdpau').require(
|
||||
x11['use'],
|
||||
error_message: 'x11 was not found!',
|
||||
@ -1721,6 +1739,8 @@ conf_data.set10('HAVE_D3D_HWACCEL', d3d_hwaccel.allowed())
|
||||
conf_data.set10('HAVE_D3D9_HWACCEL', d3d9_hwaccel.allowed())
|
||||
conf_data.set10('HAVE_D3D11', d3d11.allowed())
|
||||
conf_data.set10('HAVE_DIRECT3D', direct3d)
|
||||
conf_data.set10('HAVE_DMABUF_INTEROP_GL', dmabuf_interop_gl['use'])
|
||||
conf_data.set10('HAVE_DMABUF_INTEROP_PL', dmabuf_interop_pl['use'])
|
||||
conf_data.set10('HAVE_DOS_PATHS', win32)
|
||||
conf_data.set10('HAVE_DRM', drm['use'])
|
||||
conf_data.set10('HAVE_DVBIN', dvbin.allowed())
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <va/va_drmcommon.h>
|
||||
#include <libavutil/hwcontext_drm.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "video/out/gpu/hwdec.h"
|
||||
@ -40,7 +40,7 @@ struct priv {
|
||||
struct mp_image layout;
|
||||
struct ra_tex *tex[4];
|
||||
|
||||
VADRMPRIMESurfaceDescriptor desc;
|
||||
AVDRMFrameDescriptor desc;
|
||||
bool surface_acquired;
|
||||
|
||||
void *interop_mapper_priv;
|
||||
|
@ -144,11 +144,11 @@ static void vaapi_gl_mapper_uninit(const struct ra_hwdec_mapper *mapper)
|
||||
} while(0)
|
||||
|
||||
#define ADD_PLANE_ATTRIBS(plane) do { \
|
||||
uint64_t drm_format_modifier = p_mapper->desc.objects[p_mapper->desc.layers[n].object_index[plane]].drm_format_modifier; \
|
||||
uint64_t drm_format_modifier = p_mapper->desc.objects[p_mapper->desc.layers[n].planes[plane].object_index].format_modifier; \
|
||||
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _FD_EXT, \
|
||||
p_mapper->desc.objects[p_mapper->desc.layers[n].object_index[plane]].fd); \
|
||||
p_mapper->desc.objects[p_mapper->desc.layers[n].planes[plane].object_index].fd); \
|
||||
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
|
||||
p_mapper->desc.layers[n].offset[plane]); \
|
||||
p_mapper->desc.layers[n].planes[plane].offset); \
|
||||
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
|
||||
p_mapper->desc.layers[n].planes[plane].pitch); \
|
||||
if (dmabuf_interop->use_modifiers && drm_format_modifier != DRM_FORMAT_MOD_INVALID) { \
|
||||
@ -167,7 +167,7 @@ static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper,
|
||||
GL *gl = ra_gl_get(mapper->ra);
|
||||
|
||||
for (int n = 0; n < p_mapper->num_planes; n++) {
|
||||
if (p_mapper->desc.layers[n].num_planes > 1) {
|
||||
if (p_mapper->desc.layers[n].nb_planes > 1) {
|
||||
// Should never happen because we request separate layers
|
||||
MP_ERR(mapper, "Multi-plane surfaces are not supported\n");
|
||||
return false;
|
||||
@ -176,16 +176,16 @@ static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper,
|
||||
int attribs[48] = {EGL_NONE};
|
||||
int num_attribs = 0;
|
||||
|
||||
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, p_mapper->desc.layers[n].drm_format);
|
||||
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, p_mapper->desc.layers[n].format);
|
||||
ADD_ATTRIB(EGL_WIDTH, p_mapper->tex[n]->params.w);
|
||||
ADD_ATTRIB(EGL_HEIGHT, p_mapper->tex[n]->params.h);
|
||||
|
||||
ADD_PLANE_ATTRIBS(0);
|
||||
if (p_mapper->desc.layers[n].num_planes > 1)
|
||||
if (p_mapper->desc.layers[n].nb_planes > 1)
|
||||
ADD_PLANE_ATTRIBS(1);
|
||||
if (p_mapper->desc.layers[n].num_planes > 2)
|
||||
if (p_mapper->desc.layers[n].nb_planes > 2)
|
||||
ADD_PLANE_ATTRIBS(2);
|
||||
if (p_mapper->desc.layers[n].num_planes > 3)
|
||||
if (p_mapper->desc.layers[n].nb_planes > 3)
|
||||
ADD_PLANE_ATTRIBS(3);
|
||||
|
||||
p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
|
||||
|
@ -41,11 +41,11 @@ static bool vaapi_pl_map(struct ra_hwdec_mapper *mapper,
|
||||
for (int n = 0; n < p->num_planes; n++) {
|
||||
|
||||
const struct ra_format *format = desc.planes[n];
|
||||
int id = p->desc.layers[layer].object_index[layer_plane];
|
||||
int id = p->desc.layers[layer].planes[layer_plane].object_index;
|
||||
int fd = p->desc.objects[id].fd;
|
||||
uint32_t size = p->desc.objects[id].size;
|
||||
uint32_t offset = p->desc.layers[layer].offset[layer_plane];
|
||||
uint32_t pitch = p->desc.layers[layer].pitch[layer_plane];
|
||||
uint32_t offset = p->desc.layers[layer].planes[layer_plane].offset;
|
||||
uint32_t pitch = p->desc.layers[layer].planes[layer_plane].pitch;
|
||||
|
||||
// AMD drivers do not return the size in the surface description, so we
|
||||
// need to query it manually.
|
||||
@ -77,7 +77,7 @@ static bool vaapi_pl_map(struct ra_hwdec_mapper *mapper,
|
||||
},
|
||||
.size = size,
|
||||
.offset = offset,
|
||||
.drm_format_mod = p->desc.objects[id].drm_format_modifier,
|
||||
.drm_format_mod = p->desc.objects[id].format_modifier,
|
||||
.stride_w = pitch,
|
||||
},
|
||||
};
|
||||
@ -101,7 +101,7 @@ static bool vaapi_pl_map(struct ra_hwdec_mapper *mapper,
|
||||
id, fd, ratex);
|
||||
|
||||
layer_plane++;
|
||||
if (layer_plane == p->desc.layers[layer].num_planes) {
|
||||
if (layer_plane == p->desc.layers[layer].nb_planes) {
|
||||
layer_plane = 0;
|
||||
layer++;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/hwcontext_vaapi.h>
|
||||
#include <va/va_drmcommon.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@ -117,10 +118,10 @@ static void uninit(struct ra_hwdec *hw)
|
||||
}
|
||||
|
||||
const static dmabuf_interop_init interop_inits[] = {
|
||||
#if HAVE_VAAPI_EGL
|
||||
#if HAVE_DMABUF_INTEROP_GL
|
||||
dmabuf_interop_gl_init,
|
||||
#endif
|
||||
#if HAVE_VAAPI_LIBPLACEBO
|
||||
#if HAVE_DMABUF_INTEROP_PL
|
||||
dmabuf_interop_pl_init,
|
||||
#endif
|
||||
NULL
|
||||
@ -181,7 +182,7 @@ static void mapper_unmap(struct ra_hwdec_mapper *mapper)
|
||||
p_owner->dmabuf_interop.interop_unmap(mapper);
|
||||
|
||||
if (p->surface_acquired) {
|
||||
for (int n = 0; n < p->desc.num_objects; n++)
|
||||
for (int n = 0; n < p->desc.nb_objects; n++)
|
||||
close(p->desc.objects[n].fd);
|
||||
p->surface_acquired = false;
|
||||
}
|
||||
@ -242,12 +243,13 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
|
||||
struct priv *p = mapper->priv;
|
||||
VAStatus status;
|
||||
VADisplay *display = p_owner->display;
|
||||
VADRMPRIMESurfaceDescriptor desc;
|
||||
|
||||
status = vaExportSurfaceHandle(display, va_surface_id(mapper->src),
|
||||
VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
||||
VA_EXPORT_SURFACE_READ_ONLY |
|
||||
VA_EXPORT_SURFACE_SEPARATE_LAYERS,
|
||||
&p->desc);
|
||||
&desc);
|
||||
if (!CHECK_VA_STATUS_LEVEL(mapper, "vaExportSurfaceHandle()",
|
||||
p_owner->probing_formats ? MSGL_DEBUG : MSGL_ERR))
|
||||
{
|
||||
@ -258,21 +260,38 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
|
||||
CHECK_VA_STATUS(mapper, "vaSyncSurface()");
|
||||
p->surface_acquired = true;
|
||||
|
||||
// We use AVDRMFrameDescriptor to store the dmabuf so we need to copy the
|
||||
// values over.
|
||||
int num_returned_planes = 0;
|
||||
p->desc.nb_layers = desc.num_layers;
|
||||
p->desc.nb_objects = desc.num_objects;
|
||||
for (int i = 0; i < desc.num_layers; i++) {
|
||||
p->desc.layers[i].format = desc.layers[i].drm_format;
|
||||
p->desc.layers[i].nb_planes = desc.layers[i].num_planes;
|
||||
for (int j = 0; j < desc.layers[i].num_planes; j++)
|
||||
{
|
||||
p->desc.layers[i].planes[j].object_index = desc.layers[i].object_index[j];
|
||||
p->desc.layers[i].planes[j].offset = desc.layers[i].offset[j];
|
||||
p->desc.layers[i].planes[j].pitch = desc.layers[i].pitch[j];
|
||||
}
|
||||
|
||||
num_returned_planes += desc.layers[i].num_planes;
|
||||
}
|
||||
for (int i = 0; i < desc.num_objects; i++) {
|
||||
p->desc.objects[i].format_modifier = desc.objects[i].drm_format_modifier;
|
||||
p->desc.objects[i].fd = desc.objects[i].fd;
|
||||
p->desc.objects[i].size = desc.objects[i].size;
|
||||
}
|
||||
|
||||
// We can handle composed formats if the total number of planes is still
|
||||
// equal the number of planes we expect. Complex formats with auxilliary
|
||||
// planes cannot be supported.
|
||||
|
||||
int num_returned_planes = 0;
|
||||
for (int i = 0; i < p->desc.num_layers; i++) {
|
||||
num_returned_planes += p->desc.layers[i].num_planes;
|
||||
}
|
||||
|
||||
if (p->num_planes != num_returned_planes) {
|
||||
mp_msg(mapper->log, p_owner->probing_formats ? MSGL_DEBUG : MSGL_ERR,
|
||||
"Mapped surface with format '%s' has unexpected number of planes. "
|
||||
"(%d layers and %d planes, but expected %d planes)\n",
|
||||
mp_imgfmt_to_name(mapper->src->params.hw_subfmt),
|
||||
p->desc.num_layers, num_returned_planes, p->num_planes);
|
||||
desc.num_layers, num_returned_planes, p->num_planes);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -280,7 +299,7 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
|
||||
p_owner->probing_formats))
|
||||
goto err;
|
||||
|
||||
if (p->desc.fourcc == VA_FOURCC_YV12)
|
||||
if (desc.fourcc == VA_FOURCC_YV12)
|
||||
MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
|
||||
|
||||
return 0;
|
||||
|
10
wscript
10
wscript
@ -782,6 +782,16 @@ video_output_features = [
|
||||
'name': '--sixel',
|
||||
'desc': 'Sixel',
|
||||
'func': check_pkg_config('libsixel', '>= 1.5'),
|
||||
}, {
|
||||
'name': 'dmabuf-interop-gl',
|
||||
'desc': 'dmabuf GL Interop',
|
||||
'deps': 'egl && drm',
|
||||
'func': check_true,
|
||||
}, {
|
||||
'name': 'dmabuf-interop-pl',
|
||||
'desc': 'dmabuf libplacebo interop',
|
||||
'deps': 'vaapi-libplacebo',
|
||||
'func': check_true,
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -471,8 +471,8 @@ def build(ctx):
|
||||
( "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-libplacebo" ),
|
||||
( "video/out/hwdec/dmabuf_interop_gl.c", "vaapi-egl" ),
|
||||
( "video/out/hwdec/dmabuf_interop_pl.c", "vaapi-libplacebo" ),
|
||||
( "video/out/hwdec/dmabuf_interop_gl.c", "dmabuf-interop-gl" ),
|
||||
( "video/out/hwdec/dmabuf_interop_pl.c", "dmabuf-interop-pl" ),
|
||||
( "video/out/libmpv_sw.c" ),
|
||||
( "video/out/placebo/ra_pl.c", "libplacebo" ),
|
||||
( "video/out/placebo/utils.c", "libplacebo" ),
|
||||
|
Loading…
Reference in New Issue
Block a user