On Saturday 07 October 2006 22:19, Nicolas Huillard wrote:
> Hello,
>
> I'm a bit lost about what's needed for field parity correctness on
> TV-out with CLE266. I still have field artifacts on interlaced streams
> on TV-out.
>
> My setup :
> VDR 1.4.2
> softdevice CVS 20060929 (-P softdevice -ao alsa:pcm=default -vo
> dfb:viatv:cle266)
> libcle266mpegdec 0.4
> DirectFB-2006-09-10-04-25-09-UTC
> DFB++-2006-09-10-04-25-02-UTC
> linux-viafb 20060910 (viafb mode=720x576 bpp=32 refresh=50 TVon=1
> TVoverscan=1)
>
> I think I do not need any patches for linux-viafb (Mark Adams commited
> his patches to CVS)
> I don't know if I need something special in DirectFB/DFB++ (I applied
> libcle266mpegdec-0.3/patches/GetFBOffset.patch)
> I think the latest softdevice filed parity patches have joined CVS
> before I checked it out.

I have nicely working TV-out with CLE266. Looking back, I don't think I've 
updated DirectFB, DFB++, or linux-viafb since about April. I'm using 
libcle266mpegdec-0.4 with vdr-1.4.3 and softdevice CVS 04102006 
(-P'softdevice -vo dfb:viatv:cle266'). My options to viafb are: mode=720x576 
bpp=32 refresh=50 TVon=1 TVoverscan=1. Pretty much the same as you're doing!

However, you mention Mark Adams's patches: I have both viafb and DirectFB 
patched with his field-sync patches (attached).

I've just had a quick scan of the current CVS linux-viafb and can't see any 
obvious signs that they were added: at the time, I don't think Mark wanted to 
commit them because they were a quick bodge and he was going to do it 
properly. Having said that, it is possible that he has done so and that they 
are no longer needed with current CVS... It is a long while since he posted 
them so he has probably improved them by now, even if they haven't made CVS!

Last time I built DirectFB (which I'm sure was more recently than April!) I 
couldn't work out whether I needed the patches or not. Maybe I do!

With my setup, I don't see any noticeable interlace effects with TV-out. Some 
channels aren't quite perfect, i.e. scrolling text on BBC News 24 (a good 
test for this type of stuff!) gives the odd judder every second or so but is 
pretty good. Mark reckoned that this was probably down to a timing problem 
with triple buffering.

Maybe the patches will help your setup: since the hardware decoding has been 
in softdevice, my system has really impressed me, although recently it has 
decided to stop powering off / rebooting when shut down so I can't always 
trust nvram-wakeup!

