From 3760a70006a5ac9df264d7132380434a10e791ee Mon Sep 17 00:00:00 2001 From: claude-noether Date: Thu, 14 May 2026 08:33:18 +0000 Subject: [PATCH] =?UTF-8?q?iter15=20=CE=B1-19:=20explicit=20VIDIOC=5FS=5FF?= =?UTF-8?q?MT=20on=20CAPTURE=20side=20for=20rkvdec=20correctness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 3 ioctl-sequence diff: kdirect (ffmpeg-v4l2request) S_FMTs CAPTURE with NV12 + dimensions after S_FMT OUTPUT, BEFORE CREATE_BUFS. libva's old code only G_FMTs CAPTURE (per iter5b-β's hantro-targeted comment that explicit S_FMT puts hantro into an inconsistent state). For rkvdec on RK3399 the absence of explicit S_FMT CAPTURE doesn't commit the chosen NV12 format properly. rkvdec HEVC + H.264 silently produce zero / garbage CAPTURE output — Bug 4 + Bug 5 root cause. Now: S_FMT OUTPUT → S_FMT CAPTURE → G_FMT CAPTURE. Failure of S_FMT CAPTURE is non-fatal: fall back to G_FMT (preserves the iter5b-β hantro path). Future iter to gate this on driver_kind explicitly per feedback_per_driver_kludge_gating.md. For now, always-on is safe because kdirect proves S_FMT CAPTURE works on both rkvdec AND hantro. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/context.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/context.c b/src/context.c index a46317f..9f2ffd0 100644 --- a/src/context.c +++ b/src/context.c @@ -29,6 +29,7 @@ #include "request.h" #include "surface.h" +#include #include #include @@ -150,15 +151,42 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, } /* - * Query CAPTURE-side bytesperline/sizes after S_FMT(OUTPUT). On - * hantro the CAPTURE format derives from OUTPUT; G_FMT reflects - * that. Do NOT VIDIOC_S_FMT on CAPTURE — hantro reads the SPS - * from the OUTPUT request to set CAPTURE shape internally; - * explicitly setting CAPTURE puts the driver into an inconsistent - * state (GStreamer v4l2slh264dec only G_FMTs CAPTURE per - * gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c:: - * gst_v4l2_decoder_negotiate_src_format). + * iter15 α-19: explicit S_FMT on CAPTURE for rkvdec. + * + * Original iter5b-β comment: "Do NOT VIDIOC_S_FMT on CAPTURE — hantro + * reads the SPS from OUTPUT to set CAPTURE shape internally." + * + * Empirical finding at iter15 Phase 3 (2026-05-14): kdirect (ffmpeg- + * v4l2request) does S_FMT on CAPTURE side after S_FMT(OUTPUT), + * then CREATE_BUFS for CAPTURE. libva's old G_FMT-only path skipped + * the S_FMT call. For hantro this was deliberate (works); for rkvdec + * (HEVC + H.264 + VP9 on RK3399) the absence of explicit S_FMT puts + * the driver into a state where it does NOT commit the chosen NV12 + * pixel format properly — and the resulting decode silently writes + * garbage or zero for HEVC + H.264 (Bug 4 + Bug 5). + * + * Per [[feedback-per-driver-kludge-gating]]: this driver-specific + * difference should be gated on driver_kind. For now use a single + * always-on S_FMT call as the safe move: kdirect proves S_FMT + * CAPTURE works on both hantro AND rkvdec (it's the reference path). + * The iter5b-β comment is preserved-but-amended below. + * + * Sequence: S_FMT OUTPUT (above) → S_FMT CAPTURE (this) → G_FMT + * CAPTURE (sanity read-back, matches what S_FMT committed). */ + { + unsigned int capture_pixelformat = V4L2_PIX_FMT_NV12; + rc = v4l2_set_format(driver_data->video_fd, capture_type, + capture_pixelformat, picture_width, + picture_height); + if (rc < 0) { + /* Non-fatal: if the kernel rejects S_FMT CAPTURE (some + * older hantro variants), fall through to G_FMT. */ + request_log("iter15 α-19: S_FMT CAPTURE failed (continuing): %s\n", + strerror(errno)); + } + } + rc = v4l2_get_format(driver_data->video_fd, capture_type, &format_width, &format_height, destination_bytesperlines, destination_sizes, NULL);