diff options
author | Ian Armstrong <ian@iarmst.demon.co.uk> | 2008-10-09 11:04:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-13 07:08:30 -0400 |
commit | 2bd7ac55c31cb4f42e331d69dde9fc034a68944f (patch) | |
tree | c2547fc93abd5e35a33ed6876faa3b3d724f4c23 /drivers/media | |
parent | ec9faa1cfac1dd64a2a865dc7c577f3d483656bd (diff) |
V4L/DVB (9166): ivtv - Fix potential race condition in yuv handler
Modified yuv register update handling to remove a potential race condition
which could occur with the first video frame.
Also removed a forced yuv position update, since changing the source video
dimensions or interlace settings doesn't affect the frame already being
displayed.
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@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 1 |
4 files changed, 9 insertions, 5 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index be2d779dba12..bc29436e8a3c 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -506,6 +506,8 @@ struct yuv_playback_info | |||
506 | struct v4l2_rect main_rect; | 506 | struct v4l2_rect main_rect; |
507 | u32 v4l2_src_w; | 507 | u32 v4l2_src_w; |
508 | u32 v4l2_src_h; | 508 | u32 v4l2_src_h; |
509 | |||
510 | u8 running; /* Have any frames been displayed */ | ||
509 | }; | 511 | }; |
510 | 512 | ||
511 | #define IVTV_VBI_FRAMES 32 | 513 | #define IVTV_VBI_FRAMES 32 |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 3c2628a63015..8696527ab134 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -644,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f | |||
644 | itv->dma_data_req_size = | 644 | itv->dma_data_req_size = |
645 | 1080 * ((yi->v4l2_src_h + 31) & ~31); | 645 | 1080 * ((yi->v4l2_src_h + 31) & ~31); |
646 | 646 | ||
647 | /* Force update of yuv registers */ | ||
648 | yi->yuv_forced_update = 1; | ||
649 | return 0; | 647 | return 0; |
650 | } | 648 | } |
651 | 649 | ||
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 34f3ab827858..f5d00ec5da73 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
753 | */ | 753 | */ |
754 | unsigned int frame = read_reg(0x28c0) & 1; | 754 | unsigned int frame = read_reg(0x28c0) & 1; |
755 | struct yuv_playback_info *yi = &itv->yuv_info; | 755 | struct yuv_playback_info *yi = &itv->yuv_info; |
756 | int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); | 756 | int last_dma_frame = atomic_read(&yi->next_dma_frame); |
757 | struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; | 757 | struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; |
758 | 758 | ||
759 | if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); | 759 | if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); |
@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
772 | next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; | 772 | next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; |
773 | atomic_set(&yi->next_dma_frame, next_dma_frame); | 773 | atomic_set(&yi->next_dma_frame, next_dma_frame); |
774 | yi->fields_lapsed = -1; | 774 | yi->fields_lapsed = -1; |
775 | yi->running = 1; | ||
775 | } | 776 | } |
776 | } | 777 | } |
777 | } | 778 | } |
@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
804 | } | 805 | } |
805 | 806 | ||
806 | /* Check if we need to update the yuv registers */ | 807 | /* Check if we need to update the yuv registers */ |
807 | if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { | 808 | if (yi->running && (yi->yuv_forced_update || f->update)) { |
808 | if (!f->update) { | 809 | if (!f->update) { |
809 | last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; | 810 | last_dma_frame = |
811 | (u8)(atomic_read(&yi->next_dma_frame) - | ||
812 | 1) % IVTV_YUV_BUFFERS; | ||
810 | f = &yi->new_frame_info[last_dma_frame]; | 813 | f = &yi->new_frame_info[last_dma_frame]; |
811 | } | 814 | } |
812 | 815 | ||
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 3092ff1d00a0..ee91107376c7 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv) | |||
1147 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); | 1147 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); |
1148 | ivtv_waitq(&itv->vsync_waitq); | 1148 | ivtv_waitq(&itv->vsync_waitq); |
1149 | 1149 | ||
1150 | yi->running = 0; | ||
1150 | atomic_set(&yi->next_dma_frame, -1); | 1151 | atomic_set(&yi->next_dma_frame, -1); |
1151 | atomic_set(&yi->next_fill_frame, 0); | 1152 | atomic_set(&yi->next_fill_frame, 0); |
1152 | 1153 | ||