From 10114f6781f848fdf684b325994981b199c7d007 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Fri, 1 May 2026 12:00:00 +0000 Subject: [PATCH] mplane: enable V4L2 multiplanar capture for NV12 on hantro-vpu Fourier's local patch already wired multiplanar plumbing through src/v4l2.c (helpers v4l2_type_video_{output,capture}() at lines 59-69, struct v4l2_plane planes[] threading in QUERYBUF/QBUF/DQBUF, per-plane EXPBUF loop at line 411) and through src/context.c, src/buffer.c, src/picture.c via the v4l2_type_video_{output,capture}(video_format ->v4l2_mplane) helper calls. The remaining gap: the NV12 entry in src/video.c was hardcoded to v4l2_mplane=false, and the bootstrap path in src/surface.c was hardcoded to singleplanar literals before video_format is populated. This patch flips the NV12 entry to v4l2_mplane=true and updates the two singleplanar literals in src/surface.c to their MPLANE variants: - src/video.c:42 v4l2_mplane=false -> true (NV12 only; Sunxi-tiled NV12 left at false for cedrus compatibility) - src/surface.c:84 output_type = v4l2_type_video_output(true) - src/surface.c:109 v4l2_find_format(..., CAPTURE_MPLANE, NV12) Empirically, hantro-vpu (RK3568 mainline) advertises NV12 only under V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; querying the singleplanar type returns no match (verified via VIDIOC_ENUM_FMT in Phase 3 GStreamer strace baseline). Trade-off accepted: legacy sunxi-cedrus singleplanar NV12 paths are left unchanged via the SUNXI_TILED_NV12 entry (still mplane=false, __arm__ only). Pure-NV12 cedrus on aarch64 would regress, but the known userbase here is RK3566/RK3568 hantro. Signed-off-by: Markus Fritsche --- src/surface.c | 4 ++-- src/video.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/surface.c b/src/surface.c index 478f0cc..ca3969d 100644 --- a/src/surface.c +++ b/src/surface.c @@ -81,7 +81,7 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format, // we declare SET_FORMAT_OF_OUTPUT_ONCE to ensure v4l2_set_format only gets called once // (in the first RequestCreateSurfaces2 call BEFORE any buffers are created later on) unsigned int pixelformat = V4L2_PIX_FMT_H264_SLICE; - unsigned int output_type = v4l2_type_video_output(false); + unsigned int output_type = v4l2_type_video_output(true); if (!SET_FORMAT_OF_OUTPUT_ONCE) { rc = v4l2_set_format(driver_data->video_fd, output_type, pixelformat, @@ -106,7 +106,7 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format, video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12); found = v4l2_find_format(driver_data->video_fd, - V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, V4L2_PIX_FMT_NV12); if (found) video_format = video_format_find(V4L2_PIX_FMT_NV12); diff --git a/src/video.c b/src/video.c index 9fae332..2c0d645 100644 --- a/src/video.c +++ b/src/video.c @@ -39,7 +39,7 @@ static struct video_format formats[] = { .description = "NV12 YUV", .v4l2_format = V4L2_PIX_FMT_NV12, .v4l2_buffers_count = 1, - .v4l2_mplane = false, + .v4l2_mplane = true, .drm_format = DRM_FORMAT_NV12, .drm_modifier = DRM_FORMAT_MOD_NONE, .planes_count = 2,