u32 tru_w;
        u32 tru_h;
        u32 offset_y;
+       int lace_mode;
 };
 
 #define IVTV_YUV_MODE_INTERLACED       0x00
        int decode_height;
 
        int frame_interlaced;
-       int frame_interlaced_last;
 
        int lace_mode;
        int lace_threshold;
 
        u32 yuv_forced_update;
        int update_frame;
+
+       int sync_field[4];  /* Field to sync on */
+       int field_delay[4]; /* Flag to extend duration of previous frame */
+       u8 fields_lapsed;   /* Counter used when delaying a frame */
+
        struct yuv_frame_info new_frame_info[4];
        struct yuv_frame_info old_frame_info;
        struct yuv_frame_info old_frame_info_args;
 
 
        if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
 
-       if (((frame ^ itv->yuv_info.lace_sync_field) == 0 && ((itv->lastVsyncFrame & 1) ^ itv->yuv_info.lace_sync_field)) ||
+       if (((frame ^ itv->yuv_info.sync_field[last_dma_frame]) == 0 &&
+               ((itv->lastVsyncFrame & 1) ^ itv->yuv_info.sync_field[last_dma_frame])) ||
                        (frame != (itv->lastVsyncFrame & 1) && !itv->yuv_info.frame_interlaced)) {
                int next_dma_frame = last_dma_frame;
 
-               if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&itv->yuv_info.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);
-                       write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
-                       write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
-                       next_dma_frame = (next_dma_frame + 1) & 0x3;
-                       atomic_set(&itv->yuv_info.next_dma_frame, next_dma_frame);
+               if (!(itv->yuv_info.frame_interlaced && itv->yuv_info.field_delay[next_dma_frame] && itv->yuv_info.fields_lapsed < 1)) {
+                       if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&itv->yuv_info.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);
+                               write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
+                               write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
+                               next_dma_frame = (next_dma_frame + 1) & 0x3;
+                               atomic_set(&itv->yuv_info.next_dma_frame, next_dma_frame);
+                               itv->yuv_info.fields_lapsed = -1;
+                       }
                }
        }
        if (frame != (itv->lastVsyncFrame & 1)) {
                                set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                        }
                }
+
+               itv->yuv_info.fields_lapsed ++;
        }
 }
 
 
                itv->yuv_info.v_filter_2 = v_filter_2;
        }
 
-       itv->yuv_info.frame_interlaced_last = itv->yuv_info.frame_interlaced;
 }
 
 /* Modify the supplied coordinate information to fit the visible osd area */
            (itv->yuv_info.old_frame_info.src_y != window->src_y) ||
            (itv->yuv_info.old_frame_info.pan_y != window->pan_y) ||
            (itv->yuv_info.old_frame_info.vis_h != window->vis_h) ||
+           (itv->yuv_info.old_frame_info.lace_mode != window->lace_mode) ||
            (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) ||
            (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) {
                yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
        itv->yuv_info.new_frame_info[frame].tru_w = args->src_width;
        itv->yuv_info.new_frame_info[frame].tru_h = args->src_height;
 
+       /* Snapshot field order */
+       itv->yuv_info.sync_field[frame] = itv->yuv_info.lace_sync_field;
+
        /* Are we going to offset the Y plane */
        if (args->src.height + args->src.top < 512-16)
                itv->yuv_info.new_frame_info[frame].offset_y = 1;
        itv->yuv_info.new_frame_info[frame].update = 0;
        itv->yuv_info.new_frame_info[frame].interlaced_y = 0;
        itv->yuv_info.new_frame_info[frame].interlaced_uv = 0;
+       itv->yuv_info.new_frame_info[frame].lace_mode = itv->yuv_info.lace_mode;
 
        if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame],
            sizeof (itv->yuv_info.new_frame_info[frame]))) {
 
        itv->yuv_info.new_frame_info[frame].update |= register_update;
 
+       /* Should this frame be delayed ? */
+       if (itv->yuv_info.sync_field[frame] != itv->yuv_info.sync_field[(frame - 1) & 3])
+               itv->yuv_info.field_delay[frame] = 1;
+       else
+               itv->yuv_info.field_delay[frame] = 0;
+
        /* DMA the frame */
        mutex_lock(&itv->udma.lock);