[libcamera-devel,09/11] libcamera: v4l2_device: Add event driven buffer passing

Message ID 20190203110102.5663-10-kieran.bingham@ideasonboard.com
State Superseded
Headers show
Series
  • libcamera: V4L2 Streams
Related show

Commit Message

Kieran Bingham Feb. 3, 2019, 11:01 a.m. UTC
Register an EventNotifier on our device file descriptor to be notified of
EventNotifier::Read events. These signal that a buffer is ready for dequeing
on the V4L2Device.

A Buffer is dequeued, and passed through the bufferReady Signal.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/libcamera/include/v4l2_device.h |  7 ++++++
 src/libcamera/v4l2_device.cpp       | 39 +++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 2 deletions(-)

Patch

diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h
index d3dad355be58..fbbddad68082 100644
--- a/src/libcamera/include/v4l2_device.h
+++ b/src/libcamera/include/v4l2_device.h
@@ -13,6 +13,7 @@ 
 #include <linux/videodev2.h>
 
 #include <libcamera/buffer.h>
+#include <libcamera/event_notifier.h>
 
 namespace libcamera {
 
@@ -107,6 +108,8 @@  public:
 	int streamOn();
 	int streamOff();
 
+	Signal<Buffer *> bufferReady;
+
 private:
 	int getFormatSingleplane(V4L2DeviceFormat *fmt);
 	int setFormatSingleplane(V4L2DeviceFormat *fmt);
@@ -118,6 +121,8 @@  private:
 	int exportBuffer(Buffer *buffer);
 	int exportBuffers(BufferPool *pool);
 
+	void bufferAvailable(EventNotifier *notifier);
+
 	std::string deviceNode_;
 	int fd_;
 	V4L2Capability caps_;
@@ -126,6 +131,8 @@  private:
 	enum v4l2_memory memoryType_;
 
 	BufferPool *bufferPool_;
+
+	EventNotifier *fdEvent_;
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 1fd289137b36..630b43532c3e 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -13,6 +13,7 @@ 
 #include <vector>
 
 #include <libcamera/buffer.h>
+#include <libcamera/event_notifier.h>
 
 #include "log.h"
 #include "media_object.h"
@@ -190,7 +191,8 @@  V4L2Buffer::V4L2Buffer(struct v4l2_buffer &vb)
  * \param deviceNode The file-system path to the video device node
  */
 V4L2Device::V4L2Device(const std::string &deviceNode)
-	: deviceNode_(deviceNode), fd_(-1), bufferPool_(nullptr)
+	: deviceNode_(deviceNode), fd_(-1), bufferPool_(nullptr),
+	  fdEvent_(nullptr)
 {
 	/*
 	 * We default to an MMAP based CAPTURE device, however this will be
@@ -674,6 +676,28 @@  Buffer *V4L2Device::dequeueBuffer()
 	return bufferPool_->buffers()[buf.index];
 }
 
+/**
+ * \brief Slot to handle completed buffer events from the V4L2 device
+ *
+ * When this Slot is called, a Buffer has become available from the device, and
+ * will be emitted through the bufferReady Signal.
+ *
+ * For Capture devices the Buffer will be contain valid data.
+ * For Output devices the Buffer can be considered empty.
+ */
+void V4L2Device::bufferAvailable(EventNotifier *notifier)
+{
+	Buffer *buffer;
+
+	LOG(V4L2, Debug) << "A buffer is available";
+
+	buffer = dequeueBuffer();
+
+	bufferReady.emit(buffer);
+
+	queueBuffer(buffer);
+}
+
 /**
  * \brief Request that the V4L2Device commences streaming
  *
@@ -702,13 +726,17 @@  int V4L2Device::streamOn()
 		return ret;
 	}
 
+	fdEvent_ = new EventNotifier(fd_, EventNotifier::Read);
+	fdEvent_->activated.connect(this, &V4L2Device::bufferAvailable);
+
 	return 0;
 }
 
 /**
  * \brief Request that the V4L2Device stops streaming
  *
- * Asks the device to halt any current streaming operations.
+ * Asks the device to halt any current streaming operations and remove the event
+ * notifier registered against the device file descriptor.
  *
  * \return 0 if the operation completes or a negative error number otherwise
  */
@@ -723,7 +751,14 @@  int V4L2Device::streamOff()
 		return ret;
 	}
 
+	delete fdEvent_;
+
 	return 0;
 }
 
+/**
+ * \var V4L2Device::bufferReady
+ * \brief A Signal handler which emits completed buffers.
+ */
+
 } /* namespace libcamera */