aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-yuv.c
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2007-08-03 09:01:39 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:04:29 -0400
commitbfd7beacff2b5c811badb587a74c3dfbf7f98721 (patch)
tree47628dfa13bc221e2a5466934830ca54a6f46bc0 /drivers/media/video/ivtv/ivtv-yuv.c
parent943e8910db31e36d945f2bf7d4c273ca5fa01f6e (diff)
V4L/DVB (5973): ivtv: attach yuv field order to each frame
In the current driver, the field order is global. As soon as it's changed it takes immediate effect. This is a problem when the video changes order mid stream. Although it mostly works okay, the video may judder / flicker. This patch attaches the field order to the frame, so that any buffered frames will not be displayed until the correct field. In the event that the field order is changed mid stream, the driver will ensure that the previous frame is displayed for a minimum of 3 fields. These are the two original fields the frame should have occupied, plus the one extra since the new frame still has to wait for the correct field. 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/ivtv-yuv.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 5c94d3282c82..fa8c76f3d359 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -612,7 +612,6 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
612 itv->yuv_info.v_filter_2 = v_filter_2; 612 itv->yuv_info.v_filter_2 = v_filter_2;
613 } 613 }
614 614
615 itv->yuv_info.frame_interlaced_last = itv->yuv_info.frame_interlaced;
616} 615}
617 616
618/* Modify the supplied coordinate information to fit the visible osd area */ 617/* Modify the supplied coordinate information to fit the visible osd area */
@@ -799,6 +798,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
799 (itv->yuv_info.old_frame_info.src_y != window->src_y) || 798 (itv->yuv_info.old_frame_info.src_y != window->src_y) ||
800 (itv->yuv_info.old_frame_info.pan_y != window->pan_y) || 799 (itv->yuv_info.old_frame_info.pan_y != window->pan_y) ||
801 (itv->yuv_info.old_frame_info.vis_h != window->vis_h) || 800 (itv->yuv_info.old_frame_info.vis_h != window->vis_h) ||
801 (itv->yuv_info.old_frame_info.lace_mode != window->lace_mode) ||
802 (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) || 802 (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) ||
803 (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) { 803 (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) {
804 yuv_update |= IVTV_YUV_UPDATE_VERTICAL; 804 yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
@@ -970,6 +970,9 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
970 itv->yuv_info.new_frame_info[frame].tru_w = args->src_width; 970 itv->yuv_info.new_frame_info[frame].tru_w = args->src_width;
971 itv->yuv_info.new_frame_info[frame].tru_h = args->src_height; 971 itv->yuv_info.new_frame_info[frame].tru_h = args->src_height;
972 972
973 /* Snapshot field order */
974 itv->yuv_info.sync_field[frame] = itv->yuv_info.lace_sync_field;
975
973 /* Are we going to offset the Y plane */ 976 /* Are we going to offset the Y plane */
974 if (args->src.height + args->src.top < 512-16) 977 if (args->src.height + args->src.top < 512-16)
975 itv->yuv_info.new_frame_info[frame].offset_y = 1; 978 itv->yuv_info.new_frame_info[frame].offset_y = 1;
@@ -985,6 +988,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
985 itv->yuv_info.new_frame_info[frame].update = 0; 988 itv->yuv_info.new_frame_info[frame].update = 0;
986 itv->yuv_info.new_frame_info[frame].interlaced_y = 0; 989 itv->yuv_info.new_frame_info[frame].interlaced_y = 0;
987 itv->yuv_info.new_frame_info[frame].interlaced_uv = 0; 990 itv->yuv_info.new_frame_info[frame].interlaced_uv = 0;
991 itv->yuv_info.new_frame_info[frame].lace_mode = itv->yuv_info.lace_mode;
988 992
989 if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame], 993 if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame],
990 sizeof (itv->yuv_info.new_frame_info[frame]))) { 994 sizeof (itv->yuv_info.new_frame_info[frame]))) {
@@ -995,6 +999,12 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
995 999
996 itv->yuv_info.new_frame_info[frame].update |= register_update; 1000 itv->yuv_info.new_frame_info[frame].update |= register_update;
997 1001
1002 /* Should this frame be delayed ? */
1003 if (itv->yuv_info.sync_field[frame] != itv->yuv_info.sync_field[(frame - 1) & 3])
1004 itv->yuv_info.field_delay[frame] = 1;
1005 else
1006 itv->yuv_info.field_delay[frame] = 0;
1007
998 /* DMA the frame */ 1008 /* DMA the frame */
999 mutex_lock(&itv->udma.lock); 1009 mutex_lock(&itv->udma.lock);
1000 1010