[Kwintv] Re: Howto stop qtvision from autoscanning

Koos Vriezen koos.vriezen at xs4all.nl
Sat Dec 13 21:23:40 CET 2003


George wrote:
> > Wow, it works...hmm resizing doesn't work, as soon as I resize or go to TV
> > mode I get
> >   qtvision: Fatal IO error: client killed

>    Yes this is a known bug and no-one has been able to track it down yet.  If 
> you setup the Xv driver it will work better.

After putting some printf's, I noticed that it uses Xv (QVIDEO_METHOD_XV) but
not overlay. If I enable overlay in the v4l plugin conf I get a constants
stream of XMap/XUnmap events and the display start to flicker enormously
(but I'm able to press ^C and kill qtvision).

It seems that the fatal io occurs when the main thread is doing a XvPutImage
and the V4LGrabber is doing a ioctl on the device fd. So a quick fix is of 
course is adding the locking in QtVisionV4L::event too. But that basicly
disables any advantage of having this thread. It does work now, I can resize
change channels etc, but there're a lot of framedrops.
(maybe that's why xawtv doesn't support grabbing with Xv, dunno)

Anyway, attached what works for me (2.6.0-test11 and NPTL). Maybe useful
for someone with the same configuration atm.

Koos
-------------- next part --------------
Index: qtvision/plugins/video/v4l/qtvision_v4l.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kwintv3/qtvision/plugins/video/v4l/qtvision_v4l.cpp,v
retrieving revision 1.63
diff -u -3 -p -r1.63 qtvision_v4l.cpp
--- qtvision/plugins/video/v4l/qtvision_v4l.cpp	13 Dec 2003 13:50:03 -0000	1.63
+++ qtvision/plugins/video/v4l/qtvision_v4l.cpp	13 Dec 2003 20:20:14 -0000
@@ -152,8 +152,10 @@ _errors = 0;
 /*		kdDebug() << "Post event " << (void *)&(_buf[bl]) 
 			<< " time: " << tv3.tv_sec << "."
 			<< tv3.tv_usec << endl; */
+                        qApp->lock();
 			QApplication::postEvent(_owner,
 				new BLTEvent(BLTEvent::BLTImage,_buf[bl],_gsn));
+                        qApp->unlock();
 			if (bl == 31)
 				bl = 0;
 			else bl++;
@@ -165,7 +167,7 @@ _errors = 0;
 			// and let it prompt the user to do something.  It
 			// might even be good to reduce this number too.  Needs
 			// investigation.
-			kdDebug() << "Too many errors.  Ending V4L grabbing." << endl;
+			fprintf(stderr, "Too many errors.  Ending V4L grabbing.\n");
 			break;
 		}
 	}
@@ -718,6 +720,7 @@ QMutexLocker l(&_devMtx);
 
 
 void QtVisionV4L::updateClipping() {
+MutexMonitor l(&_devMtx);
 Display *dpy = qt_xdisplay();
 Window win = _w->winId();
 Window root;
@@ -859,6 +862,7 @@ void QtVisionV4L::repaintRegion(QPoint u
 
 bool QtVisionV4L::event(QEvent *e)
 {
+MutexMonitor l(&_devMtx);
 //kdDebug() << "V4L plugin received an event." << endl;
     if (!g || !e || e->type() != QEvent::User)
         return false;
Index: kvideoio/v4ldev.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kwintv3/kvideoio/v4ldev.cpp,v
retrieving revision 1.39
diff -u -3 -p -r1.39 v4ldev.cpp
--- kvideoio/v4ldev.cpp	13 Dec 2003 13:50:02 -0000	1.39
+++ kvideoio/v4ldev.cpp	13 Dec 2003 20:20:14 -0000
@@ -53,7 +53,7 @@ static int _sigs = 0;
 
 static void sigalarm(int) {
 	_sigs++;
-	kdDebug() << "V4L timeout " << _sigs << endl;
+	fprintf(stderr, "V4L timeout %d\n");
 }
 
 class V4LSigInit {
@@ -364,7 +364,7 @@ int V4LDev::initGrabbing() {
 
            rc = ioctl(_fd, VIDIOCMCAPTURE, _mmapData);
            if (rc != 0) {
-               kdDebug() << "VIDIOCMCAPTURE failed." << endl;
+               fprintf(stderr, "VIDIOCMCAPTURE failed.\n");
                return -1;
            }
         }
@@ -409,7 +409,7 @@ int V4LDev::grab(V4LImage *img, bool sca
         rc = ioctl(_fd, VIDIOCMCAPTURE, &(_mmapData[nextFrame]));
         if (rc != 0) {
             //perror("VIDIOCMCAPTURE");
-            kdDebug() << "VIDIOCMCAPTURE failed." << endl;
+            fprintf(stderr, "VIDIOCMCAPTURE failed.\n");
             if (errno == EBUSY) {
                 // on EBUSY, somehow the frame is busy.  This should never
 		// happen as far as I know.  Hack: try to release the frame.
@@ -418,7 +418,7 @@ int V4LDev::grab(V4LImage *img, bool sca
                 rc = ioctl(_fd, VIDIOCSYNC, &nextFrame);
                 if (rc != 0) {
                     //perror("VIDIOCSYNC");
-                    kdDebug() << "VIDIOCSYNC failed too." << endl;
+                    fprintf(stderr, "VIDIOCSYNC failed too.\n");
                 }
             }
             return -1;
@@ -443,7 +443,7 @@ int V4LDev::grab(V4LImage *img, bool sca
             ;
         _mmapCurrentFrame = nextFrame;
         if (rc != 0) {
-            kdDebug() << "VIDIOCSYNC failed." << endl;
+            fprintf(stderr, "VIDIOCSYNC failed.\n");
         }
     } else {    /////////////////////////////////////////   read() method
 // FIXME: there is no need to read into _readBuf and then memcpy(), other than
@@ -453,8 +453,7 @@ int V4LDev::grab(V4LImage *img, bool sca
             _readBuf = new uchar[sz];
         int rc = read(_fd, _readBuf, sz);
         if (rc != sz) {
-            kdDebug() << "error: wanted " << sz
-                      << ", got rc = " << rc << endl;
+            fprintf(stderr, "error: wanted %d, got rc = %d\n", sz, rc);
 
             return -1;
         }


More information about the kwintv mailing list