The patch number 10711 was added via Hans Verkuil <[email protected]>
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 <[email protected]>

------

From: Hans Verkuil  <[email protected]>
zoran: fix TRY_FMT support


Actually try to turn the format into something usable rather than just
rejecting it if it isn't perfect.

Priority: normal

Signed-off-by: Hans Verkuil <[email protected]>


---

 linux/drivers/media/video/zoran/zoran_card.c   |   67 +++++++++++------
 linux/drivers/media/video/zoran/zoran_card.h   |    3 
 linux/drivers/media/video/zoran/zoran_driver.c |   21 ++++-
 3 files changed, 65 insertions(+), 26 deletions(-)

diff -r 01228538573c -r 29653d606838 
linux/drivers/media/video/zoran/zoran_card.c
--- a/linux/drivers/media/video/zoran/zoran_card.c      Wed Feb 18 21:00:37 
2009 +0100
+++ b/linux/drivers/media/video/zoran/zoran_card.c      Wed Feb 18 21:11:17 
2009 +0100
@@ -836,7 +836,8 @@ zoran_unregister_i2c (struct zoran *zr)
 
 int
 zoran_check_jpg_settings (struct zoran              *zr,
-                         struct zoran_jpg_settings *settings)
+                         struct zoran_jpg_settings *settings,
+                         int try)
 {
        int err = 0, err0 = 0;
 
@@ -901,35 +902,61 @@ zoran_check_jpg_settings (struct zoran  
                /* We have to check the data the user has set */
 
                if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
-                   (zr->card.type == DC10_new || settings->HorDcm != 4))
+                   (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+                       settings->HorDcm = clamp(settings->HorDcm, 1, 2);
                        err0++;
-               if (settings->VerDcm != 1 && settings->VerDcm != 2)
+               }
+               if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+                       settings->VerDcm = clamp(settings->VerDcm, 1, 2);
                        err0++;
-               if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+               }
+               if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+                       settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
                        err0++;
+               }
                if (settings->field_per_buff != 1 &&
-                   settings->field_per_buff != 2)
+                   settings->field_per_buff != 2) {
+                       settings->field_per_buff = 
clamp(settings->field_per_buff, 1, 2);
                        err0++;
-               if (settings->img_x < 0)
+               }
+               if (settings->img_x < 0) {
+                       settings->img_x = 0;
                        err0++;
-               if (settings->img_y < 0)
+               }
+               if (settings->img_y < 0) {
+                       settings->img_y = 0;
                        err0++;
-               if (settings->img_width < 0)
+               }
+               if (settings->img_width < 0 || settings->img_width > 
BUZ_MAX_WIDTH) {
+                       settings->img_width = clamp(settings->img_width, 0, 
(int)BUZ_MAX_WIDTH);
                        err0++;
-               if (settings->img_height < 0)
+               }
+               if (settings->img_height < 0 || settings->img_height > 
BUZ_MAX_HEIGHT / 2) {
+                       settings->img_height = clamp(settings->img_height, 0, 
BUZ_MAX_HEIGHT / 2);
                        err0++;
-               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+               }
+               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
                        err0++;
