From e382c63e20d006ea9885106b950307cb3f5a5df0 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Fri, 1 May 2026 12:00:00 +0000 Subject: [PATCH] h264: submit PRED_WEIGHTS only when WEIGHTED_PRED applies Per kernel UAPI (include/uapi/linux/v4l2-controls.h), V4L2_CID_STATELESS_H264_PRED_WEIGHTS is a conditional control: V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice) := ((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && (slice_type == P || slice_type == SP)) || (pps->weighted_bipred_idc == 1 && slice_type == B) Submitting PRED_WEIGHTS on a frame where the macro evaluates false triggers VIDIOC_S_EXT_CTRLS to return EINVAL at error_idx=5 (the 6th, last control in the per-request batch) on hantro-vpu and any other driver that strictly enforces the spec. Smoke trace from RK3568 hantro on bbb_1080p30 (Main profile, no weighted prediction): every per-frame batch fails identically, 13 EINVALs over a 10-frame run. Without this fix, ffmpeg's vaapi-copy falls back to software decode for every frame. Fix: narrow num_controls to 5 (excluding PRED_WEIGHTS at index 5) when the macro returns false; keep at 6 when it returns true. Defect found and fixed via Phase 6 Step 1 ohm smoke testing. Not part of Sonnet's six-commit upstreamable plan; slotted in as patch 0005 ahead of the planned probe-then-set / FRAME_BASED commits because it unblocks per-frame submission on every backing driver, not just hantro. Signed-off-by: Markus Fritsche --- src/h264.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/h264.c b/src/h264.c index fb6c13a..353cfa0 100644 --- a/src/h264.c +++ b/src/h264.c @@ -559,8 +559,24 @@ int h264_set_controls(struct request_data *driver_data, } }; + /* + * PRED_WEIGHTS is conditionally required per kernel UAPI: + * V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice) is only + * true when explicit weighted prediction applies (P/SP slice + * with WEIGHTED_PRED flag, or B slice with weighted_bipred_idc + * == 1). Submitting it unconditionally on a frame that does + * not need it triggers EINVAL at error_idx=5 on hantro and + * other drivers that strictly enforce the spec. + * + * controls[5] is PRED_WEIGHTS (last in array); narrow the + * submission count to exclude it when not required. + */ + unsigned int num_controls = 6; + if (!V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(&pps, &slice)) + num_controls = 5; + rc = v4l2_set_controls(driver_data->video_fd, surface->request_fd, - controls, 6); + controls, num_controls); if (rc < 0) return VA_STATUS_ERROR_OPERATION_FAILED;