[libcamera-devel] [PATCH v3 10/10] android: camera_stream: Run post processor in a thread

Umang Jain umang.jain at ideasonboard.com
Mon Sep 20 19:37:52 CEST 2021


This commit makes the post processor run in a separate thread.
To enable the move to a separate thread, he post processor
needs to be inherited from libcamera::Object and use the
Object::moveToThread() API to execute the move.

A user defined destructor is introduced to stop the thread for cleanup.
Since CameraStream is move-constructible and compiler implicitly
generates its constructor, defining a destructor will prevent the
compiler from adding an implicitly-declared move constructor. Therefore,
we need to explicitly add a move constructor as well.

Also, the destination buffer for post-processing needs to be alive and
stored as a part of overall context, hence a CameraBuffer unique-pointer
member is introduced in the Camera3RequestDescriptor struct.

---
 /* \todo Use ConnectionTypeQueued instead of ConnectionTypeBlocking */
---

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 src/android/camera_device.h   |  2 ++
 src/android/camera_stream.cpp | 29 +++++++++++++++++++++--------
 src/android/camera_stream.h   |  5 +++++
 src/android/post_processor.h  |  3 ++-
 4 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 0bd570a1..e3f3fe7c 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -27,6 +27,7 @@
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
+#include "camera_buffer.h"
 #include "camera_capabilities.h"
 #include "camera_metadata.h"
 #include "camera_stream.h"
@@ -55,6 +56,7 @@ struct Camera3RequestDescriptor {
 	CameraMetadata settings_;
 	std::unique_ptr<CaptureRequest> request_;
 	std::unique_ptr<CameraMetadata> resultMetadata_;
+	std::unique_ptr<CameraBuffer> destBuffer_;
 
 	camera3_capture_result_t captureResult_ = {};
 	libcamera::FrameBuffer *internalBuffer_;
diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp
index c18c7041..6578ce09 100644
--- a/src/android/camera_stream.cpp
+++ b/src/android/camera_stream.cpp
@@ -55,6 +55,9 @@ CameraStream::CameraStream(CameraDevice *const cameraDevice,
 		 * is what we instantiate here.
 		 */
 		postProcessor_ = std::make_unique<PostProcessorJpeg>(cameraDevice_);
+		thread_ = std::make_unique<libcamera::Thread>();
+		postProcessor_->moveToThread(thread_.get());
+		thread_->start();
 	}
 
 	if (type == Type::Internal) {
@@ -63,6 +66,14 @@ CameraStream::CameraStream(CameraDevice *const cameraDevice,
 	}
 }
 
+CameraStream::~CameraStream()
+{
+	if (thread_) {
+		thread_->exit();
+		thread_->wait();
+	}
+}
+
 const StreamConfiguration &CameraStream::configuration() const
 {
 	return config_->at(index_);
@@ -111,21 +122,23 @@ void CameraStream::process(const FrameBuffer *source,
 		return;
 	}
 
-	/*
-	 * \todo Buffer mapping and processing should be moved to a
-	 * separate thread.
-	 */
 	const StreamConfiguration &output = configuration();
-	CameraBuffer dest(camera3Dest, formats::MJPEG, output.size,
-			  PROT_READ | PROT_WRITE);
-	if (!dest.isValid()) {
+	std::unique_ptr<CameraBuffer> dest =
+		std::make_unique<CameraBuffer>(camera3Dest, formats::MJPEG,
+					       output.size, PROT_READ | PROT_WRITE);
+
+	if (!dest->isValid()) {
 		LOG(HAL, Error) << "Failed to map android blob buffer";
 		request->status_ = Camera3RequestDescriptor::ProcessStatus::Error;
 		handleProcessComplete(request);
 		return;
 	}
+	request->destBuffer_ = std::move(dest);
 
-	postProcessor_->process(source, &dest, request);
+	/* \todo Use ConnectionTypeQueued instead of ConnectionTypeBlocking */
+	postProcessor_->invokeMethod(&PostProcessor::process,
+				     ConnectionTypeBlocking, source,
+				     request->destBuffer_.get(), request);
 }
 
 void CameraStream::handleProcessComplete(Camera3RequestDescriptor *request)
diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h
index d4ec5c25..42db72d8 100644
--- a/src/android/camera_stream.h
+++ b/src/android/camera_stream.h
@@ -13,6 +13,8 @@
 
 #include <hardware/camera3.h>
 
+#include <libcamera/base/thread.h>
+
 #include <libcamera/camera.h>
 #include <libcamera/framebuffer.h>
 #include <libcamera/framebuffer_allocator.h>
@@ -113,6 +115,8 @@ public:
 	CameraStream(CameraDevice *const cameraDevice,
 		     libcamera::CameraConfiguration *config, Type type,
 		     camera3_stream_t *camera3Stream, unsigned int index);
+	CameraStream(CameraStream &&other) = default;
+	~CameraStream();
 
 	Type type() const { return type_; }
 	const camera3_stream_t &camera3Stream() const { return *camera3Stream_; }
@@ -143,6 +147,7 @@ private:
 	 */
 	std::unique_ptr<std::mutex> mutex_;
 	std::unique_ptr<PostProcessor> postProcessor_;
+	std::unique_ptr<libcamera::Thread> thread_;
 };
 
 #endif /* __ANDROID_CAMERA_STREAM__ */
diff --git a/src/android/post_processor.h b/src/android/post_processor.h
index 48ddd8ac..fdfd52d3 100644
--- a/src/android/post_processor.h
+++ b/src/android/post_processor.h
@@ -7,6 +7,7 @@
 #ifndef __ANDROID_POST_PROCESSOR_H__
 #define __ANDROID_POST_PROCESSOR_H__
 
+#include <libcamera/base/object.h>
 #include <libcamera/base/signal.h>
 
 #include <libcamera/framebuffer.h>
@@ -18,7 +19,7 @@ class CameraMetadata;
 
 struct Camera3RequestDescriptor;
 
-class PostProcessor
+class PostProcessor : public libcamera::Object
 {
 public:
 	virtual ~PostProcessor() = default;
-- 
2.31.1



More information about the libcamera-devel mailing list