-               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2)
+               }
+               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 
2) {
+                       settings->img_y = BUZ_MAX_HEIGHT / 2 - 
settings->img_height;
                        err0++;
-               if (settings->HorDcm && settings->VerDcm) {
-                       if (settings->img_width % (16 * settings->HorDcm) != 0)
-                               err0++;
-                       if (settings->img_height % (8 * settings->VerDcm) != 0)
-                               err0++;
-               }
-
-               if (err0) {
+               }
+               if (settings->img_width % (16 * settings->HorDcm) != 0) {
+                       settings->img_width -= settings->img_width % (16 * 
settings->HorDcm);
+                       if (settings->img_width == 0)
+                               settings->img_width = 16 * settings->HorDcm;
+                       err0++;
+               }
+               if (settings->img_height % (8 * settings->VerDcm) != 0) {
+                       settings->img_height -= settings->img_height % (8 * 
settings->VerDcm);
+                       if (settings->img_height == 0)
+                               settings->img_height = 8 * settings->VerDcm;
+                       err0++;
+               }
+
+               if (!try && err0) {
                        dprintk(1,
                                KERN_ERR
                                "%s: check_jpg_settings() - error in params for 
decimation = 0\n",
@@ -1019,7 +1046,7 @@ zoran_open_init_params (struct zoran *zr
               sizeof(zr->jpg_settings.jpg_comp.COM_data));
        zr->jpg_settings.jpg_comp.jpeg_markers =
            JPEG_MARKER_DHT | JPEG_MARKER_DQT;
-       i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+       i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
        if (i)
                dprintk(1,
                        KERN_ERR
diff -r 01228538573c -r 29653d606838 
linux/drivers/media/video/zoran/zoran_card.h
--- a/linux/drivers/media/video/zoran/zoran_card.h      Wed Feb 18 21:00:37 
2009 +0100
+++ b/linux/drivers/media/video/zoran/zoran_card.h      Wed Feb 18 21:11:17 
2009 +0100
@@ -44,7 +44,8 @@ extern struct video_device zoran_templat
 extern struct video_device zoran_template;
 
 extern int zoran_check_jpg_settings(struct zoran *zr,
-                                   struct zoran_jpg_settings *settings);
+                                   struct zoran_jpg_settings *settings,
+                                   int try);
 extern void zoran_open_init_params(struct zoran *zr);
 extern void zoran_vdev_release(struct video_device *vdev);
 
diff -r 01228538573c -r 29653d606838 
linux/drivers/media/video/zoran/zoran_driver.c
--- a/linux/drivers/media/video/zoran/zoran_driver.c    Wed Feb 18 21:00:37 
2009 +0100
+++ b/linux/drivers/media/video/zoran/zoran_driver.c    Wed Feb 18 21:11:17 
2009 +0100
@@ -1798,7 +1798,7 @@ static long zoran_default(struct file *f
 
                /* Check the params first before overwriting our
                 * nternal values */
-               if (zoran_check_jpg_settings(zr, &settings)) {
+               if (zoran_check_jpg_settings(zr, &settings, 0)) {
                        res = -EINVAL;
                        goto sparams_unlock_and_return;
                }
@@ -2206,7 +2206,7 @@ static int zoran_try_fmt_vid_out(struct 
                settings.field_per_buff = 1;
 
        /* check */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 1);
        if (res)
                goto tryfmt_unlock_and_return;
 
@@ -2232,6 +2232,7 @@ static int zoran_try_fmt_vid_cap(struct 
 {
        struct zoran_fh *fh = __fh;
        struct zoran *zr = fh->zr;
+       int bpp;
        int i;
 
        if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
@@ -2248,6 +2249,8 @@ 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)
@@ -2335,8 +2338,16 @@ static int zoran_s_fmt_vid_out(struct fi
        else
                settings.field_per_buff = 1;
 
+       if (settings.HorDcm > 1) {
+               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : 
BUZ_MAX_WIDTH;
+       } else {
+               settings.img_x = 0;
+               settings.img_width = BUZ_MAX_WIDTH;
+       }
+
        /* check */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto sfmtjpg_unlock_and_return;
 
@@ -3217,7 +3228,7 @@ static int zoran_s_crop(struct file *fil
        settings.img_height = crop->c.height;
 
        /* check validity */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto scrop_unlock_and_return;
 
@@ -3279,7 +3290,7 @@ static int zoran_s_jpegcomp(struct file 
                goto sjpegc_unlock_and_return;
        }
 
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto sjpegc_unlock_and_return;
        if (!fh->jpg_buffers.allocated)


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/29653d606838a008334ef0953bc112d352110882

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to