From 4078368104d147fe8d9a6131cb6226620ffcc6c8 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Fri, 1 May 2026 12:00:00 +0000 Subject: [PATCH] context: enable ANNEX_B start-code emission to match device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch 0002 sets V4L2_CID_STATELESS_H264_START_CODE to ANNEX_B on the device, telling the kernel that OUTPUT-buffer payloads will contain 0x00 0x00 0x01 NAL start codes. picture.c::codec_store_buffer has the prepend logic guarded by `if (context->h264_start_code)`, but that boolean is set ONLY inside h264_get_controls() — a function that exists but is never called. Result: device expects ANNEX_B, libva-v4l2-request feeds raw NAL payloads with no start codes, kernel cannot find slice boundaries, hantro emits a zeroed CAPTURE buffer. mpv reports successful decode because the V4L2 round-trip succeeds (no EINVAL); the visual output is a flat dark-green frame (NV12 zero through BT.709). Identified via: - Patch 0006 cleared the EINVAL cluster-rejection (128 → 0 on bbb_1080p30) but visual output remained flat green. - GStreamer reference (gstv4l2codech264dec.c:1363-1377) confirms start codes are required when ANNEX_B is selected. - Source-archaeology of fourier's picture.c:67-74 showed the gate on context->h264_start_code. Fix: in context.c::RequestCreateContext, immediately after patch 0002's device-control block, set context_object->h264_start_code = true to match the ANNEX_B mode we just programmed. Hardcoded for now (matches 0002's hardcoded set); replaced with a runtime probe in the planned probe-then-set commit. Signed-off-by: Markus Fritsche --- src/context.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/context.c b/src/context.c index 2c863c8..d959d1b 100644 --- a/src/context.c +++ b/src/context.c @@ -146,6 +146,23 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id, dev_ctrls, 2); } + /* + * Mirror the ANNEX_B start-code mode set on the device above + * into context_object->h264_start_code so picture.c:: + * codec_store_buffer prepends 0x00 0x00 0x01 to each slice + * payload it copies into the OUTPUT buffer. Without this, the + * kernel — which we just told to expect ANNEX_B — sees a raw + * NAL stream with no start codes, fails to find slice + * boundaries, and emits a zeroed CAPTURE buffer (visually a + * flat dark-green frame). + * + * h264_get_controls() exists for this purpose but is never + * called in the current code path; the planned probe-then-set + * commit will replace this hardcoded assignment with a runtime + * read of the kernel's accepted START_CODE value. + */ + context_object->h264_start_code = true; + rc = v4l2_set_stream(driver_data->video_fd, output_type, true); if (rc < 0) { status = VA_STATUS_ERROR_OPERATION_FAILED;