From 153eab9dd76cb76ab4d8f02d69da2acc8a7e5cd3 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Mon, 12 Oct 2026 12:45:13 +0200 Subject: [PATCH] media: apple: avd: allow more than 32 capture buffers per context The capture queue never sets max_num_buffers, so vb2 limits every context to VB2_MAX_FRAME (32) buffers. Nothing in the driver needs that limit: reference frames are looked up by timestamp (vb2_find_buffer()) and handed to the hardware by DMA address, never by buffer index. 32 buffers leave too little room for userspace to decode ahead. With a 16-frame DPB, four frame threads and the frames held for display, mpv's decoder queue (--vd-queue) gets only a few frames before VIDIOC_CREATE_BUFS fails with ENOBUFS, and the FFmpeg V4L2 request hwaccel then falls back to software decoding. Decoding ahead is needed because the t8103 AVD decodes 4K59.94 H.264 at only ~41 fps during a 125-156 Mbit/s burst, so playback drops frames unless the decoder has built up a lead of 60-90 frames beforehand. Add a max_capture_buffers module parameter, default 128. Buffers are still allocated on demand by userspace, so this only raises the limit. Signed-off-by: Thomas Glanzmann --- drivers/media/platform/apple/avd/avd-drv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/platform/apple/avd/avd-drv.c b/drivers/media/platform/apple/avd/avd-drv.c index 8f7a9d99322b5..270ffb6996596 100644 --- a/drivers/media/platform/apple/avd/avd-drv.c +++ b/drivers/media/platform/apple/avd/avd-drv.c @@ -429,6 +429,17 @@ static void avd_device_run(void *priv) avd_job_finish(ctx, result); } +/* + * Capture buffers are found by timestamp and handed to the hardware by DMA + * address, so nothing limits them to VB2_MAX_FRAME. A larger pool lets + * userspace decode ahead to ride out bitrate spikes the hardware can't + * decode in real time (e.g. 150+ Mbit/s 4K60 H.264). + */ +static unsigned int max_capture_buffers = 128; +module_param(max_capture_buffers, uint, 0444); +MODULE_PARM_DESC(max_capture_buffers, + "Maximum number of capture buffers per context (default 128)"); + static int avd_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) { @@ -466,6 +477,7 @@ static int avd_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->lock = &ctx->dev->vdev_lock; dst_vq->dev = ctx->dev->v4l2_dev.dev; dst_vq->allow_cache_hints = true; + dst_vq->max_num_buffers = max(max_capture_buffers, VB2_MAX_FRAME); return vb2_queue_init(dst_vq); }