:(

As to your other post about 352x288 streams, pass! Nothing on UK DVB-T is that 
low a resolution, so I cannot test this.

Cheers,

Laz
diff -u -p -r1.4 uc_overlay.c
--- uc_overlay.c	27 Oct 2005 15:56:28 -0000	1.4
+++ uc_overlay.c	4 Nov 2005 17:38:31 -0000
@@ -23,6 +23,22 @@
 
 #include <misc/conf.h>
 
+struct fb_flip {
+    __u32 device;
+    __u32 field;
+    __u32 count;
+    __u32 offset[6];
+};
+
+#define VIAFB_FLIP_GRAPHICS 0
+#define VIAFB_FLIP_V1 1
+#define VIAFB_FLIP_V3 2
+#define VIAFB_FLIP_SPIC 3
+
+#ifndef FBIO_FLIPONVSYNC
+#define FBIO_FLIPONVSYNC    _IOWR('F', 0x21, struct fb_flip)
+#endif
+
 // Forward declaration
 static DFBResult
 uc_ovl_remove(CoreLayer *layer,
@@ -116,6 +132,8 @@ uc_ovl_set_region( CoreLayer            
 {
     UcDriverData*  ucdrv = (UcDriverData*) driver_data;
     UcOverlayData* ucovl = (UcOverlayData*) layer_data;
+    FBDev *dfb_fbdev = dfb_system_data();
+    int field_option;
 
     /* remember configuration */
     ucovl->config = *config;
@@ -144,6 +162,9 @@ uc_ovl_set_region( CoreLayer            
     ucovl->deinterlace = config->options & DLOP_DEINTERLACING;
     ucovl->surface     = surface;
 
+    field_option = 3;	// wait for any pending flip to complete
+    ioctl(dfb_fbdev->fd, FBIO_WAITFORVSYNC, &field_option);
+    
     return uc_ovl_update(ucdrv, ucovl, UC_OVL_CHANGE, surface);
 }
 
@@ -254,6 +275,7 @@ uc_ovl_flip_region( CoreLayer           
 
     ucovl->field = 0;
 
+#if 0
     if (ucovl->config.options & DLOP_FIELD_PARITY)
     {
         int field_option;
@@ -272,6 +294,33 @@ uc_ovl_flip_region( CoreLayer           
     ret = uc_ovl_update(ucdrv, ucovl, UC_OVL_FLIP, surface);
     if (ret)
         return ret;
+#else
+    if (ucovl->config.options & DLOP_FIELD_PARITY)
+    {
+        struct fb_flip flip;
+        int field_option;
+        
+        field_option = 3;	// wait for last pending flip to complete
+        ioctl(dfb_fbdev->fd, FBIO_WAITFORVSYNC, &field_option);
+        
+        flip.device = VIAFB_FLIP_V1;
+        flip.field = ucovl->config.parity;
+        flip.count = 0;	// until we implement this
+        
+        uc_ovl_map_buffer(surface->format, surface->front_buffer->video.offset,
+            ucovl->v1.ox, ucovl->v1.oy, surface->width, surface->height,
+            surface->front_buffer->video.pitch, 0,
+            &flip.offset[0], &flip.offset[1], &flip.offset[2]);
+        
+        ioctl(dfb_fbdev->fd, FBIO_FLIPONVSYNC, &flip);
+    }
+    else
+    {
+        ret = uc_ovl_update(ucdrv, ucovl, UC_OVL_FLIP, surface);
+        if (ret)
+            return ret;
+    }
+#endif
 
     if (flags & DSFLIP_WAIT)
         dfb_layer_wait_vsync(layer);
diff -u -p -r1.3 via_fbobj.c
--- linux/drivers/video/cle266/via_fbobj.c	4 Nov 2005 12:39:38 -0000	1.3
+++ linux/drivers/video/cle266/via_fbobj.c	4 Nov 2005 17:40:14 -0000
@@ -48,6 +48,9 @@
 #ifndef FBIO_WAITFORVSYNC
 #define FBIO_WAITFORVSYNC   _IOW('F', 0x20, u_int32_t)
 #endif
+#ifndef FBIO_FLIPONVSYNC
+#define FBIO_FLIPONVSYNC    _IOWR('F', 0x21, struct fb_flip)
+#endif
 
 static struct fb_fix_screeninfo viafb_fix __initdata = {
     .id =       "UNICHROME", 
@@ -74,6 +77,12 @@ static struct via_par* current_par;
 #define t_inb(reg)          inb(reg)
 #endif
 
+#define V1_STARTADDR_0                  0x254
+#define V1_STARTADDR_CR0                0x2F0
+#define V1_STARTADDR_CB0                0x28C
+#define V_COMPOSE_MODE                  0x298
+#define V1_COMMAND_FIRE                 0x80000000
+
 #define VERSION     "1.0"
 
 int VIACheckTVExist(struct fb_info *info);
@@ -1262,6 +1271,10 @@ static int viafb_wait_for_sync(struct fb
     {
         ret = wait_event_interruptible_timeout(p->wq, (cnt != p->irq_cnt) && ((p->irq_cnt & 1)==1), HZ/10);
     }
+    else if (field_option == 3) // wait for any pending flip to complete
+    {
+        ret = wait_event_interruptible_timeout(p->wq, p->flip_pending == 0, HZ/10);
+    }
 
     if (ret < 0) {
         return ret;
@@ -1273,6 +1286,21 @@ static int viafb_wait_for_sync(struct fb
     return 0;
 }
 
+static int viafb_flip_on_sync(struct fb_info *info, struct fb_flip *flip)
+{
+    struct via_par * p = (struct via_par *)info->par;
+    
+    if (flip->device == VIAFB_FLIP_V1)
+    {
+        p->flip = *flip;
+        flip->field = p->irq_cnt % 2;
+        flip->count = p->irq_cnt / 2;
+        p->flip_pending = 1;
+        return 0;
+    }
+    return -EINVAL;
+}
+
 static int viafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
     unsigned long arg, struct fb_info *info)
 {
@@ -1286,6 +1314,23 @@ static int viafb_ioctl(struct inode *ino
             
             return viafb_wait_for_sync(info, field_option);
         }
+        case FBIO_FLIPONVSYNC:
+        {
+            struct fb_flip flip;
+            int err;
+
+            if (copy_from_user(&flip, (void __user *)arg, sizeof(flip)))
+                return -EFAULT;
+
+            err = viafb_flip_on_sync(info, &flip);
+            if (err)
+                return err;
+
+            if (copy_to_user((void __user *)arg, &flip, sizeof(flip)))
+                return -EFAULT;
+
+            return 0;
+        }
     }
 
     return -ENOTTY;
@@ -1303,6 +1348,14 @@ static irqreturn_t via_vga_irqhandler(in
         VIASETREG(p->io_base_virt, VIA_REG_INTERRUPT, status | VIA_IRQ_VBI_PENDING);
 
         p->irq_cnt++;
+        if (p->flip_pending && ((p->irq_cnt & 1) == p->flip.field))
+        {
+            VIASETREG(p->io_base_virt, V1_STARTADDR_0, p->flip.offset[0]);
+            VIASETREG(p->io_base_virt, V1_STARTADDR_CB0, p->flip.offset[1]);
+            VIASETREG(p->io_base_virt, V1_STARTADDR_CR0, p->flip.offset[2]);
+            VIASETREG(p->io_base_virt, V_COMPOSE_MODE, VIAGETREG(p->io_base_virt, V_COMPOSE_MODE)|V1_COMMAND_FIRE);
+            p->flip_pending = 0;
+        }
         wake_up_interruptible(&p->wq);
         handled = 1;
     }
@@ -1532,6 +1585,8 @@ static int __devinit via_pci_probe(struc
     current_par->TVoverscan = TVoverscan;
     current_par->TVEncoder = TVEncoder;
     
+    current_par->flip_pending = 0;
+    
     if (TVon) {
         VIACheckTVExist(info);
         if (default_xres==640 && default_yres==480)
diff -u -p -r1.2 via_fbobj.h
--- linux/drivers/video/cle266/via_fbobj.h	4 Nov 2005 12:39:38 -0000	1.2
+++ linux/drivers/video/cle266/via_fbobj.h	4 Nov 2005 17:40:14 -0000
@@ -33,6 +33,18 @@
 
 #define CLE266          0x3122
 
+struct fb_flip {
+    u32 device;
+    u32 field;
+    u32 count;
+    u32 offset[6];
+};
+
+#define VIAFB_FLIP_GRAPHICS 0
+#define VIAFB_FLIP_V1 1
+#define VIAFB_FLIP_V3 2
+#define VIAFB_FLIP_SPIC 3
+
 /* 
  * This structure defines the hardware state of the graphics card. Normally
  * you place this in a header file in linux/include/video. This file usually
@@ -69,6 +81,9 @@ struct via_par {
     wait_queue_head_t wq;
     
     int vclk;       // in MHz
+    
+    struct fb_flip flip;
+    int flip_pending;
 };
 
 #define VIASETREG(mmio, addr, data)   *(volatile u32 *)((mmio) +(addr)) = (data)
_______________________________________________
Softdevice-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/softdevice-devel

Reply via email to