vc04_services: bcm2835_codec: Allow larger images through the ISP
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Thu, 3 Nov 2022 13:45:37 +0000 (13:45 +0000)
committerPhil Elwell <8911409+pelwell@users.noreply.github.com>
Thu, 10 Nov 2022 09:45:11 +0000 (09:45 +0000)
Whilst the codecs are restricted to 1920x1080 / 1080x1920, the ISP
isn't, but the limits advertised via V4L2 was 1920x1920 for all
roles.

Increase the limit to 16k x 16k for the ISP.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c

index 8e44880..cc072aa 100644 (file)
@@ -117,8 +117,10 @@ static const char * const components[] = {
 
 #define MIN_W          32
 #define MIN_H          32
-#define MAX_W          1920
-#define MAX_H          1920
+#define MAX_W_CODEC    1920
+#define MAX_H_CODEC    1920
+#define MAX_W_ISP      16384
+#define MAX_H_ISP      16384
 #define BPL_ALIGN      32
 /*
  * The decoder spec supports the V4L2_EVENT_SOURCE_CHANGE event, but the docs
@@ -684,6 +686,13 @@ struct bcm2835_codec_dev {
        /* The list of formats supported on input and output queues. */
        struct bcm2835_codec_fmt_list   supported_fmts[2];
 
+       /*
+        * Max size supported varies based on role. Store during
+        * bcm2835_codec_create for use later.
+        */
+       unsigned int max_w;
+       unsigned int max_h;
+
        struct vchiq_mmal_instance      *instance;
 
        struct v4l2_m2m_dev     *m2m_dev;
@@ -1469,10 +1478,10 @@ static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f,
         * The V4L2 specification requires the driver to correct the format
         * struct if any of the dimensions is unsupported
         */
-       if (f->fmt.pix_mp.width > MAX_W)
-               f->fmt.pix_mp.width = MAX_W;
-       if (f->fmt.pix_mp.height > MAX_H)
-               f->fmt.pix_mp.height = MAX_H;
+       if (f->fmt.pix_mp.width > ctx->dev->max_w)
+               f->fmt.pix_mp.width = ctx->dev->max_w;
+       if (f->fmt.pix_mp.height > ctx->dev->max_h)
+               f->fmt.pix_mp.height = ctx->dev->max_h;
 
        if (!(fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) {
                /* Only clip min w/h on capture. Treat 0x0 as unknown. */
@@ -2526,6 +2535,7 @@ static int vidioc_encoder_cmd(struct file *file, void *priv,
 static int vidioc_enum_framesizes(struct file *file, void *fh,
                                  struct v4l2_frmsizeenum *fsize)
 {
+       struct bcm2835_codec_ctx *ctx = file2ctx(file);
        struct bcm2835_codec_fmt *fmt;
 
        fmt = find_format_pix_fmt(fsize->pixel_format, file2ctx(file)->dev,
@@ -2544,10 +2554,10 @@ static int vidioc_enum_framesizes(struct file *file, void *fh,
        fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 
        fsize->stepwise.min_width = MIN_W;
-       fsize->stepwise.max_width = MAX_W;
+       fsize->stepwise.max_width = ctx->dev->max_w;
        fsize->stepwise.step_width = 2;
        fsize->stepwise.min_height = MIN_H;
-       fsize->stepwise.max_height = MAX_H;
+       fsize->stepwise.max_height = ctx->dev->max_h;
        fsize->stepwise.step_height = 2;
 
        return 0;
@@ -3621,6 +3631,9 @@ static int bcm2835_codec_create(struct bcm2835_codec_driver *drv,
        if (ret)
                goto vchiq_finalise;
 
+       dev->max_w = MAX_W_CODEC;
+       dev->max_h = MAX_H_CODEC;
+
        switch (role) {
        case DECODE:
                v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
@@ -3643,6 +3656,8 @@ static int bcm2835_codec_create(struct bcm2835_codec_driver *drv,
                v4l2_disable_ioctl(vfd, VIDIOC_G_PARM);
                function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
                video_nr = isp_video_nr;
+               dev->max_w = MAX_W_ISP;
+               dev->max_h = MAX_H_ISP;
                break;
        case DEINTERLACE:
                v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);