media: cedrus: choose default pixelformat in try_fmt
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Fri, 30 Aug 2019 09:26:23 +0000 (06:26 -0300)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Tue, 1 Oct 2019 19:39:23 +0000 (16:39 -0300)
If an unsupported pixelformat is passed to try_fmt, then pick
the first valid pixelformat instead. This is more standard V4L2
behavior.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/staging/media/sunxi/cedrus/cedrus_video.c

index eeee3ef..d69c9bc 100644 (file)
@@ -62,33 +62,30 @@ static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
 static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
                                                unsigned int capabilities)
 {
+       struct cedrus_format *first_valid_fmt = NULL;
        struct cedrus_format *fmt;
        unsigned int i;
 
        for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
                fmt = &cedrus_formats[i];
 
-               if (fmt->capabilities && (fmt->capabilities & capabilities) !=
-                   fmt->capabilities)
+               if ((fmt->capabilities & capabilities) != fmt->capabilities ||
+                   !(fmt->directions & directions))
                        continue;
 
-               if (fmt->pixelformat == pixelformat &&
-                   (fmt->directions & directions) != 0)
+               if (fmt->pixelformat == pixelformat)
                        break;
+
+               if (!first_valid_fmt)
+                       first_valid_fmt = fmt;
        }
 
        if (i == CEDRUS_FORMATS_COUNT)
-               return NULL;
+               return first_valid_fmt;
 
        return &cedrus_formats[i];
 }
 
-static bool cedrus_check_format(u32 pixelformat, u32 directions,
-                               unsigned int capabilities)
-{
-       return cedrus_find_format(pixelformat, directions, capabilities);
-}
-
 static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
 {
        unsigned int width = pix_fmt->width;
@@ -252,11 +249,14 @@ static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
        struct cedrus_ctx *ctx = cedrus_file2ctx(file);
        struct cedrus_dev *dev = ctx->dev;
        struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
+       struct cedrus_format *fmt =
+               cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
+                                  dev->capabilities);
 
-       if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
-                                dev->capabilities))
+       if (!fmt)
                return -EINVAL;
 
+       pix_fmt->pixelformat = fmt->pixelformat;
        cedrus_prepare_format(pix_fmt);
 
        return 0;
@@ -268,15 +268,18 @@ static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
        struct cedrus_ctx *ctx = cedrus_file2ctx(file);
        struct cedrus_dev *dev = ctx->dev;
        struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
+       struct cedrus_format *fmt =
+               cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
+                                  dev->capabilities);
 
-       if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
-                                dev->capabilities))
+       if (!fmt)
                return -EINVAL;
 
        /* Source image size has to be provided by userspace. */
        if (pix_fmt->sizeimage == 0)
                return -EINVAL;
 
+       pix_fmt->pixelformat = fmt->pixelformat;
        cedrus_prepare_format(pix_fmt);
 
        return 0;
@@ -364,21 +367,12 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
                              struct device *alloc_devs[])
 {
        struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
-       struct cedrus_dev *dev = ctx->dev;
        struct v4l2_pix_format *pix_fmt;
-       u32 directions;
 
-       if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
-               directions = CEDRUS_DECODE_SRC;
+       if (V4L2_TYPE_IS_OUTPUT(vq->type))
                pix_fmt = &ctx->src_fmt;
-       } else {
-               directions = CEDRUS_DECODE_DST;
+       else
                pix_fmt = &ctx->dst_fmt;
-       }
-
-       if (!cedrus_check_format(pix_fmt->pixelformat, directions,
-                                dev->capabilities))
-               return -EINVAL;
 
        if (*nplanes) {
                if (sizes[0] < pix_fmt->sizeimage)