Skip to content

Commit

Permalink
V4L/DVB (9166): ivtv - Fix potential race condition in yuv handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ian Armstrong authored and Mauro Carvalho Chehab committed Oct 13, 2008
1 parent ec9faa1 commit 2bd7ac5
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 5 deletions.
2 changes: 2 additions & 0 deletions drivers/media/video/ivtv/ivtv-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ struct yuv_playback_info
struct v4l2_rect main_rect;
u32 v4l2_src_w;
u32 v4l2_src_h;

u8 running; /* Have any frames been displayed */
};

#define IVTV_VBI_FRAMES 32
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/video/ivtv/ivtv-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
itv->dma_data_req_size =
1080 * ((yi->v4l2_src_h + 31) & ~31);

/* Force update of yuv registers */
yi->yuv_forced_update = 1;
return 0;
}

Expand Down
9 changes: 6 additions & 3 deletions drivers/media/video/ivtv/ivtv-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
*/
unsigned int frame = read_reg(0x28c0) & 1;
struct yuv_playback_info *yi = &itv->yuv_info;
int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame);
int last_dma_frame = atomic_read(&yi->next_dma_frame);
struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];

if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
Expand All @@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
atomic_set(&yi->next_dma_frame, next_dma_frame);
yi->fields_lapsed = -1;
yi->running = 1;
}
}
}
Expand Down Expand Up @@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv)
}

/* Check if we need to update the yuv registers */
if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) {
if (yi->running && (yi->yuv_forced_update || f->update)) {
if (!f->update) {
last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS;
last_dma_frame =
(u8)(atomic_read(&yi->next_dma_frame) -
1) % IVTV_YUV_BUFFERS;
f = &yi->new_frame_info[last_dma_frame];
}

Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/ivtv/ivtv-yuv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv)
IVTV_DEBUG_YUV("ivtv_yuv_close\n");
ivtv_waitq(&itv->vsync_waitq);

yi->running = 0;
atomic_set(&yi->next_dma_frame, -1);
atomic_set(&yi->next_fill_frame, 0);

Expand Down

0 comments on commit 2bd7ac5

Please sign in to comment.