V4L/DVB (5970): ivtv: prevent vertical overflow of yuv output
authorIan Armstrong <ian@iarmst.demon.co.uk>
Fri, 3 Aug 2007 12:44:13 +0000 (09:44 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 10 Oct 2007 01:04:25 +0000 (22:04 -0300)
When the video standard is changed, there's no guarantee the framebuffer
dimensions are still legal. The yuv output code uses these dimensions to
calculate the size & position for the video overlay. If the framebuffer
dimensions are now illegal, the output may exceed the vertical limit of the
display, causing distortion.

This patch adds an additional check to ensure the output doesn't exceed
the limits for the current video standard, cropping if required.

Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/ivtv/ivtv-yuv.c

index bcea09542e5ae903493c71e2a7584dc9680525cf..70ddf4060d37c08e79e0cc977f3cadfd548bc9de 100644 (file)
@@ -898,8 +898,21 @@ static void ivtv_yuv_init (struct ivtv *itv)
                itv->yuv_info.decode_height = 480;
 
        /* If no visible size set, assume full size */
-       if (!itv->yuv_info.osd_vis_w) itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
-       if (!itv->yuv_info.osd_vis_h) itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+       if (!itv->yuv_info.osd_vis_w)
+               itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
+
+       if (!itv->yuv_info.osd_vis_h) {
+               itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+       } else {
+               /* If output video standard has changed, requested height may
+               not be legal */
+               if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
+                       IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
+                                       itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
+                                       itv->yuv_info.decode_height);
+                       itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+               }
+       }
 
        /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
        itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);