Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755188AbcD0AgM (ORCPT ); Tue, 26 Apr 2016 20:36:12 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:39744 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753657AbcDZXNf (ORCPT ); Tue, 26 Apr 2016 19:13:35 -0400 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Hans de Goede" , "Hans Verkuil" , "Mauro Carvalho Chehab" Date: Wed, 27 Apr 2016 01:02:21 +0200 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 053/217] [media] bttv: Width must be a multiple of 16 when capturing planar formats In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8426:ae4:c500:9cba:69ae:962d:6167 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3479 Lines: 100 3.16.35-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Hans de Goede commit 5c915c68763889f0183a1cc61c84bb228b60124a upstream. On my bttv card "Hauppauge WinTV [card=10]" capturing in YV12 fmt at max size results in a solid green rectangle being captured (all colors 0 in YUV). This turns out to be caused by max-width (924) not being a multiple of 16. We've likely never hit this problem before since normally xawtv / tvtime, etc. will prefer packed pixel formats. But when using a video card which is using xf86-video-modesetting + glamor, only planar XVideo fmts are available, and xawtv will chose a matching capture format to avoid needing to do conversion, triggering the solid green window problem. Signed-off-by: Hans de Goede Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Ben Hutchings --- drivers/media/pci/bt8xx/bttv-driver.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2333,6 +2333,19 @@ static int bttv_g_fmt_vid_overlay(struct return 0; } +static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt, + unsigned int *width_mask, + unsigned int *width_bias) +{ + if (fmt->flags & FORMAT_FLAGS_PLANAR) { + *width_mask = ~15; /* width must be a multiple of 16 pixels */ + *width_bias = 8; /* nearest */ + } else { + *width_mask = ~3; /* width must be a multiple of 4 pixels */ + *width_bias = 2; /* nearest */ + } +} + static int bttv_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -2342,6 +2355,7 @@ static int bttv_try_fmt_vid_cap(struct f enum v4l2_field field; __s32 width, height; __s32 height2; + unsigned int width_mask, width_bias; int rc; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -2374,9 +2388,9 @@ static int bttv_try_fmt_vid_cap(struct f width = f->fmt.pix.width; height = f->fmt.pix.height; + bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); rc = limit_scaled_size_lock(fh, &width, &height, field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, + width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 0); if (0 != rc) @@ -2409,6 +2423,7 @@ static int bttv_s_fmt_vid_cap(struct fil struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; __s32 width, height; + unsigned int width_mask, width_bias; enum v4l2_field field; retval = bttv_switch_type(fh, f->type); @@ -2423,9 +2438,10 @@ static int bttv_s_fmt_vid_cap(struct fil height = f->fmt.pix.height; field = f->fmt.pix.field; + fmt = format_by_fourcc(f->fmt.pix.pixelformat); + bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, + width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 1); if (0 != retval) @@ -2433,8 +2449,6 @@ static int bttv_s_fmt_vid_cap(struct fil f->fmt.pix.field = field; - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - /* update our state informations */ fh->fmt = fmt; fh->cap.field = f->fmt.pix.field;