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);