[libcamera-devel,RFC,7/8] libcamera: request: Support buffer mapping

Message ID 20190630181049.9548-8-jacopo@jmondi.org
State Superseded
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
Use the Stream class buffer mapping operation to save the association in
the request at Request::findBuffer() time and reverse it with a new
operation Request::unmapBuffer() used by the pipeline handler base class
at buffer completion time, to return to the applications the Buffer they
originally provided with the Request without involving the pipeline
handlers.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 include/libcamera/request.h        |  4 +++-
 src/libcamera/pipeline_handler.cpp |  6 ++++--
 src/libcamera/request.cpp          | 27 ++++++++++++++++++++++++++-
 3 files changed, 33 insertions(+), 4 deletions(-)

Patch

diff --git a/include/libcamera/request.h b/include/libcamera/request.h
index 7adb753b2706..c22b6be282b2 100644
--- a/include/libcamera/request.h
+++ b/include/libcamera/request.h
@@ -34,7 +34,8 @@  public:
 
 	const std::map<Stream *, Buffer *> &buffers() const { return buffers_; }
 	int setBuffers(const std::map<Stream *, Buffer *> &streamMap);
-	Buffer *findBuffer(Stream *stream) const;
+	Buffer *findBuffer(Stream *stream);
+	Buffer *unmapBuffer(Buffer *streamBuffer);
 
 	Status status() const { return status_; }
 
@@ -52,6 +53,7 @@  private:
 	Camera *camera_;
 	std::map<Stream *, Buffer *> buffers_;
 	std::unordered_set<Buffer *> pending_;
+	std::map<Buffer *, Buffer *> bufferMap_;
 
 	Status status_;
 };
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index fbebe4a04acd..1dcfefaaf6eb 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -383,8 +383,10 @@  int PipelineHandler::queueRequest(Camera *camera, Request *request)
 bool PipelineHandler::completeBuffer(Camera *camera, Request *request,
 				     Buffer *buffer)
 {
-	camera->bufferCompleted.emit(request, buffer);
-	return request->completeBuffer(buffer);
+	Buffer *requestBuffer = request->unmapBuffer(buffer);
+
+	camera->bufferCompleted.emit(request, requestBuffer);
+	return request->completeBuffer(requestBuffer);
 }
 
 /**
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index def7f2f21dc7..bfe6fc99a93b 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -94,12 +94,37 @@  int Request::setBuffers(const std::map<Stream *, Buffer *> &streamMap)
  * \return The buffer associated with the stream, or nullptr if the stream is
  * not part of this request
  */
-Buffer *Request::findBuffer(Stream *stream) const
+Buffer *Request::findBuffer(Stream *stream)
 {
 	auto it = buffers_.find(stream);
 	if (it == buffers_.end())
 		return nullptr;
 
+	/*
+	 * Streams with internal memory mode do not need to perform any mapping
+	 * between the application provided buffers (part of the request)
+	 * and the one actually used by the Stream.
+	 *
+	 * Streams using externally allocated buffers need to create a mapping
+	 * between the application provided buffers and the one used by pipeline
+	 * handlers.
+	 */
+	Buffer *requestBuffer = it->second;
+	Buffer *mappedBuffer = stream->memoryType() == InternalMemory ?
+			       it->second : stream->mapBuffer(it->second);
+	bufferMap_[mappedBuffer] = requestBuffer;
+
+	return mappedBuffer;
+}
+
+/**
+ * \brief Retrieve the application buffer associated with \a streamBuffer
+ */
+Buffer *Request::unmapBuffer(Buffer *streamBuffer)
+{
+	auto it = bufferMap_.find(streamBuffer);
+	ASSERT(it != bufferMap_.end());
+
 	return it->second;
 }