Browse Source

video4linux: don't block on reading camera frames

Add v4l-blocking variable to enable the old behaviour.
rdb 7 years ago
parent
commit
e0f8d7885a

+ 4 - 0
panda/src/vision/config_vision.cxx

@@ -26,6 +26,10 @@
 Configure(config_vision);
 Configure(config_vision);
 NotifyCategoryDef(vision, "");
 NotifyCategoryDef(vision, "");
 
 
+ConfigVariableBool v4l_blocking
+("v4l-blocking", false,
+ PRC_DESC("Set this to true if you want to block waiting for webcam frames."));
+
 ConfigureFn(config_vision) {
 ConfigureFn(config_vision) {
   init_libvision();
   init_libvision();
 }
 }

+ 3 - 0
panda/src/vision/config_vision.h

@@ -16,9 +16,12 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "notifyCategoryProxy.h"
 #include "notifyCategoryProxy.h"
+#include "configVariableBool.h"
 
 
 NotifyCategoryDecl(vision, EXPCL_VISION, EXPTP_VISION);
 NotifyCategoryDecl(vision, EXPCL_VISION, EXPTP_VISION);
 
 
+extern ConfigVariableBool v4l_blocking;
+
 extern EXPCL_VISION void init_libvision();
 extern EXPCL_VISION void init_libvision();
 
 
 #endif
 #endif

+ 11 - 1
panda/src/vision/webcamVideoCursorV4L.cxx

@@ -209,7 +209,13 @@ WebcamVideoCursorV4L(WebcamVideoV4L *src) : MovieVideoCursor(src) {
 
 
   _buffers = NULL;
   _buffers = NULL;
   _buflens = NULL;
   _buflens = NULL;
-  _fd = open(src->_device.c_str(), O_RDWR);
+
+  int mode = O_RDWR;
+  if (!v4l_blocking) {
+    mode = O_NONBLOCK;
+  }
+
+  _fd = open(src->_device.c_str(), mode);
   if (-1 == _fd) {
   if (-1 == _fd) {
     vision_cat.error() << "Failed to open " << src->_device.c_str() << "\n";
     vision_cat.error() << "Failed to open " << src->_device.c_str() << "\n";
     return;
     return;
@@ -397,6 +403,10 @@ fetch_buffer() {
   vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   vbuf.memory = V4L2_MEMORY_MMAP;
   vbuf.memory = V4L2_MEMORY_MMAP;
   if (-1 == ioctl(_fd, VIDIOC_DQBUF, &vbuf) && errno != EIO) {
   if (-1 == ioctl(_fd, VIDIOC_DQBUF, &vbuf) && errno != EIO) {
+    if (errno == EAGAIN) {
+      // Simply nothing is available yet.
+      return NULL;
+    }
     vision_cat.error() << "Failed to dequeue buffer!\n";
     vision_cat.error() << "Failed to dequeue buffer!\n";
     return NULL;
     return NULL;
   }
   }