On Sat Aug 15 22:56:38 2026 +0800, Junrui Luo wrote:
> 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]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
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 ff9d50fb05fd..25ec3a43fc71 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;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]