On Monday 14 August 2006 15:31, Nicolas Dély wrote:
> 2006/7/11, Per Mellander <[EMAIL PROTECTED]>:
> > I've written some kind of a HOWTO for making use of the CLE266 hardware
> > decoding with softdevice. Could you ( Laz, Martin, Stefan etc. ) take a
> > look and comment before I drop the link on vdr ml?
> >
> > http://www.mellander.org/per/projects/linux/?chapter=epia-hw-cle266
>
> Thank you very much for your howto.
>
> I also had pached linux-viafb in order to add hardware ids
>
> to be very detailed your howto is missing:
> * "./configure" before libcle266mpegdec "make"
> * "./autogen.sh" before DirectFB "./configure" or replace "./configure
> --with-gfxdrivers=cle266,unichrome" by "./autogen.sh
> --with-gfxdrivers=cle266,unichrome"
>
> Unfortunately when I demonstated my set top box to my bosses, they
> told me that deinterlacing was "bottom first" or something like that,
> though it should be "top first" meaning that bottom frames are
> displayed before top frames. On interlaced videos, there are slow
> movements. I hope someone understand my troubles.
I _think_ that without Mark Adams's field-sync patches to viafb and DirectFB
(posted on the directfb-users or -dev list), the field order is random for
each bootup due to a timing issue. With the patches, I think it keeps track
of the field order. I use this setup with an interlaced TV and it works fine
for me (or I've not noticed jagged lines form reversed field lines).
As I say, I think that's what the patches do...they might not even be needed
these days! It was a while back that I applied them and I've forgotten why I
needed them!
I've attached the two of them (as I said, it's been a while since I've had to
apply them so they might need a bit of coaxing with current versions of viafb
and DirectFB!).
Cheers,
Laz
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)
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);
_______________________________________________
Softdevice-devel mailing list
[email protected]
http://bat.berlios.de/mailman/listinfo/softdevice-devel