[patch] Xvideo v4l module -- testers wanted.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



  Hi,

I finally found some time to go over the v4l patch.  I've cleaned it up
a bit (move yuv detection stuff into a function, loop instead of
cut+paste, ...).  It survived the ItWorksForMe[tm] test, but I'd like to
know whenever it still works for the dvb people before I send it the way
to the xfree86 cvs ...

  Gerd

==============================[ cut here ]==============================
diff -ur /home/my-cvs/xfree86/xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c
--- /home/my-cvs/xfree86/xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c	Thu Nov  1 12:23:10 2001
+++ xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c	Fri Mar  1 12:22:50 2002
@@ -132,7 +132,7 @@
     XF86OffscreenImagePtr       format;   /* list */
     int                         nformat;  /* # if list entries */
     XF86OffscreenImagePtr       myfmt;    /* which one is YUY2 (packed) */
-    int                         have_yuv;
+    int                         yuv_format;
 
     int                         yuv_width,yuv_height;
     XF86SurfacePtr              surface;
@@ -286,7 +286,7 @@
 	    return Success;
     }
 
-    if (pPPriv->have_yuv) {
+    if (0 != pPPriv->yuv_format) {
 	DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV yuv\n"));
 	width  = pPPriv->enc[pPPriv->cenc].width;
         height = pPPriv->enc[pPPriv->cenc].height/2; /* no interlace */
@@ -338,7 +338,7 @@
 	    perror("ioctl VIDIOCSFBUF");
 	if (-1 == ioctl(V4L_FD,VIDIOCGPICT,&pPPriv->pict))
 	    perror("ioctl VIDIOCGPICT");
-	pPPriv->pict.palette = VIDEO_PALETTE_YUV422;
+	pPPriv->pict.palette = pPPriv->yuv_format;
 	pPPriv->pict.depth   = 16;
 	if (-1 == ioctl(V4L_FD,VIDIOCSPICT,&pPPriv->pict))
 	    perror("ioctl VIDIOCSPICT");
@@ -585,7 +585,7 @@
     } else if (attribute == xvFreq) {
 	if (-1 == ioctl(V4L_FD,VIDIOCSFREQ,&value))
 	    perror("ioctl VIDIOCSFREQ");
-    } else if (pPPriv->have_yuv &&
+    } else if (0 != pPPriv->yuv_format &&
 	       pPPriv->myfmt->setAttribute) {
 	/* not mine -> pass to yuv scaler driver */
 	ret = pPPriv->myfmt->setAttribute(pScrn, attribute, value);
@@ -636,7 +636,7 @@
 	}
     } else if (attribute == xvFreq) {
 	ioctl(V4L_FD,VIDIOCGFREQ,value);
-    } else if (pPPriv->have_yuv &&
+    } else if (0 != pPPriv->yuv_format &&
 	       pPPriv->myfmt->getAttribute) {
 	/* not mine -> pass to yuv scaler driver */
 	ret = pPPriv->myfmt->getAttribute(pScrn, attribute, value);
@@ -660,7 +660,7 @@
     int maxx = pPPriv->enc[pPPriv->cenc].width;
     int maxy = pPPriv->enc[pPPriv->cenc].height;
 
-    if (pPPriv->have_yuv) {
+    if (0 != pPPriv->yuv_format) {
 	*p_w = pPPriv->myfmt->max_width;
 	*p_h = pPPriv->myfmt->max_height;
     } else {
@@ -838,10 +838,54 @@
     (*count)++;
 }
 
+/* setup yuv overlay + hw scaling: look if we find some common video
+   format which both v4l driver and the X-Server can handle */
+static void v4l_check_yuv(ScrnInfoPtr pScrn, PortPrivPtr pPPriv,
+			  char *dev, int fd)
+{
+    static const struct {
+	unsigned int  v4l_palette;
+	unsigned int  v4l_depth;
+	unsigned int  xv_id;
+	unsigned int  xv_format;
+    } yuvlist[] = {
+	{ VIDEO_PALETTE_YUV422, 16, 0x32595559, XvPacked },
+	{ VIDEO_PALETTE_UYVY,   16, 0x59565955, XvPacked },
+	{ 0 /* end of list */ },
+    };
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+    int fmt,i;
+
+    pPPriv->format = xf86XVQueryOffscreenImages(pScreen,&pPPriv->nformat);
+    for (fmt = 0; yuvlist[fmt].v4l_palette != 0; fmt++) {
+	/* check v4l ... */
+	ioctl(fd,VIDIOCGPICT,&pPPriv->pict);
+	pPPriv->pict.palette = yuvlist[fmt].v4l_palette;
+	pPPriv->pict.depth   = yuvlist[fmt].v4l_depth;
+	if (-1 == ioctl(fd,VIDIOCSPICT,&pPPriv->pict))
+	    continue;
+	ioctl(fd,VIDIOCGPICT,&pPPriv->pict);
+	if (pPPriv->pict.palette != yuvlist[fmt].v4l_palette)
+	    continue;
+	/* ... works, check available offscreen image formats now ... */
+	for (i = 0; i < pPPriv->nformat; i++) {
+	    if (pPPriv->format[i].image->id     == yuvlist[fmt].xv_id &&
+		pPPriv->format[i].image->format == yuvlist[fmt].xv_format) {
+		/* ... match found, good. */
+		pPPriv->yuv_format = yuvlist[fmt].v4l_palette;
+		pPPriv->myfmt = pPPriv->format+i;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "v4l[%s]: using hw video scaling [%4.4s].\n",
+			   dev,(char*)&(pPPriv->format[i].image->id));
+		return;
+	    }
+	}
+    }
+}
+
 static int
 V4LInit(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr **adaptors)
 {
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
     PortPrivPtr pPPriv;
     DevUnion *Private;
     XF86VideoAdaptorPtr *VAR = NULL;
@@ -880,35 +924,7 @@
 	V4LBuildEncodings(pPPriv,fd,pPPriv->cap.channels);
 	if (NULL == pPPriv->enc)
 	    return FALSE;
-
-#if 1
-	/* test v4l device for yuv support:  check if the driver
-	   accepts VIDEO_PALETTE_YUV422 */
-	ioctl(fd,VIDIOCGPICT,&pPPriv->pict);
-	pPPriv->pict.palette = VIDEO_PALETTE_YUV422;
-	pPPriv->pict.depth   = 16;
-	if (0 == ioctl(fd,VIDIOCSPICT,&pPPriv->pict)) {
-	    ioctl(fd,VIDIOCGPICT,&pPPriv->pict);    
-	    if (VIDEO_PALETTE_YUV422 == pPPriv->pict.palette) {
-		/* works, check screen capabilities */
-		DEBUG(xf86Msg(X_INFO, "v4l: kernel driver supports yuv422.\n"));
-		pPPriv->format = xf86XVQueryOffscreenImages
-		    (pScreen,&pPPriv->nformat);
-		DEBUG(xf86Msg(X_INFO, "v4l: screen driver supports %d yuv formats (%p)\n",
-			      pPPriv->nformat,pPPriv->format));
-		for (j = 0; j < pPPriv->nformat; j++) {
-		    DEBUG(xf86Msg(X_INFO, "v4l: yuv format: %4.4s\n",
-				  (char*)&(pPPriv->format[j].image->id)));
-		    if (pPPriv->format[j].image->id     == 0x32595559 &&
-			pPPriv->format[j].image->format == XvPacked) {
-			pPPriv->have_yuv = 1;
-			pPPriv->myfmt = pPPriv->format+j;
-			DEBUG(xf86Msg(X_INFO,  "v4l: matching format found, offscreen yuv enabled.\n"));
-		    }
-		}
-	    }
-	}
-#endif
+	v4l_check_yuv(pScrn,pPPriv,dev,fd);
 	
 	/* alloc VideoAdaptorRec */
 	VAR = xrealloc(VAR,sizeof(XF86VideoAdaptorPtr)*(i+1));
@@ -938,7 +954,7 @@
 	    v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes,
 			 &FreqAttr);
 	}
-	if (pPPriv->have_yuv) {
+	if (0 != pPPriv->yuv_format) {
 	    /* pass throuth scaler attributes */
 	    for (j = 0; j < pPPriv->myfmt->num_attributes; j++) {
 		v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes,





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux