From 65b97331fb9894f910986e03ba3fd6fe46a7797f Mon Sep 17 00:00:00 2001 From: sofus Date: Sat, 12 Sep 2026 11:06:29 +0200 Subject: [PATCH] fixup! media: apple: avd: add a dedicated "submit" step Signed-off-by: sofus --- drivers/media/platform/apple/avd/avd-h264.c | 77 +++++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/apple/avd/avd-h264.c b/drivers/media/platform/apple/avd/avd-h264.c index 2db9bd660b74c1..7fe88c4483389c 100644 --- a/drivers/media/platform/apple/avd/avd-h264.c +++ b/drivers/media/platform/apple/avd/avd-h264.c @@ -29,9 +29,6 @@ #define H264_TRANSFORM_8X8_MODE(v) FIELD_PREP(BIT(7), !!(v)) -/* not a hardware constraint */ -#define MAX_SLICES 4096 - struct avd_h264_run { struct avd_run base; @@ -59,9 +56,10 @@ struct avd_h264_ctx { struct v4l2_h264_reference b1[V4L2_H264_REF_LIST_LEN]; } reflists; - struct avd_buf slices[MAX_SLICES]; + struct avd_buf *slices; struct avd_buf *active_slice; size_t slice_num; + size_t alloc_slice_num; struct avd_h264_bufs { struct avd_buf inst; @@ -605,6 +603,15 @@ static int avd_h264_start(struct avd_ctx *ctx) ctx->priv = h264_ctx; + /* assume one slice per row */ + h264_ctx->alloc_slice_num = + ctrl->p_new.p_h264_sps->pic_height_in_map_units_minus1 + 1; + h264_ctx->slices = + kzalloc(sizeof(*h264_ctx->slices) * h264_ctx->alloc_slice_num, + GFP_KERNEL); + if (!h264_ctx->slices) + goto err_free_ctx; + ret = avd_h264_alloc_bufs(ctx); if (ret) goto err_free_ctx; @@ -636,7 +643,7 @@ static void avd_h264_stop(struct avd_ctx *ctx) for (i = 0; i < h264_ctx->slice_num; i++) avd_buf_free(dev, &h264_ctx->slices[i]); - + kfree(h264_ctx->slices); kfree(h264_ctx); } @@ -671,6 +678,42 @@ static void avd_h264_run_preamble(struct avd_ctx *ctx, struct avd_h264_run *run) run->addresses.mv_color = run->base.y_out + (dst_len - mv_color_len); } +static int avd_h264_realloc_slices(struct avd_ctx *ctx) +{ + struct avd_h264_ctx *h264_ctx = ctx->priv; + void *tmp; + size_t alloc_slice_num; + + tmp = h264_ctx->slices; + alloc_slice_num = (h264_ctx->alloc_slice_num * 3) / 2; + h264_ctx->slices = kzalloc(sizeof(*h264_ctx->slices) * alloc_slice_num, + GFP_KERNEL); + if (!h264_ctx->slices) { + /* make deallocating a little easier */ + h264_ctx->slices = tmp; + return -ENOMEM; + } + + h264_ctx->alloc_slice_num = alloc_slice_num; + memcpy(h264_ctx->slices, tmp, + sizeof(*h264_ctx->slices) * h264_ctx->slice_num); + kfree(tmp); + + tmp = ctx->job.segments; + ctx->job.segments = kzalloc( + sizeof(*ctx->job.segments) * (alloc_slice_num + 1), GFP_KERNEL); + if (!ctx->job.segments) { + ctx->job.segments = tmp; + return -ENOMEM; + } + + memcpy(ctx->job.segments, tmp, + sizeof(*ctx->job.segments) * (ctx->job.num + 1)); + kfree(tmp); + + return 0; +} + static int avd_h264_run(struct avd_ctx *ctx) { struct avd_h264_ctx *h264_ctx = ctx->priv; @@ -679,11 +722,12 @@ static int avd_h264_run(struct avd_ctx *ctx) int ret; avd_h264_run_preamble(ctx, &run); - if (h264_ctx->slice_num >= MAX_SLICES) { - dev_err_ratelimited(ctx->dev->dev, - "slice_num > %d, stream was rejected!", - MAX_SLICES); - return -EINVAL; + + if (ctx->job.segments && + h264_ctx->slice_num >= h264_ctx->alloc_slice_num) { + ret = avd_h264_realloc_slices(ctx); + if (ret) + goto err_free_jobs; } struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); @@ -692,7 +736,7 @@ static int avd_h264_run(struct avd_ctx *ctx) h264_ctx->active_slice = &h264_ctx->slices[h264_ctx->slice_num]; ret = avd_buf_alloc(ctx->dev, h264_ctx->active_slice, payload_len); if (ret) - return ret; + goto err_free_jobs; memcpy(h264_ctx->active_slice->cpu, data, payload_len); h264_ctx->slice_num++; @@ -710,7 +754,8 @@ static int avd_h264_run(struct avd_ctx *ctx) avd_run_postamble(ctx, &run.base); if (is_new_frame(run.slice_params)) { - ret = avd_init_job(ctx, AVD_CODEC_H264, MAX_SLICES); + ret = avd_init_job(ctx, AVD_CODEC_H264, + h264_ctx->alloc_slice_num + 1); if (ret) return ret; stream_hdr(ctx, &run); @@ -728,6 +773,10 @@ static int avd_h264_run(struct avd_ctx *ctx) } return avd_submit_job(ctx); + +err_free_jobs: + kfree(ctx->job.segments); + return ret; } static void avd_h264_done(struct avd_ctx *ctx, struct vb2_v4l2_buffer *src_buf, @@ -738,9 +787,11 @@ static void avd_h264_done(struct avd_ctx *ctx, struct vb2_v4l2_buffer *src_buf, struct avd_h264_ctx *h264_ctx = ctx->priv; int i; - if (!(src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)) + if (!(src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)) { for (i = 0; i < h264_ctx->slice_num; i++) avd_buf_free(avd, &h264_ctx->slices[i]); + h264_ctx->slice_num = 0; + } } static enum avd_image_fmt avd_h264_get_image_fmt(struct avd_ctx *ctx,