From de27e95571b67ef34619c23a12db4698f9b3454e Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Mon, 18 May 2026 18:14:50 +0000 Subject: [PATCH] v4l2: log error_idx + failing ctrl id on S_EXT_CTRLS failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Better diagnostic when VIDIOC_S_EXT_CTRLS returns < 0: read back error_idx and print which control id rejected (or "ioctl-level" when error_idx == count, meaning the rejection was generic, not per-control). Made it possible to triage the daedalus_v4l2 phase 8.13 issue by separating "the actual stateless control failed" (would show failing_ctrl_id=0xa40a2c VP9_FRAME) from "libva probing H264/HEVC profile/level we don't expose" (failing_ctrl_id= 0xa40900 H264_PROFILE etc.) — the latter is harmless on a VP9-only context. Before: v4l2-request: Unable to set control(s): Invalid argument After (per-control): v4l2-request: Unable to set control(s): Invalid argument (error_idx=0/2 failing_ctrl_id=0xa40900 size=0) After (ioctl-level): v4l2-request: Unable to set control(s): Invalid argument (error_idx=2/2 ioctl-level) Co-Authored-By: Claude Opus 4.7 (1M context) --- src/v4l2.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/v4l2.c b/src/v4l2.c index 9e2ce8b..27d9e61 100644 --- a/src/v4l2.c +++ b/src/v4l2.c @@ -476,12 +476,35 @@ int v4l2_set_controls(int video_fd, int request_fd, struct v4l2_ext_control *control_array, unsigned int num_controls) { + struct v4l2_ext_controls controls; int rc; - rc = v4l2_ioctl_controls(video_fd, request_fd, VIDIOC_S_EXT_CTRLS, - control_array, num_controls); + memset(&controls, 0, sizeof(controls)); + controls.controls = control_array; + controls.count = num_controls; + if (request_fd >= 0) { + controls.which = V4L2_CTRL_WHICH_REQUEST_VAL; + controls.request_fd = request_fd; + } + + rc = ioctl(video_fd, VIDIOC_S_EXT_CTRLS, &controls); if (rc < 0) { - request_log("Unable to set control(s): %s\n", strerror(errno)); + /* error_idx is the index of the first failing control; + * if it equals count, the ioctl itself failed (not a + * specific control payload). Useful for triaging + * which V4L2_CID_STATELESS_* the kernel rejected. */ + if (controls.error_idx < num_controls) + request_log("Unable to set control(s): %s " + "(error_idx=%u/%u failing_ctrl_id=0x%x size=%u)\n", + strerror(errno), + controls.error_idx, controls.count, + control_array[controls.error_idx].id, + control_array[controls.error_idx].size); + else + request_log("Unable to set control(s): %s " + "(error_idx=%u/%u ioctl-level)\n", + strerror(errno), + controls.error_idx, controls.count); return -1; }