From b8518619310fbfc632a3400b4789f860f12d73a9 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Mon, 18 May 2026 19:01:29 +0000 Subject: [PATCH] debian/mpv-fourier: new package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror of arch/mpv-fourier into the Debian tree. Same source pin (mpv 0.41.0), same 3 patches: - 0001-meson-add-detection-logic-for-v4l2request-support.patch - 0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch (Kwiboo + Langdale wiring for AV_HWDEVICE_TYPE_V4L2REQUEST through drmprime VO hwdec — '--hwdec=v4l2request' actually engages on dmabuf-wayland) - 0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch (iter1 of dmabuf-modifier-triage — explicit DMA_BUF_IOCTL_SYNC on import fds; KWin-on-RK3566 dark-green chroma readback regression fix on ohm. Root cause is the vb2_dma_resv RFC upstream still pending.) Depends on ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier) — AV_HWDEVICE_TYPE_V4L2REQUEST only exists in Kwiboo's FFmpeg fork; stock Debian ffmpeg doesn't have it. Conflicts/Replaces stock mpv + libmpv2/libmpv1 — drop-in replacement. Takes epoch 1. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...ection-logic-for-v4l2request-support.patch | 56 +++ ...and-explicit-cache-sync-on-import-fd.patch | 81 ++++ ...e-add-separate-hwdecs-for-v4l2reques.patch | 435 ++++++++++++++++++ debian/mpv-fourier/build-deb.sh | 134 ++++++ debian/mpv-fourier/debian/changelog | 12 + debian/mpv-fourier/debian/control | 70 +++ debian/mpv-fourier/debian/copyright | 25 + 7 files changed, 813 insertions(+) create mode 100644 debian/mpv-fourier/0001-meson-add-detection-logic-for-v4l2request-support.patch create mode 100644 debian/mpv-fourier/0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch create mode 100644 debian/mpv-fourier/0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch create mode 100755 debian/mpv-fourier/build-deb.sh create mode 100644 debian/mpv-fourier/debian/changelog create mode 100644 debian/mpv-fourier/debian/control create mode 100644 debian/mpv-fourier/debian/copyright diff --git a/debian/mpv-fourier/0001-meson-add-detection-logic-for-v4l2request-support.patch b/debian/mpv-fourier/0001-meson-add-detection-logic-for-v4l2request-support.patch new file mode 100644 index 000000000..ef2391faf --- /dev/null +++ b/debian/mpv-fourier/0001-meson-add-detection-logic-for-v4l2request-support.patch @@ -0,0 +1,56 @@ +From 9d3bbd3651eb8405b8609e4f5e8c4978056483d0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 18 Aug 2024 17:42:14 -0700 +Subject: [PATCH 1/2] meson: add detection logic for v4l2request support + +We will probably adjust this to look for a specific libavutil version after +v4l2request support is merged upstream, but this check is fine for now. +--- + meson.build | 11 +++++++++++ + meson.options | 1 + + 2 files changed, 12 insertions(+) + +diff --git a/meson.build b/meson.build +index d4c75a907f..540f279dc7 100644 +--- a/meson.build ++++ b/meson.build +@@ -1444,6 +1444,16 @@ if features['ios-gl'] + sources += files('video/out/hwdec/hwdec_ios_gl.m') + endif + ++v4l2request = get_option('v4l2request').require( ++ cc.has_header_symbol('libavutil/hwcontext.h', ++ 'AV_HWDEVICE_TYPE_V4L2REQUEST', ++ dependencies: libavutil) ++) ++features += {'v4l2request': v4l2request.allowed()} ++if features['v4l2request'] ++ sources += files('video/v4l2request.c') ++endif ++ + libva = dependency('libva', version: '>= 1.1.0', required: get_option('vaapi')) + + vaapi_drm = dependency('libva-drm', version: '>= 1.1.0', required: +@@ -1911,6 +1921,7 @@ summary({'cocoa': features['cocoa'] and features['swift'], + 'libmpv': get_option('libmpv'), + 'lua': features['lua'], + 'opengl': features['gl'], ++ 'v4l2request': features['v4l2request'], + 'vulkan': features['vulkan'], + 'wayland': features['wayland'], + 'x11': features['x11']}, +diff --git a/meson.options b/meson.options +index 836d16d03f..54ec2dccfc 100644 +--- a/meson.options ++++ b/meson.options +@@ -103,6 +103,7 @@ option('d3d-hwaccel', type: 'feature', value: 'auto', description: 'D3D11VA hwac + option('d3d9-hwaccel', type: 'feature', value: 'auto', description: 'DXVA2 hwaccel') + option('gl-dxinterop-d3d9', type: 'feature', value: 'auto', description: 'OpenGL/DirectX DXVA2 hwaccel') + option('ios-gl', type: 'feature', value: 'auto', description: 'iOS OpenGL ES interop support') ++option('v4l2request', type: 'feature', value: 'auto', description: 'V4L2 Request API hwaccel') + option('videotoolbox-gl', type: 'feature', value: 'auto', description: 'Videotoolbox with OpenGL') + option('videotoolbox-pl', type: 'feature', value: 'auto', description: 'Videotoolbox with libplacebo') + +-- +2.52.0 + diff --git a/debian/mpv-fourier/0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch b/debian/mpv-fourier/0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch new file mode 100644 index 000000000..85e820505 --- /dev/null +++ b/debian/mpv-fourier/0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Markus Fritsche +Date: Fri, 8 May 2026 23:30:00 +0000 +Subject: [PATCH] vo_dmabuf_wayland: explicit DMA_BUF_IOCTL_SYNC on import fds + +V4L2 does not attach implicit fences (dma_resv) to CAPTURE buffers +on VIDIOC_DQBUF. When the buffer is forwarded to a Wayland compositor +that imports it via wl_dmabuf and samples in the GPU, the GPU may +read from physical memory before the producer's writes have flushed, +producing all-zero output (manifests as solid green for BT.601 +limited-range YUV(0,0,0) -> RGB(0, 135, 0) on the consumer side). + +Issue an explicit DMA_BUF_IOCTL_SYNC(SYNC_START|SYNC_RW) + +SYNC_END(SYNC_RW) round-trip on each unique dma_buf fd before +zwp_linux_buffer_params_v1_add(). This invokes the producer driver's +dma_buf_ops->begin_cpu_access / end_cpu_access, which on most ARM +SoCs flushes write buffers and synchronizes coherent memory before +the compositor's GPU import. + +This is a userspace workaround. Root cause is the missing implicit +fence on V4L2 CAPTURE DQBUF and is being addressed upstream via +the vb2_dma_resv RFC. + +Without this patch, on RK3566 (hantro VPU + Mali-G52 panfrost + +KDE Plasma 6 / KWin 6.6.4), `mpv --hwdec=vaapi --vo=dmabuf-wayland` +shows solid green frames for all hardware-decoded content. With +this patch, decoded frames are presented correctly. + +Signed-off-by: Markus Fritsche +--- +diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c +index 6b7c511..16e3d18 100644 +--- a/video/out/vo_dmabuf_wayland.c ++++ b/video/out/vo_dmabuf_wayland.c +@@ -27,6 +27,12 @@ + #include + #endif + ++/* fourier patch: explicit dma_buf cache sync workaround for missing ++ * implicit-fence on V4L2 stateless CAPTURE buffers. Applies to both ++ * VAAPI and DRMPrime import paths. */ ++#include ++#include ++ + #include "gpu/hwdec.h" + #include "gpu/video.h" + #include "mpv_talloc.h" +@@ -205,6 +211,14 @@ static void vaapi_dmabuf_importer(struct buffer *buf, struct mp_image *src, + buf->drm_format = 0; + goto done; + } ++ /* fourier patch: explicit cache coherency sync on each dma_buf fd ++ * before submitting to the compositor. See top-of-file comment. */ ++ for (int obj_no = 0; obj_no < desc.num_objects; obj_no++) { ++ struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW }; ++ (void)ioctl(desc.objects[obj_no].fd, DMA_BUF_IOCTL_SYNC, &sync); ++ sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; ++ (void)ioctl(desc.objects[obj_no].fd, DMA_BUF_IOCTL_SYNC, &sync); ++ } + for (int plane_no = 0; plane_no < desc.layers[layer_no].num_planes; ++plane_no) { + int object = desc.layers[layer_no].object_index[plane_no]; + uint64_t modifier = desc.objects[object].drm_format_modifier; +@@ -258,6 +272,16 @@ static void drmprime_dmabuf_importer(struct buffer *buf, struct mp_image *src, + return; + + buf->id = drmprime_surface_id(src); ++ ++ /* fourier patch: explicit cache coherency sync on each dma_buf fd ++ * before submitting to the compositor. See top-of-file comment. */ ++ for (int obj_no = 0; obj_no < desc->nb_objects; obj_no++) { ++ struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW }; ++ (void)ioctl(desc->objects[obj_no].fd, DMA_BUF_IOCTL_SYNC, &sync); ++ sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; ++ (void)ioctl(desc->objects[obj_no].fd, DMA_BUF_IOCTL_SYNC, &sync); ++ } ++ + for (layer_no = 0; layer_no < desc->nb_layers; layer_no++) { + AVDRMLayerDescriptor layer = desc->layers[layer_no]; + +-- +2.51.0 diff --git a/debian/mpv-fourier/0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch b/debian/mpv-fourier/0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch new file mode 100644 index 000000000..53cd516fa --- /dev/null +++ b/debian/mpv-fourier/0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch @@ -0,0 +1,435 @@ +From dd1e1fd6fe884d66c49dc26af715e1423c7471a3 Mon Sep 17 00:00:00 2001 +From: Philip Langdale +Date: Sun, 18 Aug 2024 17:43:41 -0700 +Subject: [PATCH 2/2] vo: hwdec: drmprime: add separate hwdecs for v4l2request + +With all the machinery in place, we can now add the v4l2request hwdecs with a +different hw device type, and a different initialisation path. This applies to +both the drmprime and drmprime_overlay hwdecs. + +At the moment, the device initialisation is done in the bare minimum way, but +it can be extended to take a device path (for example) if that makes sense as +we better understand what meaningful configuration will be. + +Co-authored-by: Jonas Karlman +--- + video/hwdec.c | 3 + + video/hwdec.h | 1 + + video/out/gpu/hwdec.c | 6 ++ + video/out/hwdec/hwdec_drmprime.c | 125 +++++++++++++++++------ + video/out/hwdec/hwdec_drmprime_overlay.c | 81 +++++++++++++-- + video/out/vo_dmabuf_wayland.c | 1 + + video/v4l2request.c | 34 ++++++ + 7 files changed, 210 insertions(+), 41 deletions(-) + create mode 100644 video/v4l2request.c + +diff --git a/video/hwdec.c b/video/hwdec.c +index deba518e82..de2ffecc40 100644 +--- a/video/hwdec.c ++++ b/video/hwdec.c +@@ -125,6 +125,9 @@ static const struct hwcontext_fns *const hwcontext_fns[] = { + #if HAVE_DRM + &hwcontext_fns_drmprime, + #endif ++#if HAVE_V4L2REQUEST ++ &hwcontext_fns_v4l2request, ++#endif + #if HAVE_VAAPI + &hwcontext_fns_vaapi, + #endif +diff --git a/video/hwdec.h b/video/hwdec.h +index e7734e5d7e..bf337389cb 100644 +--- a/video/hwdec.h ++++ b/video/hwdec.h +@@ -119,6 +119,7 @@ extern const struct hwcontext_fns hwcontext_fns_cuda; + extern const struct hwcontext_fns hwcontext_fns_d3d11; + extern const struct hwcontext_fns hwcontext_fns_drmprime; + extern const struct hwcontext_fns hwcontext_fns_dxva2; ++extern const struct hwcontext_fns hwcontext_fns_v4l2request; + extern const struct hwcontext_fns hwcontext_fns_vaapi; + extern const struct hwcontext_fns hwcontext_fns_vdpau; + +diff --git a/video/out/gpu/hwdec.c b/video/out/gpu/hwdec.c +index be39c507d0..f50b927851 100644 +--- a/video/out/gpu/hwdec.c ++++ b/video/out/gpu/hwdec.c +@@ -38,6 +38,8 @@ extern const struct ra_hwdec_driver ra_hwdec_drmprime; + extern const struct ra_hwdec_driver ra_hwdec_drmprime_overlay; + extern const struct ra_hwdec_driver ra_hwdec_aimagereader; + extern const struct ra_hwdec_driver ra_hwdec_vulkan; ++extern const struct ra_hwdec_driver ra_hwdec_v4l2request; ++extern const struct ra_hwdec_driver ra_hwdec_v4l2request_overlay; + + const struct ra_hwdec_driver *const ra_hwdec_drivers[] = { + #if HAVE_D3D_HWACCEL +@@ -73,6 +75,10 @@ const struct ra_hwdec_driver *const ra_hwdec_drivers[] = { + &ra_hwdec_drmprime, + &ra_hwdec_drmprime_overlay, + #endif ++#if HAVE_V4L2REQUEST ++ &ra_hwdec_v4l2request, ++ &ra_hwdec_v4l2request_overlay, ++#endif + #if HAVE_ANDROID_MEDIA_NDK + &ra_hwdec_aimagereader, + #endif +diff --git a/video/out/hwdec/hwdec_drmprime.c b/video/out/hwdec/hwdec_drmprime.c +index 7869eb124a..446f63de44 100644 +--- a/video/out/hwdec/hwdec_drmprime.c ++++ b/video/out/hwdec/hwdec_drmprime.c +@@ -77,7 +77,7 @@ static const char *forked_pix_fmt_names[] = { + "rpi4_10", + }; + +-static int init(struct ra_hwdec *hw) ++static int pre_init(struct ra_hwdec *hw) + { + struct priv_owner *p = hw->priv; + +@@ -92,36 +92,12 @@ static int init(struct ra_hwdec *hw) + return -1; + } + +- /* +- * The drm_params resource is not provided when using X11 or Wayland, but +- * 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_ctx->ra, +- "drm_params_v2"); +- +- /* +- * Respect drm_device option, so there is a way to control this when not +- * using a DRM gpu context. If drm_params_v2 are present, they will already +- * respect this option. +- */ +- 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->device_path; +- +- const char *device_path = params && params->render_fd > -1 ? +- drmGetRenderDeviceNameFromFd(params->render_fd) : +- opt_path ? opt_path : "/dev/dri/renderD128"; +- MP_VERBOSE(hw, "Using DRM device: %s\n", device_path); ++ return 0; ++} + +- int ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, +- AV_HWDEVICE_TYPE_DRM, +- device_path, NULL, 0); +- talloc_free(tmp); +- if (ret != 0) { +- MP_VERBOSE(hw, "Failed to create hwdevice_ctx: %s\n", av_err2str(ret)); +- return -1; +- } ++static int post_init(struct ra_hwdec *hw) ++{ ++ struct priv_owner *p = hw->priv; + + /* + * At the moment, there is no way to discover compatible formats +@@ -154,6 +130,75 @@ static int init(struct ra_hwdec *hw) + return 0; + } + ++static int init_drmprime(struct ra_hwdec *hw) ++{ ++ struct priv_owner *p = hw->priv; ++ ++ int ret = pre_init(hw); ++ if (ret < 0) ++ return ret; ++ ++ /* ++ * The drm_params resource is not provided when using X11 or Wayland, but ++ * 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_ctx->ra, ++ "drm_params_v2"); ++ ++ /* ++ * Respect drm_device option, so there is a way to control this when not ++ * using a DRM gpu context. If drm_params_v2 are present, they will already ++ * respect this option. ++ */ ++ 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->device_path; ++ ++ const char *device_path = params && params->render_fd > -1 ? ++ drmGetRenderDeviceNameFromFd(params->render_fd) : ++ opt_path ? opt_path : "/dev/dri/renderD128"; ++ MP_VERBOSE(hw, "Using DRM device: %s\n", device_path); ++ ++ ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, ++ AV_HWDEVICE_TYPE_DRM, ++ device_path, NULL, 0); ++ talloc_free(tmp); ++ if (ret < 0) { ++ MP_VERBOSE(hw, "Failed to create hwdevice_ctx: %s\n", av_err2str(ret)); ++ return ret; ++ } ++ ++ return post_init(hw); ++} ++ ++#if HAVE_V4L2REQUEST ++static int init_v4l2request(struct ra_hwdec *hw) ++{ ++ struct priv_owner *p = hw->priv; ++ ++ int ret = pre_init(hw); ++ if (ret < 0) ++ return ret; ++ ++ /* ++ * AVCodecHWConfig contains a combo of a pixel format and hwdevice type, ++ * correct type must be created here or hwaccel will fail. ++ * ++ * FIXME: Create hwdevice based on type in AVCodecHWConfig ++ */ ++ ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, ++ AV_HWDEVICE_TYPE_V4L2REQUEST, ++ NULL, NULL, 0); ++ if (ret < 0) { ++ MP_VERBOSE(hw, "Failed to create hwdevice_ctx: %s\n", av_err2str(ret)); ++ return ret; ++ } ++ ++ return post_init(hw); ++} ++#endif ++ + static void mapper_unmap(struct ra_hwdec_mapper *mapper) + { + struct priv_owner *p_owner = mapper->owner->priv; +@@ -308,7 +353,7 @@ const struct ra_hwdec_driver ra_hwdec_drmprime = { + .priv_size = sizeof(struct priv_owner), + .imgfmts = {IMGFMT_DRMPRIME, 0}, + .device_type = AV_HWDEVICE_TYPE_DRM, +- .init = init, ++ .init = init_drmprime, + .uninit = uninit, + .mapper = &(const struct ra_hwdec_mapper_driver){ + .priv_size = sizeof(struct dmabuf_interop_priv), +@@ -318,3 +363,21 @@ const struct ra_hwdec_driver ra_hwdec_drmprime = { + .unmap = mapper_unmap, + }, + }; ++ ++#if HAVE_V4L2REQUEST ++const struct ra_hwdec_driver ra_hwdec_v4l2request = { ++ .name = "v4l2request", ++ .priv_size = sizeof(struct priv_owner), ++ .imgfmts = {IMGFMT_DRMPRIME, 0}, ++ .device_type = AV_HWDEVICE_TYPE_V4L2REQUEST, ++ .init = init_v4l2request, ++ .uninit = uninit, ++ .mapper = &(const struct ra_hwdec_mapper_driver){ ++ .priv_size = sizeof(struct dmabuf_interop_priv), ++ .init = mapper_init, ++ .uninit = mapper_uninit, ++ .map = mapper_map, ++ .unmap = mapper_unmap, ++ }, ++}; ++#endif +diff --git a/video/out/hwdec/hwdec_drmprime_overlay.c b/video/out/hwdec/hwdec_drmprime_overlay.c +index 61514f8e89..689e9b04e5 100644 +--- a/video/out/hwdec/hwdec_drmprime_overlay.c ++++ b/video/out/hwdec/hwdec_drmprime_overlay.c +@@ -246,7 +246,7 @@ static void uninit(struct ra_hwdec *hw) + } + } + +-static int init(struct ra_hwdec *hw) ++static int pre_init(struct ra_hwdec *hw) + { + struct priv *p = hw->priv; + int draw_plane, drmprime_video_plane; +@@ -267,15 +267,15 @@ static int init(struct ra_hwdec *hw) + drm_params->connector_id, draw_plane, drmprime_video_plane); + if (!p->ctx) { + mp_err(p->log, "Failed to retrieve DRM atomic context.\n"); +- goto err; ++ return -1; + } + if (!p->ctx->drmprime_video_plane) { + mp_warn(p->log, "No drmprime video plane. You might need to specify it manually using --drm-drmprime-video-plane\n"); +- goto err; ++ return -1; + } + } else { + mp_verbose(p->log, "Failed to retrieve DRM fd from native display.\n"); +- goto err; ++ return -1; + } + + drmModeCrtcPtr crtc; +@@ -289,7 +289,7 @@ static int init(struct ra_hwdec *hw) + uint64_t has_prime; + if (drmGetCap(p->ctx->fd, DRM_CAP_PRIME, &has_prime) < 0) { + MP_ERR(hw, "Card does not support prime handles.\n"); +- goto err; ++ return -1; + } + + if (has_prime) { +@@ -298,19 +298,67 @@ static int init(struct ra_hwdec *hw) + + disable_video_plane(hw); + ++ return 0; ++} ++ ++static int init_drmprime(struct ra_hwdec *hw) ++{ ++ struct priv *p = hw->priv; ++ ++ int ret = pre_init(hw); ++ if (ret < 0) ++ goto err; ++ + p->hwctx = (struct mp_hwdec_ctx) { + .driver_name = hw->driver->name, + .hw_imgfmt = IMGFMT_DRMPRIME, + }; + + char *device = drmGetDeviceNameFromFd2(p->ctx->fd); +- int ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, +- AV_HWDEVICE_TYPE_DRM, device, NULL, 0); ++ ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, ++ AV_HWDEVICE_TYPE_DRM, device, NULL, 0); + + if (device) + free(device); + +- if (ret != 0) { ++ if (ret < 0) { ++ MP_VERBOSE(hw, "Failed to create hwdevice_ctx: %s\n", av_err2str(ret)); ++ goto err; ++ } ++ ++ hwdec_devices_add(hw->devs, &p->hwctx); ++ ++ return 0; ++ ++err: ++ uninit(hw); ++ return ret; ++} ++ ++#if HAVE_V4L2REQUEST ++static int init_v4l2request(struct ra_hwdec *hw) ++{ ++ struct priv *p = hw->priv; ++ ++ int ret = pre_init(hw); ++ if (ret < 0) ++ goto err; ++ ++ p->hwctx = (struct mp_hwdec_ctx) { ++ .driver_name = hw->driver->name, ++ .hw_imgfmt = IMGFMT_DRMPRIME, ++ }; ++ ++ /* ++ * AVCodecHWConfig contains a combo of a pixel format and hwdevice type, ++ * correct type must be created here or hwaccel will fail. ++ * ++ * FIXME: Create hwdevice based on type in AVCodecHWConfig ++ */ ++ ret = av_hwdevice_ctx_create(&p->hwctx.av_device_ref, ++ AV_HWDEVICE_TYPE_V4L2REQUEST, ++ NULL, NULL, 0); ++ if (ret < 0) { + MP_VERBOSE(hw, "Failed to create hwdevice_ctx: %s\n", av_err2str(ret)); + goto err; + } +@@ -321,15 +369,28 @@ static int init(struct ra_hwdec *hw) + + err: + uninit(hw); +- return -1; ++ return ret; + } ++#endif + + const struct ra_hwdec_driver ra_hwdec_drmprime_overlay = { + .name = "drmprime-overlay", + .priv_size = sizeof(struct priv), + .imgfmts = {IMGFMT_DRMPRIME, 0}, + .device_type = AV_HWDEVICE_TYPE_DRM, +- .init = init, ++ .init = init_drmprime, ++ .overlay_frame = overlay_frame, ++ .uninit = uninit, ++}; ++ ++#if HAVE_V4L2REQUEST ++const struct ra_hwdec_driver ra_hwdec_v4l2request_overlay = { ++ .name = "v4l2request-overlay", ++ .priv_size = sizeof(struct priv), ++ .imgfmts = {IMGFMT_DRMPRIME, 0}, ++ .device_type = AV_HWDEVICE_TYPE_V4L2REQUEST, ++ .init = init_v4l2request, + .overlay_frame = overlay_frame, + .uninit = uninit, + }; ++#endif +diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c +index 9b06643544..6d62849568 100644 +--- a/video/out/vo_dmabuf_wayland.c ++++ b/video/out/vo_dmabuf_wayland.c +@@ -860,6 +860,7 @@ static int preinit(struct vo *vo) + // Initialize all possible hwdec drivers. + ra_hwdec_ctx_init(&p->hwdec_ctx, vo->hwdec_devs, "vaapi", false); + ra_hwdec_ctx_init(&p->hwdec_ctx, vo->hwdec_devs, "drmprime", false); ++ ra_hwdec_ctx_init(&p->hwdec_ctx, vo->hwdec_devs, "v4l2request", false); + + p->src = (struct mp_rect){0, 0, 0, 0}; + return 0; +diff --git a/video/v4l2request.c b/video/v4l2request.c +new file mode 100644 +index 0000000000..2aa4d14fea +--- /dev/null ++++ b/video/v4l2request.c +@@ -0,0 +1,34 @@ ++/* ++ * 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 . ++ */ ++ ++#include ++ ++#include "hwdec.h" ++ ++static struct AVBufferRef *v4l2request_create_standalone(struct mpv_global *global, ++ struct mp_log *log, struct hwcontext_create_dev_params *params) ++{ ++ AVBufferRef* ref = NULL; ++ av_hwdevice_ctx_create(&ref, AV_HWDEVICE_TYPE_V4L2REQUEST, NULL, NULL, 0); ++ ++ return ref; ++} ++ ++const struct hwcontext_fns hwcontext_fns_v4l2request = { ++ .av_hwdevice_type = AV_HWDEVICE_TYPE_V4L2REQUEST, ++ .create_dev = v4l2request_create_standalone, ++}; +-- +2.52.0 + diff --git a/debian/mpv-fourier/build-deb.sh b/debian/mpv-fourier/build-deb.sh new file mode 100755 index 000000000..c930aae01 --- /dev/null +++ b/debian/mpv-fourier/build-deb.sh @@ -0,0 +1,134 @@ +#!/bin/bash +# Build mpv-fourier__arm64.deb (mpv with v4l2request hwdec wiring + +# vo_dmabuf_wayland cache-sync fix). +# +# Mirror of arch/mpv-fourier into the Debian tree. Same source pin +# (mpv 0.41.0), same 3 patches, same meson options. +# +# Depends on ffmpeg-v4l2-request-fourier for the libavcodec backing +# library — the v4l2request hwdec mpv now offers requires +# AV_HWDEVICE_TYPE_V4L2REQUEST which only exists in Kwiboo's FFmpeg +# fork, not in Debian stock ffmpeg. +# +# Conflicts: mpv — drop-in replacement. Pi 5 / CM5 hosts using stock +# Firefox + VAAPI don't need this; the firefox-fourier / kdirect +# bench-test paths do. +# +# Sibling Arch package: ../../arch/mpv-fourier/PKGBUILD +# Sibling FFmpeg package: ../ffmpeg-v4l2-request-fourier/build-deb.sh +# Upstream: https://github.com/mpv-player/mpv +set -euo pipefail + +MPV_VERSION=0.41.0 +PKGVER=1:${MPV_VERSION}+rfourier +PKGREL=1 +MPV_TARBALL_SHA256=ee21092a5ee427353392360929dc64645c54479aefdb5babc5cfbb5fad626209 + +HERE=$(dirname "$(readlink -f "$0")") + +# Reproducible build. 2026-05-18 23:00 UTC — Phase 8.13 close. +export SOURCE_DATE_EPOCH=1779231600 + +work=$(mktemp -d) +trap "rm -rf $work" EXIT + +cd "$work" +curl -sSLfo mpv.tar.gz \ + "https://github.com/mpv-player/mpv/archive/v${MPV_VERSION}/mpv-${MPV_VERSION}.tar.gz" +echo "$MPV_TARBALL_SHA256 mpv.tar.gz" | sha256sum -c +tar xzf mpv.tar.gz + +cd "mpv-${MPV_VERSION}" + +# Apply the 3 fourier patches. +patch -p1 < "$HERE/0001-meson-add-detection-logic-for-v4l2request-support.patch" +patch -p1 < "$HERE/0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch" +patch -p1 < "$HERE/0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch" + +# Configure. Same shape as arch/mpv-fourier's meson options. +meson setup build \ + --prefix=/usr \ + --libdir=lib/aarch64-linux-gnu \ + --buildtype=release \ + --auto-features=auto \ + -Dv4l2request=enabled \ + -Dlibmpv=true \ + -Dgl-x11=enabled \ + -Dcaca=disabled \ + -Dcdda=enabled \ + -Ddrm=enabled \ + -Ddvbin=enabled \ + -Ddvdnav=enabled \ + -Dlibarchive=enabled \ + -Dopenal=enabled \ + -Dsdl2-audio=enabled \ + -Dsdl2-video=enabled \ + -Dsdl2-gamepad=enabled + +meson compile -C build -j"$(nproc)" + +# Stage +ROOT="$work/pkgroot" +DESTDIR="$ROOT" meson install -C build + +# Drop private linkage entries from the .pc (only matter for static linking). +sed -i -e '/Requires.private/d' -e '/Libs.private/d' \ + "$ROOT/usr/lib/aarch64-linux-gnu/pkgconfig/mpv.pc" + +# Docs +mkdir -p "$ROOT/usr/share/doc/mpv-fourier" "$ROOT/DEBIAN" +install -m 644 DOCS/encoding.rst "$ROOT/usr/share/doc/mpv-fourier/" +install -m 644 DOCS/tech-overview.txt "$ROOT/usr/share/doc/mpv-fourier/" +install -Dm644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/mpv-fourier/copyright" +install -Dm644 "$HERE/debian/changelog" "$ROOT/usr/share/doc/mpv-fourier/changelog.Debian" +gzip -9 -n "$ROOT/usr/share/doc/mpv-fourier/changelog.Debian" + +# TOOLS scripts +mkdir -p "$ROOT/usr/share/mpv/scripts" +install -m 644 TOOLS/umpv TOOLS/mpv_identify.sh TOOLS/stats-conv.py TOOLS/idet.sh \ + "$ROOT/usr/share/mpv/scripts/" 2>/dev/null || true +[ -d TOOLS/lua ] && cp TOOLS/lua/* "$ROOT/usr/share/mpv/scripts/" 2>/dev/null || true + +cat > "$ROOT/DEBIAN/control" <= 2:8.1+rfourier), + libc6, libdrm2, + libass9, libbluray2, libcdio19, libcdio-paranoia2, + libdvdnav4, libdvdread8, + libegl1, libgl1, libjpeg62-turbo | libjpeg62, + libplacebo338 | libplacebo208, + libpulse0, libsixel1, libluajit-5.1-2, + libmujs3 | libmujs2 | libmujs1, + libpipewire-0.3-0, librubberband2, libsdl2-2.0-0, + libopenal1, libuchardet0, libvulkan1, + libwayland-client0, libwayland-egl1, libwayland-cursor0, + libxkbcommon0, libxext6, libxpresent1, + libxrandr2, libxss1, libxv1, libx11-6, + zlib1g +Conflicts: mpv, libmpv2 | libmpv1 +Replaces: mpv, libmpv2, libmpv1 +Provides: mpv (= ${PKGVER}-${PKGREL}), libmpv.so.2 +Maintainer: Markus Fritsche +Homepage: https://mpv.io/ +Description: mpv media player with V4L2-Request hwdec (fourier fork) + mpv ${MPV_VERSION} patched with: + - Kwiboo + Langdale v4l2request hwdec wiring (meson detection + + vo_hwdec_drmprime separate hwdec instance for AV_HWDEVICE_TYPE_ + V4L2REQUEST) so '--hwdec=v4l2request' actually engages on + dmabuf-wayland. + - vo_dmabuf_wayland explicit DMA_BUF_IOCTL_SYNC on import fds + (iter1 of dmabuf-modifier-triage) — workaround for missing + implicit-fence on V4L2 stateless CAPTURE buffers. Fixes the + KWin-on-RK3566 dark-green chroma readback regression on ohm. + . + Requires ffmpeg-v4l2-request-fourier as the backing libavcodec. + Stock Debian ffmpeg does not provide AV_HWDEVICE_TYPE_V4L2REQUEST. +EOF + +DEB_OUT="mpv-fourier_${PKGVER//:/%3a}-${PKGREL}_arm64.deb" +dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT" +echo "built: $HERE/$DEB_OUT" diff --git a/debian/mpv-fourier/debian/changelog b/debian/mpv-fourier/debian/changelog new file mode 100644 index 000000000..f0709199e --- /dev/null +++ b/debian/mpv-fourier/debian/changelog @@ -0,0 +1,12 @@ +mpv-fourier (1:0.41.0+rfourier-1) bookworm trixie; urgency=medium + + * Initial Debian packaging for mpv with the fourier-umbrella patches. + * Mirror of arch/mpv-fourier (same source tarball pin 0.41.0, + same 3 patches: v4l2request meson detection, drmprime hwdec + wiring, vo_dmabuf_wayland explicit cache-sync). + * Depends on ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier) — the + v4l2request hwdec requires AV_HWDEVICE_TYPE_V4L2REQUEST which + only exists in Kwiboo's FFmpeg fork. + * Drop-in replacement for Debian's stock mpv; takes epoch 1. + + -- Markus Fritsche Mon, 18 May 2026 23:00:00 +0000 diff --git a/debian/mpv-fourier/debian/control b/debian/mpv-fourier/debian/control new file mode 100644 index 000000000..371335282 --- /dev/null +++ b/debian/mpv-fourier/debian/control @@ -0,0 +1,70 @@ +Source: mpv-fourier +Section: video +Priority: optional +Maintainer: Markus Fritsche +Build-Depends: debhelper-compat (= 13), + meson (>= 1.0), + ninja-build, + pkg-config, + python3-docutils, + ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier), + libdrm-dev, + libass-dev, + libbluray-dev, + libcdio-dev, + libcdio-paranoia-dev, + libdvdnav-dev, + libdvdread-dev, + libegl-dev, + libgl-dev, + libjpeg-dev, + libplacebo-dev, + libpulse-dev, + libsixel-dev, + libluajit-5.1-dev, + libmujs-dev, + libpipewire-0.3-dev, + librubberband-dev, + libsdl2-dev, + libopenal-dev, + libuchardet-dev, + libvulkan-dev, + libwayland-dev, + wayland-protocols, + libxkbcommon-dev, + libxext-dev, + libxpresent-dev, + libxrandr-dev, + libxss-dev, + libxv-dev, + libx11-dev, + libv4l-dev, + libudev-dev, + libsystemd-dev, + libarchive-dev, + libxml2-dev, + libdvbpsi-dev, + zlib1g-dev +Standards-Version: 4.6.2 +Homepage: https://mpv.io/ + +Package: mpv-fourier +Architecture: arm64 +Depends: ${misc:Depends}, ${shlibs:Depends}, + ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier) +Conflicts: mpv, libmpv2, libmpv1 +Replaces: mpv, libmpv2, libmpv1 +Provides: mpv (= ${binary:Version}), libmpv.so.2 +Description: mpv media player with V4L2-Request hwdec (fourier fork) + mpv 0.41.0 patched with: + - Kwiboo + Langdale v4l2request hwdec wiring (meson detection + + vo_hwdec_drmprime separate hwdec instance for AV_HWDEVICE_TYPE_ + V4L2REQUEST) so '--hwdec=v4l2request' actually engages on + dmabuf-wayland. + - vo_dmabuf_wayland explicit DMA_BUF_IOCTL_SYNC on import fds + (iter1 of dmabuf-modifier-triage) — workaround for missing + implicit-fence on V4L2 stateless CAPTURE buffers. Fixes the + KWin-on-RK3566 dark-green chroma readback regression on ohm. + . + Requires ffmpeg-v4l2-request-fourier as the backing libavcodec. + Stock Debian ffmpeg does not provide AV_HWDEVICE_TYPE_V4L2REQUEST. diff --git a/debian/mpv-fourier/debian/copyright b/debian/mpv-fourier/debian/copyright new file mode 100644 index 000000000..2e68d868c --- /dev/null +++ b/debian/mpv-fourier/debian/copyright @@ -0,0 +1,25 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: mpv +Upstream-Contact: https://github.com/mpv-player/mpv/issues +Source: https://github.com/mpv-player/mpv + +Files: * +Copyright: 2000-2026 The mpv developers +License: GPL-2.0-or-later AND LGPL-2.1-or-later + +Files: 0001-meson-add-detection-logic-for-v4l2request-support.patch + 0002-vo-hwdec-drmprime-add-separate-hwdecs-for-v4l2reques.patch +Copyright: 2024 Kwiboo, Niklas Haas, contributors +License: LGPL-2.1-or-later + +Files: 0001-vo_dmabuf_wayland-explicit-cache-sync-on-import-fd.patch +Copyright: 2026 Markus Fritsche +License: LGPL-2.1-or-later + +License: GPL-2.0-or-later + On Debian systems, the complete text of the GNU General Public + License v2 can be found in `/usr/share/common-licenses/GPL-2'. + +License: LGPL-2.1-or-later + On Debian systems, the complete text of the GNU Lesser General + Public License v2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.