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