The patch number 11914 was added via Mauro Carvalho Chehab <mche...@redhat.com> to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward compatible with older kernels. Compatibility modifications will be removed before inclusion into the mainstream Kernel If anyone has any objections, please let us know by sending a message to: Linux Media Mailing List <linux-me...@vger.kernel.org> ------ From: Mauro Carvalho Chehab <mche...@redhat.com> merge: http://linuxtv.org/hg/~tap/v4l-dvb Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com> --- linux/drivers/media/video/cx231xx/cx231xx-avcore.c | 17 --- linux/drivers/media/video/cx231xx/cx231xx-video.c | 26 +--- linux/drivers/media/video/cx231xx/cx231xx.h | 3 linux/drivers/media/video/cx23885/cx23885-video.c | 11 - linux/drivers/media/video/cx88/cx88-video.c | 11 - linux/drivers/media/video/em28xx/em28xx-video.c | 38 ++---- linux/drivers/media/video/mt9m001.c | 12 -- linux/drivers/media/video/mt9t031.c | 14 -- linux/drivers/media/video/mt9v022.c | 12 -- linux/drivers/media/video/pxa_camera.c | 36 +----- linux/drivers/media/video/saa7134/saa7134-video.c | 11 - linux/drivers/media/video/sh_mobile_ceu_camera.c | 12 -- linux/drivers/media/video/v4l2-common.c | 73 ++++++++++++- linux/drivers/media/video/vivi.c | 11 - linux/drivers/media/video/w9968cf.c | 39 ++---- linux/drivers/media/video/zoran/zoran_driver.c | 14 -- linux/include/media/v4l2-common.h | 10 + v4l/compat.h | 15 ++ 18 files changed, 165 insertions(+), 200 deletions(-) diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/cx231xx/cx231xx-avcore.c --- a/linux/drivers/media/video/cx231xx/cx231xx-avcore.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/cx231xx/cx231xx-avcore.c Mon Jun 01 05:21:32 2009 -0300 @@ -1052,22 +1052,13 @@ int cx231xx_set_audio_decoder_input(stru /* Set resolution of the video */ int cx231xx_resolution_set(struct cx231xx *dev) { - int width, height; - u32 hscale, vscale; - int status = 0; - - width = dev->width; - height = dev->height; - - get_scale(dev, width, height, &hscale, &vscale); - /* set horzontal scale */ - status = vid_blk_write_word(dev, HSCALE_CTRL, hscale); + int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale); + if (status) + return status; /* set vertical scale */ - status = vid_blk_write_word(dev, VSCALE_CTRL, vscale); - - return status; + return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale); } /****************************************************************************** diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/cx231xx/cx231xx-video.c --- a/linux/drivers/media/video/cx231xx/cx231xx-video.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/cx231xx/cx231xx-video.c Mon Jun 01 05:21:32 2009 -0300 @@ -893,9 +893,9 @@ static int check_dev(struct cx231xx *dev return 0; } -void get_scale(struct cx231xx *dev, - unsigned int width, unsigned int height, - unsigned int *hscale, unsigned int *vscale) +static void get_scale(struct cx231xx *dev, + unsigned int width, unsigned int height, + unsigned int *hscale, unsigned int *vscale) { unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); @@ -907,10 +907,6 @@ void get_scale(struct cx231xx *dev, *vscale = (((unsigned long)maxh) << 12) / height - 4096L; if (*vscale >= 0x4000) *vscale = 0x3fff; - - dev->hscale = *hscale; - dev->vscale = *vscale; - } /* ------------------------------------------------------------------ @@ -955,8 +951,8 @@ static int vidioc_try_fmt_vid_cap(struct { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; - int width = f->fmt.pix.width; - int height = f->fmt.pix.height; + unsigned int width = f->fmt.pix.width; + unsigned int height = f->fmt.pix.height; unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); unsigned int hscale, vscale; @@ -971,17 +967,7 @@ static int vidioc_try_fmt_vid_cap(struct /* width must even because of the YUYV format height must be even because of interlacing */ - height &= 0xfffe; - width &= 0xfffe; - - if (unlikely(height < 32)) - height = 32; - if (unlikely(height > maxh)) - height = maxh; - if (unlikely(width < 48)) - width = 48; - if (unlikely(width > maxw)) - width = maxw; + v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); get_scale(dev, width, height, &hscale, &vscale); diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/cx231xx/cx231xx.h --- a/linux/drivers/media/video/cx231xx/cx231xx.h Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/cx231xx/cx231xx.h Mon Jun 01 05:21:32 2009 -0300 @@ -731,9 +731,6 @@ int cx231xx_set_decoder_video_input(stru int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input); int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev); int cx231xx_set_audio_input(struct cx231xx *dev, u8 input); -void get_scale(struct cx231xx *dev, - unsigned int width, unsigned int height, - unsigned int *hscale, unsigned int *vscale); /* Provided by cx231xx-video.c */ int cx231xx_register_extension(struct cx231xx_ops *dev); diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/cx23885/cx23885-video.c --- a/linux/drivers/media/video/cx23885/cx23885-video.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/cx23885/cx23885-video.c Mon Jun 01 05:21:32 2009 -0300 @@ -1035,15 +1035,8 @@ static int vidioc_try_fmt_vid_cap(struct } f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/cx88/cx88-video.c --- a/linux/drivers/media/video/cx88/cx88-video.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/cx88/cx88-video.c Mon Jun 01 05:21:32 2009 -0300 @@ -1339,15 +1339,8 @@ static int vidioc_try_fmt_vid_cap(struct } f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/em28xx/em28xx-video.c --- a/linux/drivers/media/video/em28xx/em28xx-video.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/em28xx/em28xx-video.c Mon Jun 01 05:21:32 2009 -0300 @@ -691,8 +691,8 @@ static int vidioc_try_fmt_vid_cap(struct { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int width = f->fmt.pix.width; - int height = f->fmt.pix.height; + unsigned int width = f->fmt.pix.width; + unsigned int height = f->fmt.pix.height; unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); unsigned int hscale, vscale; @@ -705,34 +705,20 @@ static int vidioc_try_fmt_vid_cap(struct return -EINVAL; } - /* width must even because of the YUYV format - height must be even because of interlacing */ - height &= 0xfffe; - width &= 0xfffe; - - if (unlikely(height < 32)) - height = 32; - if (unlikely(height > maxh)) - height = maxh; - if (unlikely(width < 48)) - width = 48; - if (unlikely(width > maxw)) - width = maxw; - if (dev->board.is_em2800) { /* the em2800 can only scale down to 50% */ - if (height % (maxh / 2)) - height = maxh; - if (width % (maxw / 2)) - width = maxw; - /* according to empiatech support */ - /* the MaxPacketSize is to small to support */ - /* framesizes larger than 640x480 @ 30 fps */ - /* or 640x576 @ 25 fps. As this would cut */ - /* of a part of the image we prefer */ - /* 360x576 or 360x480 for now */ + height = height > (3 * maxh / 4) ? maxh : maxh / 2; + width = width > (3 * maxw / 4) ? maxw : maxw / 2; + /* According to empiatech support the MaxPacketSize is too small + * to support framesizes larger than 640x480 @ 30 fps or 640x576 + * @ 25 fps. As this would cut of a part of the image we prefer + * 360x576 or 360x480 for now */ if (width == maxw && height == maxh) width /= 2; + } else { + /* width must even because of the YUYV format + height must be even because of interlacing */ + v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); } get_scale(dev, width, height, &hscale, &vscale); diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/mt9m001.c --- a/linux/drivers/media/video/mt9m001.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/mt9m001.c Mon Jun 01 05:21:32 2009 -0300 @@ -280,15 +280,9 @@ static int mt9m001_try_fmt(struct soc_ca { struct v4l2_pix_format *pix = &f->fmt.pix; - if (pix->height < 32 + icd->y_skip_top) - pix->height = 32 + icd->y_skip_top; - if (pix->height > 1024 + icd->y_skip_top) - pix->height = 1024 + icd->y_skip_top; - if (pix->width < 48) - pix->width = 48; - if (pix->width > 1280) - pix->width = 1280; - pix->width &= ~0x01; /* has to be even, unsure why was ~3 */ + v4l_bound_align_image(&pix->width, 48, 1280, 1, + &pix->height, 32 + icd->y_skip_top, + 1024 + icd->y_skip_top, 0, 0); return 0; } diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/mt9t031.c --- a/linux/drivers/media/video/mt9t031.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/mt9t031.c Mon Jun 01 05:21:32 2009 -0300 @@ -385,17 +385,9 @@ static int mt9t031_try_fmt(struct soc_ca { struct v4l2_pix_format *pix = &f->fmt.pix; - if (pix->height < MT9T031_MIN_HEIGHT) - pix->height = MT9T031_MIN_HEIGHT; - if (pix->height > MT9T031_MAX_HEIGHT) - pix->height = MT9T031_MAX_HEIGHT; - if (pix->width < MT9T031_MIN_WIDTH) - pix->width = MT9T031_MIN_WIDTH; - if (pix->width > MT9T031_MAX_WIDTH) - pix->width = MT9T031_MAX_WIDTH; - - pix->width &= ~0x01; /* has to be even */ - pix->height &= ~0x01; /* has to be even */ + v4l_bound_align_image( + &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, + &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); return 0; } diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/mt9v022.c --- a/linux/drivers/media/video/mt9v022.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/mt9v022.c Mon Jun 01 05:21:32 2009 -0300 @@ -364,15 +364,9 @@ static int mt9v022_try_fmt(struct soc_ca { struct v4l2_pix_format *pix = &f->fmt.pix; - if (pix->height < 32 + icd->y_skip_top) - pix->height = 32 + icd->y_skip_top; - if (pix->height > 480 + icd->y_skip_top) - pix->height = 480 + icd->y_skip_top; - if (pix->width < 48) - pix->width = 48; - if (pix->width > 752) - pix->width = 752; - pix->width &= ~0x03; /* ? */ + v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, + &pix->height, 32 + icd->y_skip_top, + 480 + icd->y_skip_top, 0, 0); return 0; } diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/pxa_camera.c --- a/linux/drivers/media/video/pxa_camera.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/pxa_camera.c Mon Jun 01 05:21:32 2009 -0300 @@ -173,13 +173,6 @@ #define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \ CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ CICR0_EOFM | CICR0_FOM) - -/* - * YUV422P picture size should be a multiple of 16, so the heuristic aligns - * height, width on 4 byte boundaries to reach the 16 multiple for the size. - */ -#define YUV422P_X_Y_ALIGN 4 -#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN /* * Structures @@ -1410,28 +1403,13 @@ static int pxa_camera_try_fmt(struct soc return -EINVAL; } - /* limit to pxa hardware capabilities */ - if (pix->height < 32) - pix->height = 32; - if (pix->height > 2048) - pix->height = 2048; - if (pix->width < 48) - pix->width = 48; - if (pix->width > 2048) - pix->width = 2048; - pix->width &= ~0x01; - - /* - * YUV422P planar format requires images size to be a 16 bytes - * multiple. If not, zeros will be inserted between Y and U planes, and - * U and V planes, and YUV422P standard would be violated. - */ - if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) { - if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN)) - pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN); - if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN)) - pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN); - } + /* Limit to pxa hardware capabilities. YUV422P planar format requires + * images size to be a multiple of 16 bytes. If not, zeros will be + * inserted between Y and U planes, and U and V planes, which violates + * the YUV422P standard. */ + v4l2_bound_align_image(&pix->width, 48, 2048, 1, + &pix->height, 32, 2048, 0, + xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); pix->bytesperline = pix->width * DIV_ROUND_UP(xlate->host_fmt->depth, 8); diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/saa7134/saa7134-video.c --- a/linux/drivers/media/video/saa7134/saa7134-video.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/saa7134/saa7134-video.c Mon Jun 01 05:21:32 2009 -0300 @@ -1646,15 +1646,8 @@ static int saa7134_try_fmt_vid_cap(struc } f->fmt.pix.field = field; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - f->fmt.pix.width &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/sh_mobile_ceu_camera.c --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c Mon Jun 01 05:21:32 2009 -0300 @@ -690,16 +690,8 @@ static int sh_mobile_ceu_try_fmt(struct /* FIXME: calculate using depth and bus width */ - if (f->fmt.pix.height < 4) - f->fmt.pix.height = 4; - if (f->fmt.pix.height > 1920) - f->fmt.pix.height = 1920; - if (f->fmt.pix.width < 2) - f->fmt.pix.width = 2; - if (f->fmt.pix.width > 2560) - f->fmt.pix.width = 2560; - f->fmt.pix.width &= ~0x01; - f->fmt.pix.height &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1, + &f->fmt.pix.height, 4, 1920, 2, 0); f->fmt.pix.bytesperline = f->fmt.pix.width * DIV_ROUND_UP(xlate->host_fmt->depth, 8); diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/v4l2-common.c --- a/linux/drivers/media/video/v4l2-common.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/v4l2-common.c Mon Jun 01 05:21:32 2009 -0300 @@ -997,4 +997,75 @@ const unsigned short *v4l2_i2c_tuner_add } EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs); -#endif +/* Clamp x to be between min and max, aligned to a multiple of 2^align. min + * and max don't have to be aligned, but there must be at least one valid + * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples + * of 16 between 17 and 31. */ +static unsigned int clamp_align(unsigned int x, unsigned int min, + unsigned int max, unsigned int align) +{ + /* Bits that must be zero to be aligned */ + unsigned int mask = ~((1 << align) - 1); + + /* Round to nearest aligned value */ + if (align) + x = (x + (1 << (align - 1))) & mask; + + /* Clamp to aligned value of min and max */ + if (x < min) + x = (min + ~mask) & mask; + else if (x > max) + x = max & mask; + + return x; +} + +/* Bound an image to have a width between wmin and wmax, and height between + * hmin and hmax, inclusive. Additionally, the width will be a multiple of + * 2^walign, the height will be a multiple of 2^halign, and the overall size + * (width*height) will be a multiple of 2^salign. The image may be shrunk + * or enlarged to fit the alignment constraints. + * + * The width or height maximum must not be smaller than the corresponding + * minimum. The alignments must not be so high there are no possible image + * sizes within the allowed bounds. wmin and hmin must be at least 1 + * (don't use 0). If you don't care about a certain alignment, specify 0, + * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If + * you only want to adjust downward, specify a maximum that's the same as + * the initial value. + */ +void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, + unsigned int walign, + u32 *h, unsigned int hmin, unsigned int hmax, + unsigned int halign, unsigned int salign) +{ + *w = clamp_align(*w, wmin, wmax, walign); + *h = clamp_align(*h, hmin, hmax, halign); + + /* Usually we don't need to align the size and are done now. */ + if (!salign) + return; + + /* How much alignment do we have? */ + walign = __ffs(*w); + halign = __ffs(*h); + /* Enough to satisfy the image alignment? */ + if (walign + halign < salign) { + /* Max walign where there is still a valid width */ + unsigned int wmaxa = __fls(wmax ^ (wmin - 1)); + + /* up the smaller alignment until we have enough */ + do { + if (walign <= halign && walign < wmaxa) { + *w = clamp_align(*w, wmin, wmax, walign + 1); + walign = __ffs(*w); + } else { + *h = clamp_align(*h, hmin, hmax, halign + 1); + halign = __ffs(*h); + } + } while (halign + walign < salign); + } +} +EXPORT_SYMBOL_GPL(v4l_bound_align_image); + +#endif diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/vivi.c --- a/linux/drivers/media/video/vivi.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/vivi.c Mon Jun 01 05:21:32 2009 -0300 @@ -886,15 +886,8 @@ static int vidioc_try_fmt_vid_cap(struct maxh = norm_maxh(); f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/w9968cf.c --- a/linux/drivers/media/video/w9968cf.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/w9968cf.c Mon Jun 01 05:21:32 2009 -0300 @@ -464,7 +464,7 @@ static int w9968cf_set_window(struct w99 static int w9968cf_set_window(struct w9968cf_device*, struct video_window); static int w9968cf_postprocess_frame(struct w9968cf_device*, struct w9968cf_frame_t*); -static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h); +static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h); static void w9968cf_init_framelist(struct w9968cf_device*); static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); @@ -1777,8 +1777,7 @@ w9968cf_set_window(struct w9968cf_device #define UNSC(x) ((x) >> 10) /* Make sure we are using a supported resolution */ - if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, - (u16*)&win.height))) + if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height))) goto error; /* Scaling factors */ @@ -1928,12 +1927,9 @@ error: Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ static int -w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) -{ - u16 maxw, maxh; - - if ((*width < cam->minwidth) || (*height < cam->minheight)) - return -ERANGE; +w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height) +{ + unsigned int maxw, maxh, align; maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) @@ -1941,16 +1937,10 @@ w9968cf_adjust_window_size(struct w9968c maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) : cam->maxheight; - - if (*width > maxw) - *width = maxw; - if (*height > maxh) - *height = maxh; - - if (cam->vpp_flag & VPP_DECOMPRESSION) { - *width &= ~15L; /* multiple of 16 */ - *height &= ~15L; - } + align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0; + + v4l_bound_align_image(width, cam->minwidth, maxw, align, + height, cam->minheight, maxh, align, 0); PDBGG("Window size adjusted w=%u, h=%u ", *width, *height) @@ -3057,8 +3047,8 @@ static long w9968cf_v4l_ioctl(struct fil if (win.clipcount != 0 || win.flags != 0) return -EINVAL; - if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, - (u16*)&win.height))) { + if ((err = w9968cf_adjust_window_size(cam, &win.width, + &win.height))) { DBG(4, "Resolution not supported (%ux%u). " "VIDIOCSWIN failed", win.width, win.height) return err; @@ -3130,6 +3120,7 @@ static long w9968cf_v4l_ioctl(struct fil { struct video_mmap mmap; struct w9968cf_frame_t* fr; + u32 w, h; int err = 0; if (copy_from_user(&mmap, arg, sizeof(mmap))) @@ -3178,8 +3169,10 @@ static long w9968cf_v4l_ioctl(struct fil } } - if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, - (u16*)&mmap.height))) { + w = mmap.width; h = mmap.height; + err = w9968cf_adjust_window_size(cam, &w, &h); + mmap.width = w; mmap.height = h; + if (err) { DBG(4, "Resolution not supported (%dx%d). " "VIDIOCMCAPTURE failed", mmap.width, mmap.height) diff -r e431fc1768a9 -r 89f922c8614e linux/drivers/media/video/zoran/zoran_driver.c --- a/linux/drivers/media/video/zoran/zoran_driver.c Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/drivers/media/video/zoran/zoran_driver.c Mon Jun 01 05:21:32 2009 -0300 @@ -2096,16 +2096,10 @@ static int zoran_try_fmt_vid_cap(struct return -EINVAL; } - bpp = (zoran_formats[i].depth + 7) / 8; - fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) - fmt->fmt.pix.width = BUZ_MIN_WIDTH; - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) - fmt->fmt.pix.height = BUZ_MIN_HEIGHT; + bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8); + v4l_bound_align_image( + &fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2, + &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0); mutex_unlock(&zr->resource_lock); return 0; diff -r e431fc1768a9 -r 89f922c8614e linux/include/media/v4l2-common.h --- a/linux/include/media/v4l2-common.h Mon Jun 01 05:02:59 2009 -0300 +++ b/linux/include/media/v4l2-common.h Mon Jun 01 05:21:32 2009 -0300 @@ -198,4 +198,14 @@ struct v4l2_routing { u32 output; }; +/* ------------------------------------------------------------------------- */ + +/* Miscellaneous helper functions */ + +void v4l_bound_align_image(unsigned int *w, unsigned int wmin, + unsigned int wmax, unsigned int walign, + unsigned int *h, unsigned int hmin, + unsigned int hmax, unsigned int halign, + unsigned int salign); + #endif /* V4L2_COMMON_H_ */ diff -r e431fc1768a9 -r 89f922c8614e v4l/compat.h --- a/v4l/compat.h Mon Jun 01 05:02:59 2009 -0300 +++ b/v4l/compat.h Mon Jun 01 05:21:32 2009 -0300 @@ -454,4 +454,19 @@ static inline int snd_card_create(int id #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #endif +/* __fls() was added for generic code in 2.6.29, existed for just 64-bit arches + * since 2.6.26 (v2.6.25-5228-g56a6b1e), and was x86-64 only before then. We + * only want this compat code when __fls doesn't exist, which 2.6.29 or later, + * non x86-64, and non 64-bit that's 2.6.26 or later. */ +#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) || \ + defined(__x86_64__) || \ + (BITS_PER_LONG == 64 && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26))) +/* This define will prevent breakage if __fls was already defined. */ +#define __fls v4l_compat_fls +static inline unsigned long v4l_compat_fls(unsigned long x) +{ + return fls(x) - 1; +} +#endif + #endif /* _COMPAT_H */ --- Patch is available at: http://linuxtv.org/hg/v4l-dvb/rev/89f922c8614ec6fc26bb1079faaeb8068ed4be24 _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits