[PATCH 4/4] media: vicodec: make encoder CAPTURE dimensions read-only
Junrui Luo via B4 Relay <[email protected]>
| Newsgroups | org.kernel.vger.linux-media,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Junrui Luo <[email protected]> Setting the encoder's compressed CAPTURE format to a smaller resolution than the raw OUTPUT format makes the encoder write past the end of the CAPTURE buffer. For a stateful encoder the CAPTURE width and height are not client-settable; Documentation/userspace-api/media/v4l/dev-encoder.rst specifies them as "ignored (read-only)" on VIDIOC_S_FMT. vicodec only implements half of that: vidioc_s_fmt_vid_out() derives the CAPTURE coded size and sizeimage from the OUTPUT format, but S_FMT on the CAPTURE queue overwrites them. The encoder then takes its geometry from the OUTPUT queue alone, and v4l2_fwht_encode() gets no destination length. Overwrite the requested width and height with the OUTPUT queue's coded dimensions in vidioc_try_fmt_vid_cap(), making them read-only as the interface requires. Fixes: efec9c815e5d ("media: vicodec: pass on enc output format to capture side") Reported-by: Yuhao Jiang <[email protected]> Assisted-by: Claude:claude-opus-5 Cc: [email protected] Signed-off-by: Junrui Luo <[email protected]> --- drivers/media/test-drivers/vicodec/vicodec-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c index 36b92f68ac42..6d20a749635c 100644 --- a/drivers/media/test-drivers/vicodec/vicodec-core.c +++ b/drivers/media/test-drivers/vicodec/vicodec-core.c @@ -890,6 +890,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct vicodec_ctx *ctx = file2ctx(file); + struct vicodec_q_data *q_data_out = + get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); struct v4l2_pix_format_mplane *pix_mp; struct v4l2_pix_format *pix; @@ -900,6 +902,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, pix = &f->fmt.pix; pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT : find_fmt(f->fmt.pix.pixelformat)->id; + if (ctx->is_enc) { + pix->width = q_data_out->coded_width; + pix->height = q_data_out->coded_height; + } pix->colorspace = ctx->state.colorspace; pix->xfer_func = ctx->state.xfer_func; pix->ycbcr_enc = ctx->state.ycbcr_enc; @@ -911,6 +917,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, pix_mp = &f->fmt.pix_mp; pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT : find_fmt(pix_mp->pixelformat)->id; + if (ctx->is_enc) { + pix_mp->width = q_data_out->coded_width; + pix_mp->height = q_data_out->coded_height; + } pix_mp->colorspace = ctx->state.colorspace; pix_mp->xfer_func = ctx->state.xfer_func; pix_mp->ycbcr_enc = ctx->state.ycbcr_enc; -- 2.51.2