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