From 38822ea8817873a2cf74353ef6ad8e363e3dea70 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Nov 2022 13:45:37 +0000 Subject: [PATCH] vc04_services: bcm2835_codec: Allow larger images through the ISP 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 --- .../bcm2835-codec/bcm2835-v4l2-codec.c | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -119,8 +119,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 @@ -686,6 +688,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; @@ -1471,10 +1480,10 @@ static int vidioc_try_fmt(struct bcm2835 * 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. */ @@ -2528,6 +2537,7 @@ static int vidioc_encoder_cmd(struct fil 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, @@ -2546,10 +2556,10 @@ static int vidioc_enum_framesizes(struct 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; @@ -3623,6 +3633,9 @@ static int bcm2835_codec_create(struct b 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); @@ -3645,6 +3658,8 @@ static int bcm2835_codec_create(struct b 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);