The real multiplanar wedge: probe MPLANE in surface.c, add NV12 mplane
This is what was actually broken — and it's much smaller than the STUDY
guessed.
The library is in fact multiplanar-aware throughout the v4l2.c helpers
(v4l2_setup_format, v4l2_get_format, v4l2_query_buffer, v4l2_queue_buffer,
v4l2_dequeue_buffer all branch on v4l2_type_is_mplane). The whole
"context.c / picture.c are single-plane" hypothesis from STUDY.md was wrong —
they derive output_type and capture_type from
video_format->v4l2_mplane and pass them through.
The bug is upstream of all that: driver_data->video_format is set in
RequestCreateSurfaces only, and the probe there only tries
V4L2_BUF_TYPE_VIDEO_CAPTURE (single-plane). On hantro the single-plane
ENUM_FMT returns nothing, video_format stays NULL, and every subsequent
operation hits the `if (video_format == NULL) return OPERATION_FAILED`
guard at the top of context.c / buffer.c / image.c. That's exactly what
Brave's vaCreateContext failure was — not a downstream multiplanar fault,
just the format-detection short-circuit firing.
Three small changes:
- src/video.c: add an NV12 multi-plane entry next to the existing
single-plane NV12 / Sunxi entries. Same pixelformat fourcc (S264 vs NV12
has nothing to do with mplane), distinguished by the v4l2_mplane bit.
- src/video.h + src/video.c: video_format_find() takes a `bool mplane`
parameter and matches both fields. Without this the single-plane and
multi-plane NV12 entries collide on pixelformat.
- src/surface.c: the probe block now tries V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
as a fallback after the single-plane probes return nothing. On a
single-plane decoder the mplane probe is a no-op; on hantro it picks
the new mplane NV12 entry, video_format gets set, and the rest of the
library — already mplane-aware — does the right thing for OUTPUT
S_FMT, REQBUFS, EXPBUF, QBUF, DQBUF.
Also: src/context.c: the H264 case still referenced V4L2_PIX_FMT_H264_SLICE_RAW
that we renamed in commit c1f5108. Caught now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -104,7 +104,7 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
||||
case VAProfileH264ConstrainedBaseline:
|
||||
case VAProfileH264MultiviewHigh:
|
||||
case VAProfileH264StereoHigh:
|
||||
pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW;
|
||||
pixelformat = V4L2_PIX_FMT_H264_SLICE;
|
||||
break;
|
||||
|
||||
case VAProfileHEVCMain:
|
||||
|
||||
+18
-6
@@ -73,17 +73,29 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
||||
|
||||
|
||||
if (!driver_data->video_format) {
|
||||
/* Single-plane CAPTURE first (the original sunxi-cedrus path) */
|
||||
found = v4l2_find_format(driver_data->video_fd,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
||||
if (found)
|
||||
video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
||||
video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12, false);
|
||||
|
||||
found = v4l2_find_format(driver_data->video_fd,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_PIX_FMT_NV12);
|
||||
if (found)
|
||||
video_format = video_format_find(V4L2_PIX_FMT_NV12);
|
||||
if (video_format == NULL) {
|
||||
found = v4l2_find_format(driver_data->video_fd,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_PIX_FMT_NV12);
|
||||
if (found)
|
||||
video_format = video_format_find(V4L2_PIX_FMT_NV12, false);
|
||||
}
|
||||
|
||||
/* Multi-plane CAPTURE fallback (Rockchip hantro / RK3588 VDPU381) */
|
||||
if (video_format == NULL) {
|
||||
found = v4l2_find_format(driver_data->video_fd,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
||||
V4L2_PIX_FMT_NV12);
|
||||
if (found)
|
||||
video_format = video_format_find(V4L2_PIX_FMT_NV12, true);
|
||||
}
|
||||
|
||||
if (video_format == NULL)
|
||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||
|
||||
+13
-2
@@ -45,6 +45,16 @@ static struct video_format formats[] = {
|
||||
.planes_count = 2,
|
||||
.bpp = 16,
|
||||
},
|
||||
{
|
||||
.description = "NV12 YUV (multi-plane)",
|
||||
.v4l2_format = V4L2_PIX_FMT_NV12,
|
||||
.v4l2_buffers_count = 1,
|
||||
.v4l2_mplane = true,
|
||||
.drm_format = DRM_FORMAT_NV12,
|
||||
.drm_modifier = DRM_FORMAT_MOD_NONE,
|
||||
.planes_count = 2,
|
||||
.bpp = 16,
|
||||
},
|
||||
{
|
||||
.description = "Sunxi tiled NV12 YUV",
|
||||
.v4l2_format = V4L2_PIX_FMT_SUNXI_TILED_NV12,
|
||||
@@ -59,12 +69,13 @@ static struct video_format formats[] = {
|
||||
|
||||
static unsigned int formats_count = sizeof(formats) / sizeof(formats[0]);
|
||||
|
||||
struct video_format *video_format_find(unsigned int pixelformat)
|
||||
struct video_format *video_format_find(unsigned int pixelformat, bool mplane)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < formats_count; i++)
|
||||
if (formats[i].v4l2_format == pixelformat)
|
||||
if (formats[i].v4l2_format == pixelformat &&
|
||||
formats[i].v4l2_mplane == mplane)
|
||||
return &formats[i];
|
||||
|
||||
return NULL;
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ struct video_format {
|
||||
unsigned int bpp;
|
||||
};
|
||||
|
||||
struct video_format *video_format_find(unsigned int pixelformat);
|
||||
struct video_format *video_format_find(unsigned int pixelformat, bool mplane);
|
||||
bool video_format_is_linear(struct video_format *format);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user