media: coda: limit frame interval enumeration to supported encoder frame sizes
authorPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 26 Apr 2022 09:15:55 +0000 (11:15 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 13 May 2022 09:02:20 +0000 (11:02 +0200)
Let VIDIOC_ENUM_FRAMEINTERVALS return -EINVAL if userspace queries
frame intervals for frame sizes unsupported by the encoder. Fixes the
following v4l2-compliance failure:

fail: v4l2-test-formats.cpp(123): found frame intervals for invalid size 47x16
fail: v4l2-test-formats.cpp(282): node->codec_mask & STATEFUL_ENCODER
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: FAIL

[hverkuil: drop incorrect 'For decoder devices, return -ENOTTY.' in the commit log]

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/chips-media/coda-common.c

index 7528f27..af71eea 100644 (file)
@@ -1315,7 +1315,8 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
                                    struct v4l2_frmivalenum *f)
 {
        struct coda_ctx *ctx = fh_to_ctx(fh);
-       int i;
+       struct coda_q_data *q_data;
+       const struct coda_codec *codec;
 
        if (f->index)
                return -EINVAL;
@@ -1324,12 +1325,19 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
        if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV)
                return -EINVAL;
 
-       for (i = 0; i < CODA_MAX_FORMATS; i++) {
-               if (f->pixel_format == ctx->cvd->src_formats[i] ||
-                   f->pixel_format == ctx->cvd->dst_formats[i])
-                       break;
+       if (coda_format_normalize_yuv(f->pixel_format) == V4L2_PIX_FMT_YUV420) {
+               q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+               codec = coda_find_codec(ctx->dev, f->pixel_format,
+                                       q_data->fourcc);
+       } else {
+               codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
+                                       f->pixel_format);
        }
-       if (i == CODA_MAX_FORMATS)
+       if (!codec)
+               return -EINVAL;
+
+       if (f->width < MIN_W || f->width > codec->max_w ||
+           f->height < MIN_H || f->height > codec->max_h)
                return -EINVAL;
 
        f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;