From c8af44e1e791c5d6e38c464603ae8d9a7b0468b1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 28 Feb 2019 01:25:50 -0500 Subject: media: vim2m: use different framesizes for bayer formats The only real restriction at vim2m is that width should be multiple of two, as the copy routine always copy two pixels each time. However, Bayer formats are defined as having a 2x2 matrix. So, odd vertical numbers would cause color distortions at the last line. So, it makes sense to use step 2 for vertical alignment on Bayer. With this patch, the reported formats for video capture will be: [0]: 'RGBP' (16-bit RGB 5-6-5) Size: Stepwise 32x32 - 640x480 with step 2/1 [1]: 'RGBR' (16-bit RGB 5-6-5 BE) Size: Stepwise 32x32 - 640x480 with step 2/1 [2]: 'RGB3' (24-bit RGB 8-8-8) Size: Stepwise 32x32 - 640x480 with step 2/1 [3]: 'BGR3' (24-bit BGR 8-8-8) Size: Stepwise 32x32 - 640x480 with step 2/1 [4]: 'YUYV' (YUYV 4:2:2) Size: Stepwise 32x32 - 640x480 with step 2/1 [5]: 'BA81' (8-bit Bayer BGBG/GRGR) Size: Stepwise 32x32 - 640x480 with step 2/2 [6]: 'GBRG' (8-bit Bayer GBGB/RGRG) Size: Stepwise 32x32 - 640x480 with step 2/2 [7]: 'GRBG' (8-bit Bayer GRGR/BGBG) Size: Stepwise 32x32 - 640x480 with step 2/2 [8]: 'RGGB' (8-bit Bayer RGRG/GBGB) Size: Stepwise 32x32 - 640x480 with step 2/2 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vim2m.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'drivers/media/platform/vim2m.c') diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 620f064ff12a..12f0f3e433da 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -50,7 +50,14 @@ MODULE_PARM_DESC(default_transtime, "default transaction time in ms"); #define MIN_H 32 #define MAX_W 640 #define MAX_H 480 -#define WIDTH_ALIGN 2 /* 2-byte alignment */ + +/* Pixel alignment for non-bayer formats */ +#define WIDTH_ALIGN 2 +#define HEIGHT_ALIGN 1 + +/* Pixel alignment for bayer formats */ +#define BAYER_WIDTH_ALIGN 2 +#define BAYER_HEIGHT_ALIGN 2 /* Flags that indicate a format can be used for capture/output */ #define MEM2MEM_CAPTURE (1 << 0) @@ -162,6 +169,24 @@ static struct vim2m_fmt *find_format(u32 fourcc) return &formats[k]; } +static void get_alignment(u32 fourcc, + unsigned int *walign, unsigned int *halign) +{ + switch (fourcc) { + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + *walign = BAYER_WIDTH_ALIGN; + *halign = BAYER_HEIGHT_ALIGN; + return; + default: + *walign = WIDTH_ALIGN; + *halign = HEIGHT_ALIGN; + return; + } +} + struct vim2m_dev { struct v4l2_device v4l2_dev; struct video_device vfd; @@ -691,8 +716,10 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->stepwise.min_height = MIN_H; fsize->stepwise.max_width = MAX_W; fsize->stepwise.max_height = MAX_H; - fsize->stepwise.step_width = WIDTH_ALIGN; - fsize->stepwise.step_height = 1; + + get_alignment(fsize->pixel_format, + &fsize->stepwise.step_width, + &fsize->stepwise.step_height); return 0; } @@ -735,6 +762,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt) { + int walign, halign; /* V4L2 specification suggests the driver corrects the format struct * if any of the dimensions is unsupported */ if (f->fmt.pix.height < MIN_H) @@ -747,7 +775,9 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt) else if (f->fmt.pix.width > MAX_W) f->fmt.pix.width = MAX_W; - f->fmt.pix.width &= ~(WIDTH_ALIGN - 1); + get_alignment(f->fmt.pix.pixelformat, &walign, &halign); + f->fmt.pix.width &= ~(walign - 1); + f->fmt.pix.height &= ~(halign - 1); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.field = V4L2_FIELD_NONE; -- cgit v1.2.3