On Tue, Feb 01, 2005 at 12:02:13AM +0000, Tony Houghton wrote:
> In <[EMAIL PROTECTED]>, Ville Syrj�l� wrote:
>
> > On Sun, Jan 30, 2005 at 12:39:07PM +0200, Tomi Hautakoski wrote:
> > >
> > > The command is mplayer -vo dfbmga:fieldparity=top:buffermode=triple:input
> > > -fs -vsync and without the -vsync av-sync is perfect but the picture is
> > > unviewable. Any ideas?
> >
> > Drop the -vsync option. Using it makes triple buffering effectively
> > double buffering. Maybe you need to use fieldparity=bottom to get a good
> > picture.
>
> I've just tried without vsync and it looks like it's needed to make the
> fieldparity work. That makes sense, because how could fieldparity sync
> the video frames to the correct output frames if it's not doing any
> syncing at all?
Fieldparity does wait for vsync if needed (that's all it does actually).
My guess is that it fails because the actual ioctl() calls' user<->kernel
transitions are too slow or some unfortunately timed scheduling happens.
I've attached two hackish patches (one for the kernel and the other for
DirectFB) that move field parity handling completely to the kernel. That
should guarantee better timing. Give them a try and see if they help.
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
--- matrox_crtc2.c 20 Nov 2004 21:18:08 -0000 1.29
+++ matrox_crtc2.c 1 Feb 2005 03:54:41 -0000
@@ -270,6 +269,20 @@
return DFB_OK;
}
+#define C2ADDR_WAIT_FIELD 0x1
+#define C2ADDR_WAIT_FLIP 0x2
+struct matroxioc_crtc2_address {
+ __u32 flags;
+ __u32 field;
+ __u32 startadd0;
+ __u32 startadd1;
+ __u32 pl2startadd0;
+ __u32 pl2startadd1;
+ __u32 pl3startadd0;
+ __u32 pl3startadd1;
+};
+#define MATROXFB_CRTC2_ADDRESS _IOW('n', 0xFC, struct matroxioc_crtc2_address)
+
static DFBResult
crtc2FlipRegion( CoreLayer *layer,
void *driver_data,
@@ -282,17 +295,10 @@
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
volatile __u8 *mmio = mdrv->mmio_base;
- int vdisplay = (dfb_config->matrox_ntsc ? 480/2 :
576/2) + 2;
- int line;
-
dfb_surface_flip_buffers( surface, false );
crtc2_calc_buffer( mdrv, mcrtc2, surface );
- line = mga_in32( mmio, C2VCOUNT ) & 0x00000FFF;
- if (line + 6 > vdisplay && line < vdisplay)
- while ((int)(mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != vdisplay)
- ;
-
+#if 0
if (mcrtc2->config.options & DLOP_FIELD_PARITY) {
int field = (mga_in32( mmio, C2VCOUNT ) >> 24) & 0x1;
@@ -306,6 +312,28 @@
if (flags & DSFLIP_WAIT)
dfb_screen_wait_vsync( mdrv->secondary );
+#else
+ {
+ FBDev *dfb_fbdev = dfb_system_data();
+ struct matroxioc_crtc2_address addr;
+
+ addr.flags = 0;
+ if (mcrtc2->config.options & DLOP_FIELD_PARITY)
+ addr.flags |= C2ADDR_WAIT_FIELD;
+ if (flags & DSFLIP_WAIT)
+ addr.flags |= C2ADDR_WAIT_FLIP;
+ addr.field = mcrtc2->field;
+ addr.startadd0 = mcrtc2->regs.c2STARTADD0;
+ addr.startadd1 = mcrtc2->regs.c2STARTADD1;
+ addr.pl2startadd0 = mcrtc2->regs.c2PL2STARTADD0;
+ addr.pl2startadd1 = mcrtc2->regs.c2PL2STARTADD1;
+ addr.pl3startadd0 = mcrtc2->regs.c2PL3STARTADD0;
+ addr.pl3startadd1 = mcrtc2->regs.c2PL3STARTADD1;
+
+ if (ioctl( dfb_fbdev->fd, MATROXFB_CRTC2_ADDRESS, &addr ))
+ D_ERROR( "CRTC2 address ioctl failed\n" );
+ }
+#endif
return DFB_OK;
}
--- linux/drivers/video/matrox/matroxfb_base.c 2004-11-04 22:18:33.000000000
+0200
+++ linux/drivers/video/matrox/matroxfb_base.c 2005-02-01 05:46:44.000000000
+0200
@@ -302,6 +300,61 @@
return 0;
}
+#define C2ADDR_WAIT_FIELD 0x1
+#define C2ADDR_WAIT_FLIP 0x2
+
+struct matroxioc_crtc2_address {
+ u32 flags;
+ u32 field;
+ u32 startadd0;
+ u32 startadd1;
+ u32 pl2startadd0;
+ u32 pl2startadd1;
+ u32 pl3startadd0;
+ u32 pl3startadd1;
+};
+
+#define MATROXFB_CRTC2_ADDRESS _IOW('n', 0xFC, struct matroxioc_crtc2_address)
+
+int matroxfb_crtc2_address(WPMINFO struct matroxioc_crtc2_address *addr) {
+ struct matrox_vsync *vs = &ACCESS_FBINFO(crtc2.vsync);
+ unsigned int tmp;
+ int vbl, ret;
+
+ vbl = (addr->flags & (C2ADDR_WAIT_FIELD | C2ADDR_WAIT_FLIP)) &&
!matroxfb_enable_irq(PMINFO 0);
+
+ if (vbl && addr->flags & C2ADDR_WAIT_FIELD) {
+ tmp = addr->field;
+ ret = wait_event_interruptible_timeout(vs->wait, tmp !=
((mga_inl(0x3C48) >> 24) & 1), HZ/10);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ matroxfb_enable_irq(PMINFO 1);
+ return -ETIMEDOUT;
+ }
+ }
+
+ mga_outl(0x3C28, addr->startadd0);
+ mga_outl(0x3C2C, addr->startadd1);
+ mga_outl(0x3C30, addr->pl2startadd0);
+ mga_outl(0x3C34, addr->pl2startadd1);
+ mga_outl(0x3C38, addr->pl3startadd0);
+ mga_outl(0x3C3C, addr->pl3startadd1);
+
+ if (vbl && addr->flags & C2ADDR_WAIT_FLIP) {
+ tmp = vs->cnt;
+ ret = wait_event_interruptible_timeout(vs->wait, tmp !=
vs->cnt, HZ/10);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ matroxfb_enable_irq(PMINFO 1);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
/* --------------------------------------------------------------------- */
static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
@@ -909,6 +963,14 @@
return matroxfb_wait_for_sync(PMINFO crt);
}
+ case MATROXFB_CRTC2_ADDRESS:
+ {
+ struct matroxioc_crtc2_address addr;
+
+ if (copy_from_user(&addr, argp, sizeof(addr)))
+ return -EFAULT;
+ return matroxfb_crtc2_address(PMINFO &addr);
+ }
case MATROXFB_SET_OUTPUT_MODE:
{
struct matroxioc_output_mode mom;