[MPlayer-dev-eng] [PATCH] mga_vid support for interlaced video modes

D Richard Felker III dalias at aerifal.cx
Sun Jan 12 04:39:11 CET 2003


And it would help it I attached the patch!! Arrg!

Rich


On Sat, Jan 11, 2003 at 10:32:09PM -0500, D Richard Felker III wrote:
> Here's a somewhat preliminary patch to add support for interlaced
> video modes to the mga_vid driver. This is especially useful since tv
> is interlaced. The G200 manual says the BES doesn't support interlaced
> modes and it's not supposed to, but this trickery makes it work.
> 
> A few important issues still remain though...
> 
> 1) I don't like probing for interlaced mode in the mga_vid_set_config
>    function. Ideally this should be configured by the client program,
>    especially since it's something of a hack, but I didn't want to
>    make the ioctl interface incompatible. Of course at some point I
>    think new features do need to be added to the interface anyway...
>    For instance the BES supports deinterlacing in hardware, which we
>    should use!
> 
> 2) Interlace support works by muddling with the pitch and buffer
>    pointers at every vblank. This requires using the irq support in
>    mga_vid, which was disabled by default. It works, but if you switch
>    virtual consoles while it's running the stupid matroxfb driver goes
>    and kills your interrupt setup and then pages don't get flipped at
>    all. This is bad. I'm not sure how to properly work around the
>    problem. Also I don't know if/how using the irq conflicts with DRM
>    stuff for GLX users.
> 
> 3) I have no idea how to get the current field number from the G200
>    when in interlaced mode, so you have a 50% chance of having your
>    fields displayed backwards every time around. This is bad, but
>    pressing f to toggle fullscreen a few times usually gets you the
>    right field order before it's over. Still there should be a better
>    way...
> 
> If anyone wants to help put the finishing touches on this patch, I'd
> really appreciate it (either help with coding or just some info on the
> hardware that I could use to work around the above problems). Ideas,
> anyone?
> 
> Rich
> 
> 
> 
> 
> 
> _______________________________________________
> MPlayer-dev-eng mailing list
> MPlayer-dev-eng at mplayerhq.hu
> http://mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
-------------- next part --------------
Index: mga_vid.c
===================================================================
RCS file: /cvsroot/mplayer/main/drivers/mga_vid.c,v
retrieving revision 1.48
diff -u -r1.48 mga_vid.c
--- mga_vid.c	25 Jul 2002 21:34:24 -0000	1.48
+++ mga_vid.c	12 Jan 2003 03:15:14 -0000
@@ -7,7 +7,7 @@
 // Set this value, if autodetection fails! (video ram size in megabytes)
 // #define MGA_MEMORY_SIZE 16
 
-//#define MGA_ALLOW_IRQ
+#define MGA_ALLOW_IRQ
 
 #define MGA_VSYNC_POS 2
 
@@ -373,6 +373,7 @@
 #define STATUS      0x1e14
 
 static int mga_next_frame=0;
+static int mga_laced, mga_laced_field;
 
 #ifdef CRTC2
 static void crtc2_frame_sel(int frame)
