From 69a62a922f3cc0546cc187e9a728104674acde42 Mon Sep 17 00:00:00 2001 From: claude-noether Date: Thu, 21 May 2026 11:01:41 +0200 Subject: [PATCH] kernel: register H.264 DECODE_MODE + START_CODE menu controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libva-v4l2-request sets V4L2_CID_STATELESS_H264_DECODE_MODE and V4L2_CID_STATELESS_H264_START_CODE on the device fd at context init (see libva-v4l2-request-fourier src/context.c:577 — best-effort call, result is (void)cast). Our ctrl_handler did not advertise either control, so v4l2-core returned EINVAL on validate; userspace logged the noisy v4l2-request: Unable to set control(s): Invalid argument (error_idx=2/2 ioctl-level) at every Firefox/ffmpeg context creation, despite decode itself succeeding (the daemon already operates as FRAME_BASED + ANNEX_B and the per-request SPS/PPS/SCALING_MATRIX/DECODE_PARAMS batch lands fine). Register the two as v4l2_ctrl_new_std_menu with the only value each the daemon actually supports — FRAME_BASED for DECODE_MODE, ANNEX_B for START_CODE — and mask out the unsupported alternates (SLICE_BASED, NONE). Pattern matches rkvdec / hantro. Update the handler-init capacity hint to ARRAY_SIZE(daedalus_stateless_ctrls) + 2 to cover the additions. Verified: builds clean on 6.18.29+rpt-rpi-2712 (Pi CM5) DKMS source tree. --- kernel/daedalus_v4l2_main.c | 43 ++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/kernel/daedalus_v4l2_main.c b/kernel/daedalus_v4l2_main.c index 6eb021a..61fc312 100644 --- a/kernel/daedalus_v4l2_main.c +++ b/kernel/daedalus_v4l2_main.c @@ -287,6 +287,44 @@ static int daedalus_register_stateless_ctrls(struct v4l2_ctrl_handler *hdl) } (void) ctrl; } + + /* + * Device-wide H.264 mode controls. libva-v4l2-request sets these + * on the device fd (request_fd=-1) at context init via + * VIDIOC_S_EXT_CTRLS before any per-request controls are bound; + * without entries on our ctrl_handler v4l2-core returns EINVAL + * and userspace logs a noisy "Unable to set control(s)" warning + * (cosmetic — libva already treats this as best-effort). Expose + * the single value each that the daemon actually accepts: + * + * DECODE_MODE: FRAME_BASED only — the daemon receives a full + * frame's worth of slice data per REQ_DECODE and calls + * avcodec_send_packet / avcodec_receive_frame once per + * submission; partial-slice (SLICE_BASED) decode is not + * wired into the daemon pipeline. + * START_CODE: ANNEX_B only — the daemon's H.264 SPS/PPS + * synthesiser prepends 0x00000001-delimited NAL units + * (Annex B); a NONE start-code variant would need a + * separate emit path. + * + * Pattern matches rkvdec / hantro (skip_mask = BIT(unsupported)). + */ + v4l2_ctrl_new_std_menu(hdl, &daedalus_ctrl_ops, + V4L2_CID_STATELESS_H264_DECODE_MODE, + V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, + BIT(V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED), + V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED); + v4l2_ctrl_new_std_menu(hdl, &daedalus_ctrl_ops, + V4L2_CID_STATELESS_H264_START_CODE, + V4L2_STATELESS_H264_START_CODE_ANNEX_B, + BIT(V4L2_STATELESS_H264_START_CODE_NONE), + V4L2_STATELESS_H264_START_CODE_ANNEX_B); + if (hdl->error) { + pr_debug("daedalus_v4l2: H.264 menu ctrls registration err=%d\n", + hdl->error); + hdl->error = 0; + } + return 0; } @@ -1130,7 +1168,10 @@ static int daedalus_open(struct file *file) v4l2_fh_init(&ctx->fh, &dev->vdev); file->private_data = &ctx->fh; - v4l2_ctrl_handler_init(&ctx->hdl, ARRAY_SIZE(daedalus_stateless_ctrls)); + /* +2 covers the H.264 DECODE_MODE + START_CODE menu controls + * registered alongside daedalus_stateless_ctrls[]. */ + v4l2_ctrl_handler_init(&ctx->hdl, + ARRAY_SIZE(daedalus_stateless_ctrls) + 2); daedalus_register_stateless_ctrls(&ctx->hdl); /* * v4l2_ctrl_handler_setup runs s_ctrl for every registered