Commit 3b5c1c8e authored by Ian Armstrong's avatar Ian Armstrong Committed by Mauro Carvalho Chehab

V4L/DVB (6716): ivtv: yuv interlace mode change

Interlace mode selection code moved into the frame setup phase, so it's now
run before the frame is loaded into a hardware buffer. Given that it can
affect how a new frame is displayed, it was a bit stupid running it after the
frame was already visible.

A few stray interlace related variables which were linked to individual frames
have now been moved into the yuv_frame_info struct. This means that all
variables linked to a specific frame are in the same place & not scattered.

Minor code reformatting in areas touched by the above changes.
Signed-off-by: default avatarIan Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 406c8b0f
......@@ -392,6 +392,9 @@ struct yuv_frame_info
u32 tru_h;
u32 offset_y;
s32 lace_mode;
u32 sync_field;
u32 delay;
u32 interlaced;
};
#define IVTV_YUV_MODE_INTERLACED 0x00
......@@ -465,8 +468,6 @@ struct yuv_playback_info
int decode_height;
int frame_interlaced;
int lace_mode;
int lace_threshold;
int lace_sync_field;
......@@ -477,8 +478,6 @@ struct yuv_playback_info
u32 yuv_forced_update;
int update_frame;
int sync_field[IVTV_YUV_BUFFERS]; /* Field to sync on */
int field_delay[IVTV_YUV_BUFFERS]; /* Flag to extend duration of previous frame */
u8 fields_lapsed; /* Counter used when delaying a frame */
struct yuv_frame_info new_frame_info[IVTV_YUV_BUFFERS];
......
......@@ -746,15 +746,16 @@ 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);
struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
if (((frame ^ yi->sync_field[last_dma_frame]) == 0 &&
((itv->last_vsync_field & 1) ^ yi->sync_field[last_dma_frame])) ||
(frame != (itv->last_vsync_field & 1) && !yi->frame_interlaced)) {
if (((frame ^ f->sync_field) == 0 &&
((itv->last_vsync_field & 1) ^ f->sync_field)) ||
(frame != (itv->last_vsync_field & 1) && !f->interlaced)) {
int next_dma_frame = last_dma_frame;
if (!(yi->frame_interlaced && yi->field_delay[next_dma_frame] && yi->fields_lapsed < 1)) {
if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) {
if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) {
write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
......@@ -795,13 +796,15 @@ static void ivtv_irq_vsync(struct ivtv *itv)
}
/* Check if we need to update the yuv registers */
if ((yi->yuv_forced_update || yi->new_frame_info[last_dma_frame].update) && last_dma_frame != -1) {
if (!yi->new_frame_info[last_dma_frame].update)
if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) {
if (!f->update) {
last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS;
f = &yi->new_frame_info[last_dma_frame];
}
if (yi->new_frame_info[last_dma_frame].src_w) {
if (f->src_w) {
yi->update_frame = last_dma_frame;
yi->new_frame_info[last_dma_frame].update = 0;
f->update = 0;
yi->yuv_forced_update = 0;
set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment