diff options
Diffstat (limited to 'video/out/hwdec/hwdec_drmprime.c')
-rw-r--r-- | video/out/hwdec/hwdec_drmprime.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/video/out/hwdec/hwdec_drmprime.c b/video/out/hwdec/hwdec_drmprime.c index 1328e19162..bf604056f3 100644 --- a/video/out/hwdec/hwdec_drmprime.c +++ b/video/out/hwdec/hwdec_drmprime.c @@ -23,12 +23,14 @@ #include <libavutil/hwcontext.h> #include <libavutil/hwcontext_drm.h> +#include <libavutil/pixdesc.h> #include <xf86drm.h> #include "config.h" #include "libmpv/render_gl.h" #include "options/m_config.h" +#include "video/fmt-conversion.h" #include "video/out/drm_common.h" #include "video/out/gpu/hwdec.h" #include "video/out/hwdec/dmabuf_interop.h" @@ -47,13 +49,14 @@ static void uninit(struct ra_hwdec *hw) struct priv_owner *p = hw->priv; if (p->hwctx.driver_name) hwdec_devices_remove(hw->devs, &p->hwctx); + av_buffer_unref(&p->hwctx.av_device_ref); } -const static dmabuf_interop_init interop_inits[] = { +static const dmabuf_interop_init interop_inits[] = { #if HAVE_DMABUF_INTEROP_GL dmabuf_interop_gl_init, #endif -#if HAVE_DMABUF_INTEROP_PL +#if HAVE_VAAPI dmabuf_interop_pl_init, #endif #if HAVE_DMABUF_WAYLAND @@ -62,6 +65,18 @@ const static dmabuf_interop_init interop_inits[] = { NULL }; +/** + * Due to the fact that Raspberry Pi support only exists in forked ffmpegs and + * also requires custom pixel formats, we need some way to work with those formats + * without introducing any build time dependencies. We do this by looking up the + * pixel formats by name. As rpi is an important target platform for this hwdec + * we don't really have the luxury of ignoring these forks. + */ +static const char *forked_pix_fmt_names[] = { + "rpi4_8", + "rpi4_10", +}; + static int init(struct ra_hwdec *hw) { struct priv_owner *p = hw->priv; @@ -82,7 +97,7 @@ static int init(struct ra_hwdec *hw) * there are extensions that supposedly provide this information from the * drivers. Not properly documented. Of course. */ - mpv_opengl_drm_params_v2 *params = ra_get_native_resource(hw->ra, + mpv_opengl_drm_params_v2 *params = ra_get_native_resource(hw->ra_ctx->ra, "drm_params_v2"); /* @@ -92,7 +107,7 @@ static int init(struct ra_hwdec *hw) */ void *tmp = talloc_new(NULL); struct drm_opts *drm_opts = mp_get_config_group(tmp, hw->global, &drm_conf); - const char *opt_path = drm_opts->drm_device_path; + const char *opt_path = drm_opts->device_path; const char *device_path = params && params->render_fd > -1 ? drmGetRenderDeviceNameFromFd(params->render_fd) : @@ -115,6 +130,20 @@ static int init(struct ra_hwdec *hw) */ int num_formats = 0; MP_TARRAY_APPEND(p, p->formats, num_formats, IMGFMT_NV12); + MP_TARRAY_APPEND(p, p->formats, num_formats, IMGFMT_420P); + MP_TARRAY_APPEND(p, p->formats, num_formats, pixfmt2imgfmt(AV_PIX_FMT_NV16)); + MP_TARRAY_APPEND(p, p->formats, num_formats, IMGFMT_P010); +#ifdef AV_PIX_FMT_P210 + MP_TARRAY_APPEND(p, p->formats, num_formats, pixfmt2imgfmt(AV_PIX_FMT_P210)); +#endif + + for (int i = 0; i < MP_ARRAY_SIZE(forked_pix_fmt_names); i++) { + enum AVPixelFormat fmt = av_get_pix_fmt(forked_pix_fmt_names[i]); + if (fmt != AV_PIX_FMT_NONE) { + MP_TARRAY_APPEND(p, p->formats, num_formats, pixfmt2imgfmt(fmt)); + } + } + MP_TARRAY_APPEND(p, p->formats, num_formats, 0); // terminate it p->hwctx.hw_imgfmt = IMGFMT_DRMPRIME; @@ -165,7 +194,17 @@ static int mapper_init(struct ra_hwdec_mapper *mapper) struct dmabuf_interop_priv *p = mapper->priv; mapper->dst_params = mapper->src_params; - mapper->dst_params.imgfmt = mapper->src_params.hw_subfmt; + + /* + * rpi4_8 and rpi4_10 function identically to NV12. These two pixel + * formats however are not defined in upstream ffmpeg so a string + * comparison is used to identify them instead of a mpv IMGFMT. + */ + const char* fmt_name = mp_imgfmt_to_name(mapper->src_params.hw_subfmt); + if (strcmp(fmt_name, "rpi4_8") == 0 || strcmp(fmt_name, "rpi4_10") == 0) + mapper->dst_params.imgfmt = IMGFMT_NV12; + else + mapper->dst_params.imgfmt = mapper->src_params.hw_subfmt; mapper->dst_params.hw_subfmt = 0; struct ra_imgfmt_desc desc = {0}; @@ -234,7 +273,7 @@ static int mapper_map(struct ra_hwdec_mapper *mapper) } // We can handle composed formats if the total number of planes is still - // equal the number of planes we expect. Complex formats with auxilliary + // equal the number of planes we expect. Complex formats with auxiliary // planes cannot be supported. int num_returned_planes = 0; @@ -242,7 +281,7 @@ static int mapper_map(struct ra_hwdec_mapper *mapper) num_returned_planes += p->desc.layers[i].nb_planes; } - if (p->num_planes != num_returned_planes) { + if (p->num_planes != 0 && p->num_planes != num_returned_planes) { MP_ERR(mapper, "Mapped surface with format '%s' has unexpected number of planes. " "(%d layers and %d planes, but expected %d planes)\n", |