[PATCH 4/4] media: vicodec: make encoder CAPTURE dimensions read-only
Junrui Luo <[email protected]>
| Newsgroups | org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media,org.kernel.vger.stable |
|---|---|
| Message-ID | <[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