@@ -656,7 +657,7 @@
 
 static int mga_vid_set_config(mga_vid_config_t *config)
 {
-	int x, y, sw, sh, dw, dh;
+	int x, y, sw, sh, dw, dh, lace;
 	int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights;
 	int frame_size=config->frame_size;
 #ifdef CRTC2
@@ -682,6 +683,8 @@
 	sh = config->src_height;
 	dw = config->dest_width;
 	dh = config->dest_height;
+	writeb(0, mga_mmio_base + 0x1fde);
+	lace = readb(mga_mmio_base + 0x1fdf) & 0x80;
 
 #ifdef MP_DEBUG
 	printk(KERN_DEBUG "mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d) format %X\n",
@@ -760,6 +763,13 @@
 	printk(KERN_ERR "mga_vid: Unsupported pixel format: 0x%X\n",config->format);
 	return -1;
 }
+	if (lace) {
+		if (mga_irq != -1) sh /= 2;
+		dh /= 2;
+		y /= 2;
+		mga_laced = 1;
+	}
+	else mga_laced = 0;
 
 	// setting black&white mode 
 	regs.besctl|=(regs.blackie<<20); 
@@ -779,6 +789,7 @@
 	//Setup source dimensions
 	regs.beshsrclst  = (sw - 1) << 16;
 	regs.bespitch = (sw + 31) & ~31 ; 
+	if (lace && mga_irq != -1) regs.bespitch *= 2;
 	
 	//Setup horizontal scaling
 	ifactor = ((sw-1)<<14)/(dw-1);
@@ -1064,24 +1075,29 @@
 
 static void enable_irq(){
 	long int cc;
+	unsigned char b;
 
 	cc = readl(mga_mmio_base + IEN);
 //	printk(KERN_ALERT "*** !!! IRQREG = %d\n", (int)(cc&0xff));
 
 	writeb( 0x11, mga_mmio_base + CRTCX);
-	
-	writeb(0x20, mga_mmio_base + CRTCD );  /* clear 0, enable off */
-	writeb(0x00, mga_mmio_base + CRTCD );  /* enable on */
-	writeb(0x10, mga_mmio_base + CRTCD );  /* clear = 1 */
+
+	mga_laced_field = 0;
+	b = readb(mga_mmio_base + CRTCD) & 0x0f;
+	writeb(0x20|b, mga_mmio_base + CRTCD );  /* clear 0, enable off */
+	writeb(0x00|b, mga_mmio_base + CRTCD );  /* enable on */
+	writeb(0x10|b, mga_mmio_base + CRTCD );  /* clear = 1 */
 	
 	writel( regs.besglobctl , mga_mmio_base + BESGLOBCTL);
 
 }
 
 static void disable_irq(){
+	unsigned char b;
 
 	writeb( 0x11, mga_mmio_base + CRTCX);
-	writeb(0x20, mga_mmio_base + CRTCD );  /* clear 0, enable off */
+	b = readb(mga_mmio_base + CRTCD) & 0x0f;
+	writeb(0x20|b, mga_mmio_base + CRTCD );  /* clear 0, enable off */
 
 }
 
@@ -1089,6 +1105,7 @@
 //	static int frame=0;
 //	static int counter=0;
 	long int cc;
+	unsigned char b;
 //	if ( ! mga_enabled_flag ) return;
 
 //	printk(KERN_DEBUG "vcount = %d\n",readl(mga_mmio_base + VCOUNT));
@@ -1122,6 +1139,20 @@
 	}
 */
 
+	if (mga_laced) {
+		if (regs.besctl & (1<<17)) { /* planar 4:2:0 */
+			writel(regs.besa1org + regs.bespitch/2*mga_laced_field, mga_mmio_base + BESA1ORG);
+			writel(regs.besa2org + regs.bespitch/2*mga_laced_field, mga_mmio_base + BESA2ORG);
+			writel(regs.besb1org + regs.bespitch/2*mga_laced_field, mga_mmio_base + BESB1ORG);
+			writel(regs.besb2org + regs.bespitch/2*mga_laced_field, mga_mmio_base + BESB2ORG);
+		} else { /* packed 4:2:2 */
+			writel(regs.besa1org + regs.bespitch*mga_laced_field, mga_mmio_base + BESA1ORG);
+			writel(regs.besa2org + regs.bespitch*mga_laced_field, mga_mmio_base + BESA2ORG);
+			writel(regs.besb1org + regs.bespitch*mga_laced_field, mga_mmio_base + BESB1ORG);
+			writel(regs.besb2org + regs.bespitch*mga_laced_field, mga_mmio_base + BESB2ORG);
+		}
+		mga_laced_field ^= 1;
+	}
 //	frame=(frame+1)&1;
 	regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25);
 	writel( regs.besctl, mga_mmio_base + BESCTL ); 
@@ -1144,8 +1175,9 @@
 
 	if ( irq != -1 ) {
 		writeb( 0x11, mga_mmio_base + CRTCX);
-		writeb( 0, mga_mmio_base + CRTCD );
-		writeb( 0x10, mga_mmio_base + CRTCD );
+		b = readb(mga_mmio_base + CRTCD) & 0x0f;
+		writeb( 0|b, mga_mmio_base + CRTCD );
+		writeb( 0x10|b, mga_mmio_base + CRTCD );
 	}
 
 //	writel( regs.besglobctl, mga_mmio_base + BESGLOBCTL);


More information about the MPlayer-dev-eng mailing list