V4L/DVB (7243): ivtv: yuv framebuffer tracking

The existing yuv code limits output to the display area occupied by the
framebuffer. This patch allows the yuv output to be 'detached' via
V4L2_FBUF_FLAG_OVERLAY.

By default, the yuv output window will be restricted to the framebuffer
dimensions and the output position is relative to the top left corner of the
framebuffer. This matches the behaviour of previous versions.

If V4L2_FBUF_FLAG_OVERLAY is cleared, the yuv output will no longer be linked
to the framebuffer. The maximum dimensions are either 720x576 or 720x480
depending on the current broadcast standard, with the output position
relative to the top left corner of the display. The framebuffer itself can be
resized, moved and panned without affecting the yuv output.

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>
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 8fdd67c..393d917 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -718,9 +718,11 @@
 		f->src_w -= (osd_scale * osd_crop) >> 16;
 	}
 
-	/* The OSD can be moved. Track to it */
-	f->dst_x += itv->yuv_info.osd_x_offset;
-	f->dst_y += itv->yuv_info.osd_y_offset;
+	if (itv->yuv_info.track_osd) {
+		/* The OSD can be moved. Track to it */
+		f->dst_x += itv->yuv_info.osd_x_offset;
+		f->dst_y += itv->yuv_info.osd_y_offset;
+	}
 
 	/* Width & height for both src & dst must be even.
 	   Same for coordinates. */
@@ -792,11 +794,19 @@
 	IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
 	f = yi->new_frame_info[frame];
 
-	/* Update the osd pan info */
-	f.pan_x = yi->osd_x_pan;
-	f.pan_y = yi->osd_y_pan;
-	f.vis_w = yi->osd_vis_w;
-	f.vis_h = yi->osd_vis_h;
+	if (yi->track_osd) {
+		/* Snapshot the osd pan info */
+		f.pan_x = yi->osd_x_pan;
+		f.pan_y = yi->osd_y_pan;
+		f.vis_w = yi->osd_vis_w;
+		f.vis_h = yi->osd_vis_h;
+	} else {
+		/* Not tracking the osd, so assume full screen */
+		f.pan_x = 0;
+		f.pan_y = 0;
+		f.vis_w = 720;
+		f.vis_h = yi->decode_height;
+	}
 
 	/* Calculate the display window coordinates. Exit if nothing left */
 	if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
@@ -965,12 +975,6 @@
 	/* Are we going to offset the Y plane */
 	nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
 
-	/* Snapshot the osd pan info */
-	nf->pan_x = yi->osd_x_pan;
-	nf->pan_y = yi->osd_y_pan;
-	nf->vis_w = yi->osd_vis_w;
-	nf->vis_h = yi->osd_vis_h;
-
 	nf->update = 0;
 	nf->interlaced_y = 0;
 	nf->interlaced_uv = 0;