iter15 α-19: explicit VIDIOC_S_FMT on CAPTURE side for rkvdec correctness
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) <noreply@anthropic.com>
This commit is contained in:
+36
-8
@@ -29,6 +29,7 @@
|
||||
#include "request.h"
|
||||
#include "surface.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user