aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2008-04-22 13:42:14 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:44 -0400
commit88ab075aee974f70b7b0273a964810698c8a5b95 (patch)
tree7ef505be831d742b59fb8ed6f5d84a2894dc5ce9 /drivers/media/video/ivtv
parent520ebe5f72ff450d7a73e8f669190254a5836093 (diff)
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>
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c25
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c32
4 files changed, 38 insertions, 22 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index b533188c9439..d0bb5b18797a 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -711,6 +711,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
711 itv->yuv_info.lace_mode = ivtv_yuv_mode; 711 itv->yuv_info.lace_mode = ivtv_yuv_mode;
712 itv->yuv_info.lace_threshold = ivtv_yuv_threshold; 712 itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
713 itv->yuv_info.max_frames_buffered = 3; 713 itv->yuv_info.max_frames_buffered = 3;
714 itv->yuv_info.track_osd = 1;
714 return 0; 715 return 0;
715} 716}
716 717
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 536140f0c19e..ba06e813c58c 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -456,6 +456,8 @@ struct yuv_playback_info
456 int v_filter_2; 456 int v_filter_2;
457 int h_filter; 457 int h_filter;
458 458
459 u8 track_osd; /* Should yuv output track the OSD size & position */
460
459 u32 osd_x_offset; 461 u32 osd_x_offset;
460 u32 osd_y_offset; 462 u32 osd_y_offset;
461 463
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index edef2a579617..f562cbbadc16 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -712,6 +712,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
712int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) 712int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
713{ 713{
714 struct ivtv_open_id *id = NULL; 714 struct ivtv_open_id *id = NULL;
715 struct yuv_playback_info *yi = &itv->yuv_info;
715 u32 data[CX2341X_MBOX_MAX_DATA]; 716 u32 data[CX2341X_MBOX_MAX_DATA];
716 int streamtype = 0; 717 int streamtype = 0;
717 718
@@ -837,8 +838,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
837 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; 838 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
838 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; 839 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
839 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 840 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
840 cropcap->bounds.width = itv->yuv_info.osd_full_w; 841 if (yi->track_osd) {
841 cropcap->bounds.height = itv->yuv_info.osd_full_h; 842 cropcap->bounds.width = yi->osd_full_w;
843 cropcap->bounds.height = yi->osd_full_h;
844 } else {
845 cropcap->bounds.width = 720;
846 cropcap->bounds.height =
847 itv->is_out_50hz ? 576 : 480;
848 }
842 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; 849 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
843 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; 850 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
844 } else { 851 } else {
@@ -856,7 +863,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
856 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 863 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
857 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 864 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
858 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 865 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
859 itv->yuv_info.main_rect = crop->c; 866 yi->main_rect = crop->c;
860 return 0; 867 return 0;
861 } else { 868 } else {
862 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, 869 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
@@ -878,7 +885,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
878 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 885 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
879 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 886 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
880 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) 887 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
881 crop->c = itv->yuv_info.main_rect; 888 crop->c = yi->main_rect;
882 else 889 else
883 crop->c = itv->main_rect; 890 crop->c = itv->main_rect;
884 return 0; 891 return 0;
@@ -1070,11 +1077,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1070 itv->main_rect.height = itv->params.height; 1077 itv->main_rect.height = itv->params.height;
1071 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, 1078 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1072 720, itv->main_rect.height, 0, 0); 1079 720, itv->main_rect.height, 0, 0);
1073 itv->yuv_info.main_rect = itv->main_rect; 1080 yi->main_rect = itv->main_rect;
1074 if (!itv->osd_info) { 1081 if (!itv->osd_info) {
1075 itv->yuv_info.osd_full_w = 720; 1082 yi->osd_full_w = 720;
1076 itv->yuv_info.osd_full_h = 1083 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1077 itv->is_out_50hz ? 576 : 480;
1078 } 1084 }
1079 } 1085 }
1080 break; 1086 break;
@@ -1272,6 +1278,8 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1272 else 1278 else
1273 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; 1279 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1274 } 1280 }
1281 if (yi->track_osd)
1282 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1275 break; 1283 break;
1276 } 1284 }
1277 1285
@@ -1285,6 +1293,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1285 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; 1293 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1286 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; 1294 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1287 ivtv_set_osd_alpha(itv); 1295 ivtv_set_osd_alpha(itv);
1296 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
1288 break; 1297 break;
1289 } 1298 }
1290 1299
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 8fdd67cef74c..393d917cd672 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -718,9 +718,11 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
718 f->src_w -= (osd_scale * osd_crop) >> 16; 718 f->src_w -= (osd_scale * osd_crop) >> 16;
719 } 719 }
720 720
721 /* The OSD can be moved. Track to it */ 721 if (itv->yuv_info.track_osd) {
722 f->dst_x += itv->yuv_info.osd_x_offset; 722 /* The OSD can be moved. Track to it */
723 f->dst_y += itv->yuv_info.osd_y_offset; 723 f->dst_x += itv->yuv_info.osd_x_offset;
724 f->dst_y += itv->yuv_info.osd_y_offset;
725 }
724 726
725 /* Width & height for both src & dst must be even. 727 /* Width & height for both src & dst must be even.
726 Same for coordinates. */ 728 Same for coordinates. */
@@ -792,11 +794,19 @@ void ivtv_yuv_work_handler(struct ivtv *itv)
792 IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame); 794 IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
793 f = yi->new_frame_info[frame]; 795 f = yi->new_frame_info[frame];
794 796
795 /* Update the osd pan info */ 797 if (yi->track_osd) {
796 f.pan_x = yi->osd_x_pan; 798 /* Snapshot the osd pan info */
797 f.pan_y = yi->osd_y_pan; 799 f.pan_x = yi->osd_x_pan;
798 f.vis_w = yi->osd_vis_w; 800 f.pan_y = yi->osd_y_pan;
799 f.vis_h = yi->osd_vis_h; 801 f.vis_w = yi->osd_vis_w;
802 f.vis_h = yi->osd_vis_h;
803 } else {
804 /* Not tracking the osd, so assume full screen */
805 f.pan_x = 0;
806 f.pan_y = 0;
807 f.vis_w = 720;
808 f.vis_h = yi->decode_height;
809 }
800 810
801 /* Calculate the display window coordinates. Exit if nothing left */ 811 /* Calculate the display window coordinates. Exit if nothing left */
802 if (!(yuv_update = ivtv_yuv_window_setup(itv, &f))) 812 if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
@@ -965,12 +975,6 @@ static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
965 /* Are we going to offset the Y plane */ 975 /* Are we going to offset the Y plane */
966 nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0; 976 nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
967 977
968 /* Snapshot the osd pan info */
969 nf->pan_x = yi->osd_x_pan;
970 nf->pan_y = yi->osd_y_pan;
971 nf->vis_w = yi->osd_vis_w;
972 nf->vis_h = yi->osd_vis_h;
973
974 nf->update = 0; 978 nf->update = 0;
975 nf->interlaced_y = 0; 979 nf->interlaced_y = 0;
976 nf->interlaced_uv = 0; 980 nf->interlaced_uv = 0;