[libcamera-devel] [PATCH 3/4] ipa: vimc: Map and unmap buffers

Umang Jain umang.jain at ideasonboard.com
Fri Aug 6 12:14:08 CEST 2021


Since VIMC is a virtual test driver, the support for IPA
buffers(parameter and statistics) is missing. We could create
our own and pass it around, but created buffers needs to be
backed by dmabuf file-descriptors ideally.

This might prove cubersome given that we use vimc for test purposes.
Hence, pass actual frame data buffers into the IPA instead, which
would result in exercising these code paths for now. Introduce plumbing
support for mapping and un-mapping of these buffers into the IPA.

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 include/libcamera/ipa/vimc.mojom     |  3 +++
 src/ipa/vimc/vimc.cpp                | 26 ++++++++++++++++++++++++++
 src/libcamera/pipeline/vimc/vimc.cpp | 25 ++++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/include/libcamera/ipa/vimc.mojom b/include/libcamera/ipa/vimc.mojom
index 99b6412b..8452461d 100644
--- a/include/libcamera/ipa/vimc.mojom
+++ b/include/libcamera/ipa/vimc.mojom
@@ -26,6 +26,9 @@ interface IPAVimcInterface {
 
 	start() => (int32 ret);
 	stop();
+
+	mapBuffers(array<libcamera.IPABuffer> buffers);
+	unmapBuffers(array<uint32> ids);
 };
 
 interface IPAVimcEventInterface {
diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
index 54d9086a..2b00687f 100644
--- a/src/ipa/vimc/vimc.cpp
+++ b/src/ipa/vimc/vimc.cpp
@@ -19,6 +19,8 @@
 #include <libcamera/ipa/ipa_interface.h>
 #include <libcamera/ipa/ipa_module_info.h>
 
+#include "libcamera/internal/framebuffer.h"
+
 namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPAVimc)
@@ -38,11 +40,15 @@ public:
 		      const std::map<unsigned int, IPAStream> &streamConfig,
 		      const std::map<unsigned int, ControlInfoMap> &entityControls) override;
 
+	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
+	void unmapBuffers(const std::vector<unsigned int> &ids) override;
+
 private:
 	void initTrace();
 	void trace(enum ipa::vimc::IPATraceCode operation);
 
 	int fd_;
+	std::map<unsigned int, MappedFrameBuffer> buffers_;
 };
 
 IPAVimc::IPAVimc()
@@ -99,6 +105,26 @@ int IPAVimc::configure([[maybe_unused]] const IPACameraSensorInfo &sensorInfo,
 	return 0;
 }
 
+void IPAVimc::mapBuffers(const std::vector<IPABuffer> &buffers)
+{
+	for (const IPABuffer &buffer : buffers) {
+		const FrameBuffer fb(buffer.planes);
+		buffers_.emplace(buffer.id,
+				 MappedFrameBuffer(&fb, PROT_READ));
+	}
+}
+
+void IPAVimc::unmapBuffers(const std::vector<unsigned int> &ids)
+{
+	for (unsigned int id : ids) {
+		auto it = buffers_.find(id);
+		if (it == buffers_.end())
+			continue;
+
+		buffers_.erase(it);
+	}
+}
+
 void IPAVimc::initTrace()
 {
 	struct stat fifoStat;
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index b7dd6595..fa21128d 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -45,7 +45,7 @@ class VimcCameraData : public CameraData
 {
 public:
 	VimcCameraData(PipelineHandler *pipe, MediaDevice *media)
-		: CameraData(pipe), media_(media)
+		: CameraData(pipe), media_(media), buffers_(nullptr)
 	{
 	}
 
@@ -61,6 +61,9 @@ public:
 	Stream stream_;
 
 	std::unique_ptr<ipa::vimc::IPAProxyVimc> ipa_;
+
+	std::vector<std::unique_ptr<FrameBuffer>> *buffers_;
+	std::vector<IPABuffer> ipaBuffers_;
 };
 
 class VimcCameraConfiguration : public CameraConfiguration
@@ -319,6 +322,7 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,
 {
 	VimcCameraData *data = cameraData(camera);
 	unsigned int count = stream->configuration().bufferCount;
+	data->buffers_ = buffers;
 
 	return data->video_->exportBuffers(count, buffers);
 }
@@ -332,6 +336,19 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] const ControlLis
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * We don't have actual parameters/statistics buffers in VIMC.
+	 * Hence, map frame buffers to exercise IPA IPC code paths for now.
+	 */
+	ASSERT(data->buffers_ != nullptr);
+	unsigned int ipaBufferId = 1;
+	for (unsigned int i = 0; i< count; i++) {
+		std::unique_ptr<FrameBuffer> &buffer = data->buffers_->at(i);
+		buffer->setCookie(ipaBufferId++);
+                data->ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());
+	}
+	data->ipa_->mapBuffers(data->ipaBuffers_);
+
 	ret = data->ipa_->start();
 	if (ret) {
 		data->video_->releaseBuffers();
@@ -352,7 +369,13 @@ void PipelineHandlerVimc::stop(Camera *camera)
 {
 	VimcCameraData *data = cameraData(camera);
 	data->video_->streamOff();
+
+	std::vector<unsigned int> ids;
+	for (IPABuffer &ipabuf : data->ipaBuffers_)
+		ids.push_back(ipabuf.id);
+	data->ipa_->unmapBuffers(ids);
 	data->ipa_->stop();
+
 	data->video_->releaseBuffers();
 }
 
-- 
2.31.1



More information about the libcamera-devel mailing list