mirror of
https://github.com/torvalds/linux.git
synced 2024-12-12 14:12:51 +00:00
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>
This commit is contained in:
parent
ec9faa1cfa
commit
2bd7ac55c3
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user