From 96d70af6748e88d18fd2e9bd2d445967f488102c Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Wed, 20 May 2026 20:58:57 +0200 Subject: [PATCH] picture: no-op codec_set_controls case for VAProfileAV1Profile0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit picture.c's codec_set_controls() switch was falling through to the default case for VAProfileAV1Profile0, returning VA_STATUS_ERROR_UNSUPPORTED_PROFILE. Result: vaEndPicture failed with status 12 ("requested VAProfile is not supported"), no OUTPUT buffer ever got queued, and the daedalus_v4l2 daemon never saw a REQ_DECODE for AV1. config.c's VAProfileAV1Profile0 case (line 84-93) explicitly notes "Decode-side ctrl dispatch (V4L2_CID_STATELESS_AV1_*) is NOT YET WIRED on master — vainfo will list the profile + CreateConfig succeeds, but consumers that submit decode buffers hit a NOP path". The NOP path was never actually wired in picture.c — it hit the default UNSUPPORTED_PROFILE branch instead. Fix: add a VAProfileAV1Profile0 case that just `break;`s through without setting V4L2 controls. For the daedalus_v4l2 daemon path this is exactly the right shape — AV1 frame data is self-describing per OBU stream (no separate SPS/PPS controls needed at the V4L2 boundary), so the OUTPUT buffer alone is sufficient for the kernel to forward to the daemon. Verified on higgs: ffmpeg -hwaccel vaapi -i av1.mkv now actually queues frames to /dev/video2 and the daemon's libdav1d context opens. Decode itself still fails (libdav1d wants the AV1 sequence header OBU, which ffmpeg-vaapi sends via VAPictureParameterBufferAV1 not via the slice buffer) — separate issue, needs an OBU sequence-header synthesiser in the daedalus daemon (analogous to the new H.264 SPS/PPS NAL synth in daedalus-v4l2/daemon/src/h264_nal_synth.c). That sequence-header synth work is a substantial follow-up; this patch unblocks AV1 reaching the daemon at all. For RK3588 vpu981 (the originally-planned AV1 target), this remains a true NO-OP — when V4L2_CID_STATELESS_AV1_* dispatch lands from the av1-iter1 operator branch, replace the no-op with av1_set_controls(...). Co-Authored-By: Claude Opus 4.7 --- src/picture.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/picture.c b/src/picture.c index 693ae45..31d9e57 100644 --- a/src/picture.c +++ b/src/picture.c @@ -318,6 +318,30 @@ static VAStatus codec_set_controls(struct request_data *driver_data, return VA_STATUS_ERROR_OPERATION_FAILED; break; + case VAProfileAV1Profile0: + /* + * AV1 has no codec-specific V4L2 control dispatch wired up + * yet on this branch (see config.c VAProfileAV1Profile0 + * comment). For the daedalus_v4l2 daemon path that's fine: + * AV1 frames are self-describing per-frame (OBU sequence + + * frame headers carry everything libavcodec needs), so the + * bitstream in the V4L2 OUTPUT buffer is sufficient — no + * V4L2_CID_STATELESS_AV1_* controls have to be populated. + * + * Per-codec dispatch in request_switch_device_for_profile + * has already retargeted (video_fd, media_fd) to + * video_fd_daedalus (or video_fd_vpu981 on RK3588 if + * present) by the time we get here; the OUTPUT buffer will + * be queued via that fd and the kernel forwards bytes to + * the daemon as a regular REQ_DECODE. No-op is the + * correct shape. + * + * When the vpu981-targeted V4L2_CID_STATELESS_AV1_* dispatch + * lands from the av1-iter1 operator branch, replace this + * with av1_set_controls(...). + */ + break; + default: return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; }