提交 2bd7ac55 编写于 作者: I Ian Armstrong 提交者: Mauro Carvalho Chehab

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: NIan Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 ec9faa1c
...@@ -506,6 +506,8 @@ struct yuv_playback_info ...@@ -506,6 +506,8 @@ struct yuv_playback_info
struct v4l2_rect main_rect; struct v4l2_rect main_rect;
u32 v4l2_src_w; u32 v4l2_src_w;
u32 v4l2_src_h; u32 v4l2_src_h;
u8 running; /* Have any frames been displayed */
}; };
#define IVTV_VBI_FRAMES 32 #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 ...@@ -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 = itv->dma_data_req_size =
1080 * ((yi->v4l2_src_h + 31) & ~31); 1080 * ((yi->v4l2_src_h + 31) & ~31);
/* Force update of yuv registers */
yi->yuv_forced_update = 1;
return 0; return 0;
} }
......
...@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) ...@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
*/ */
unsigned int frame = read_reg(0x28c0) & 1; unsigned int frame = read_reg(0x28c0) & 1;
struct yuv_playback_info *yi = &itv->yuv_info; 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]; struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
...@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) ...@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
atomic_set(&yi->next_dma_frame, next_dma_frame); atomic_set(&yi->next_dma_frame, next_dma_frame);
yi->fields_lapsed = -1; yi->fields_lapsed = -1;
yi->running = 1;
} }
} }
} }
...@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv) ...@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv)
} }
/* Check if we need to update the yuv registers */ /* 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) { 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]; f = &yi->new_frame_info[last_dma_frame];
} }
......
...@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv) ...@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv)
IVTV_DEBUG_YUV("ivtv_yuv_close\n"); IVTV_DEBUG_YUV("ivtv_yuv_close\n");
ivtv_waitq(&itv->vsync_waitq); ivtv_waitq(&itv->vsync_waitq);
yi->running = 0;
atomic_set(&yi->next_dma_frame, -1); atomic_set(&yi->next_dma_frame, -1);
atomic_set(&yi->next_fill_frame, 0); atomic_set(&yi->next_fill_frame, 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册