av1: populate V4L2_CID_STATELESS_AV1_SEQUENCE in codec_set_controls
Implements the libva-side portion of issue #11 — replaces PR #10's no-op AV1 dispatch with a real av1_set_controls that maps VAAPI's VADecPictureParameterBufferAV1.seq_info_fields + scalar fields onto struct v4l2_ctrl_av1_sequence (the kernel uAPI control declared at linux/v4l2-controls.h:2891-2919). Daemon-track context (issue #11 daemon side, operator-owned): ffmpeg-vaapi splits the AV1 bitstream client-side and strips the OBU_SEQUENCE_HEADER before delivery; the V4L2 OUTPUT buffer contains only OBU_FRAME_HEADER + OBU_TILE_GROUP. libdav1d in the daedalus daemon cannot parse this — it expects a complete OBU stream. The daemon side has to synthesise OBU_SEQUENCE_HEADER from the SEQUENCE ctrl and prepend it to the slice bitstream. This libva-side change just makes the SEQUENCE ctrl populated and queued via S_EXT_CTRLS; the daemon track is the consumer. Three small touch points beyond the new src/av1.{c,h}: - src/surface.h: add an av1 leaf to surface->params holding VADecPictureParameterBufferAV1. Slice params intentionally absent — the daedalus daemon consumes the slice OBU bytes directly from the OUTPUT buffer; no per-tile-group struct → OBU re-synthesis required from libva today. - src/picture.c: copy the picture-param buffer into the new leaf in RenderPicture, mirror of the per-codec memcpy pattern, plus call av1_set_controls from codec_set_controls (replacing the no-op). - src/meson.build: register src/av1.c. Sequence-field mapping covers everything VAAPI exposes at the sequence level (12 of 18 V4L2_AV1_SEQUENCE_FLAG_* bits + the four scalars). Bits VAAPI doesn't carry at the sequence level (WARPED_MOTION, REF_FRAME_MVS, SUPERRES, RESTORATION, SEPARATE_UV_DELTA_Q) stay clear; per-frame consumers (libdav1d via the daemon, vpu981 via the hardware path) read those from the OBU_FRAME_HEADER that is already in the slice buffer anyway. See feedback memory `feedback_vaapi_blind_to_some_hevc_sps_fields` for the precedent. Build verified on higgs (Debian 13 trixie, gcc 14.2.0, libva 2.22.0, linux uAPI v4l2-controls.h sizeof(struct v4l2_ctrl_av1_sequence)==12): clean meson + ninja link of v4l2_request_drv_video.so, vainfo enumerates VAProfileAV1Profile0 via daedalus_v4l2 slot, av1_set_controls symbol present. Out of scope on this PR (operator-track, issue #11 follow-up): - daedalus-v4l2 kernel module wire-protocol extension (daedalus_ collect_av1_meta + AV1 ctrl request_setup). - daedalus daemon OBU synthesiser (~400 LoC AV1 OBU encoder in daemon/src/av1_obu_synth.{c,h}). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+21
-18
@@ -36,6 +36,7 @@
|
||||
#include "mpeg2.h"
|
||||
#include "vp8.h"
|
||||
#include "vp9.h"
|
||||
#include "av1.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -157,6 +158,12 @@ static VAStatus codec_store_buffer(struct request_data *driver_data,
|
||||
sizeof(surface_object->params.vp9.picture));
|
||||
break;
|
||||
|
||||
case VAProfileAV1Profile0:
|
||||
memcpy(&surface_object->params.av1.picture,
|
||||
buffer_object->data,
|
||||
sizeof(surface_object->params.av1.picture));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -320,26 +327,22 @@ static VAStatus codec_set_controls(struct request_data *driver_data,
|
||||
|
||||
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.
|
||||
* Populates V4L2_CID_STATELESS_AV1_SEQUENCE from
|
||||
* VAPictureParameterBufferAV1. The daedalus_v4l2 daemon
|
||||
* (issue #11 daemon track) synthesises an OBU_SEQUENCE_HEADER
|
||||
* from this ctrl and prepends it to the slice bitstream
|
||||
* before handing it to libavcodec/libdav1d, which otherwise
|
||||
* cannot parse the (sequence-header-stripped) OUTPUT buffer
|
||||
* that ffmpeg-vaapi delivers.
|
||||
*
|
||||
* 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(...).
|
||||
* On the RK3588 vpu981 hardware path the same SEQUENCE ctrl
|
||||
* is harmless: vpu981's driver parses the OBU stream
|
||||
* directly and ignores the ctrl payload, so no per-decoder
|
||||
* gating is required here.
|
||||
*/
|
||||
rc = av1_set_controls(driver_data, context, surface_object);
|
||||
if (rc < 0)
|
||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user