[libcamera-devel,RFC,3/8] libcamera: stream: Add Stream memory type

Message ID 20190630181049.9548-4-jacopo@jmondi.org
State Accepted
Headers show
Series
  • libcamera: Add support for importing external memory buffers
Related show

Commit Message

Jacopo Mondi June 30, 2019, 6:10 p.m. UTC
Define the memory type a Stream uses and allow application to set it
through the associated StreamConfiguration.

A Stream can use either internal or external memory allocation methods,
depending on where the data produced by the stream is actually saved.

Use the memory type flag in pipeline handlers (todo: change all pipeline
handlers) during buffer setup operations, to decide if the Stream's
internal memory has to be exported to applications, or the Stream
should prepare to use buffers whose memory is allocated elsewhere.

To support the last use case, a translation mechanism between the external
buffers provided by applications and internal ones used by pipeline
handlers to feed the video device will be implemented on top of this
change.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 include/libcamera/stream.h          |  8 ++++++++
 src/libcamera/camera.cpp            |  1 +
 src/libcamera/pipeline/uvcvideo.cpp |  8 +++++++-
 src/libcamera/pipeline/vimc.cpp     |  8 +++++++-
 src/libcamera/stream.cpp            | 14 ++++++++++++--
 5 files changed, 35 insertions(+), 4 deletions(-)

Patch

diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
index fa7d6ba4987c..796f1aff2602 100644
--- a/include/libcamera/stream.h
+++ b/include/libcamera/stream.h
@@ -34,6 +34,11 @@  private:
 	std::map<unsigned int, std::vector<SizeRange>> formats_;
 };
 
+enum MemoryType {
+	InternalMemory,
+	ExternalMemory,
+};
+
 struct StreamConfiguration {
 	StreamConfiguration();
 	StreamConfiguration(const StreamFormats &formats);
@@ -41,6 +46,7 @@  struct StreamConfiguration {
 	unsigned int pixelFormat;
 	Size size;
 
+	MemoryType memoryType;
 	unsigned int bufferCount;
 
 	Stream *stream() const { return stream_; }
@@ -77,6 +83,7 @@  public:
 	std::vector<Buffer> &buffers() { return bufferPool_.buffers(); }
 	unsigned int bufferCount() const { return bufferPool_.count(); }
 	const StreamConfiguration &configuration() const { return configuration_; }
+	MemoryType memoryType() const { return memoryType_; }
 
 protected:
 	friend class Camera;
@@ -86,6 +93,7 @@  protected:
 
 	BufferPool bufferPool_;
 	StreamConfiguration configuration_;
+	MemoryType memoryType_;
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 023ae53e5f9d..662406b970dc 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -671,6 +671,7 @@  int Camera::configure(CameraConfiguration *config)
 		 * Allocate buffer objects in the pool.
 		 * Memory will be allocated and assigned later.
 		 */
+		stream->memoryType_ = cfg.memoryType;
 		stream->createBuffers(cfg.bufferCount);
 	}
 
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 2e22523d7cb1..5112356c25ac 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -190,10 +190,16 @@  int PipelineHandlerUVC::allocateBuffers(Camera *camera,
 	UVCCameraData *data = cameraData(camera);
 	Stream *stream = *streams.begin();
 	const StreamConfiguration &cfg = stream->configuration();
+	int ret;
 
 	LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
 
-	return data->video_->exportBuffers(&stream->bufferPool());
+	if (stream->memoryType() == InternalMemory)
+		ret = data->video_->exportBuffers(&stream->bufferPool());
+	else
+		ret = data->video_->importBuffers(&stream->bufferPool());
+
+	return ret;
 }
 
 int PipelineHandlerUVC::freeBuffers(Camera *camera,
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 6833213650dc..21a37dba1fc6 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -189,10 +189,16 @@  int PipelineHandlerVimc::allocateBuffers(Camera *camera,
 	VimcCameraData *data = cameraData(camera);
 	Stream *stream = *streams.begin();
 	const StreamConfiguration &cfg = stream->configuration();
+	int ret;
 
 	LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
 
-	return data->video_->exportBuffers(&stream->bufferPool());
+	if (stream->memoryType() == InternalMemory)
+		ret = data->video_->exportBuffers(&stream->bufferPool());
+	else
+		ret = data->video_->importBuffers(&stream->bufferPool());
+
+	return ret;
 }
 
 int PipelineHandlerVimc::freeBuffers(Camera *camera,
diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp
index c6701e5f9921..b6292427d3a2 100644
--- a/src/libcamera/stream.cpp
+++ b/src/libcamera/stream.cpp
@@ -263,6 +263,11 @@  SizeRange StreamFormats::range(unsigned int pixelformat) const
 	return range;
 }
 
+/**
+ * \enum MemoryType
+ * \todo
+ */
+
 /**
  * \struct StreamConfiguration
  * \brief Configuration parameters for a stream
@@ -276,7 +281,7 @@  SizeRange StreamFormats::range(unsigned int pixelformat) const
  * handlers provied StreamFormats.
  */
 StreamConfiguration::StreamConfiguration()
-	: stream_(nullptr)
+	: memoryType(InternalMemory), stream_(nullptr)
 {
 }
 
@@ -284,7 +289,7 @@  StreamConfiguration::StreamConfiguration()
  * \brief Construct a configuration with stream formats
  */
 StreamConfiguration::StreamConfiguration(const StreamFormats &formats)
-	: stream_(nullptr), formats_(formats)
+	: memoryType(InternalMemory), stream_(nullptr), formats_(formats)
 {
 }
 
@@ -301,6 +306,11 @@  StreamConfiguration::StreamConfiguration(const StreamFormats &formats)
  * format described in V4L2 using the V4L2_PIX_FMT_* definitions.
  */
 
+/**
+ * \var memoryType
+ * \todo
+ */
+
 /**
  * \var StreamConfiguration::bufferCount
  * \brief Requested number of buffers to allocate for the stream