[libcamera-devel] [PATCH v4 3/7] android: Notify post processing completion via a signal

Umang Jain umang.jain at ideasonboard.com
Mon Oct 11 09:35:01 CEST 2021


Notify that the post processing for a request has been completed,
via a signal. A pointer to the descriptor which is tracking the
capture request is emitted along with the status of post processing.
The function CameraDevice::streamProcessingComplete() will finally set
the status on the descriptor by reading the status of the post-processor
completion (passed as an argument to the signal) and call
sendCaptureResults().

We also need to save a pointer to any internal buffers that might have
been allocated by CameraStream. The buffer should be returned back to
CameraStream just before capture results are sent.

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 src/android/camera_device.cpp            | 49 +++++++++++++++++-------
 src/android/camera_device.h              |  5 +++
 src/android/camera_stream.cpp            |  5 +++
 src/android/jpeg/post_processor_jpeg.cpp |  2 +
 src/android/post_processor.h             |  9 +++++
 src/android/yuv/post_processor_yuv.cpp   | 12 +++++-
 6 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index b52bdc8f..9f26c36d 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -8,7 +8,6 @@
 #include "camera_device.h"
 #include "camera_hal_config.h"
 #include "camera_ops.h"
-#include "post_processor.h"
 
 #include <algorithm>
 #include <fstream>
@@ -1226,20 +1225,12 @@ void CameraDevice::requestComplete(Request *request)
 			continue;
 		}
 
-		int ret = cameraStream->process(*src, buffer, descriptor);
-
-		/*
-		 * Return the FrameBuffer to the CameraStream now that we're
-		 * done processing it.
-		 */
 		if (cameraStream->type() == CameraStream::Type::Internal)
-			cameraStream->putBuffer(src);
+			descriptor->internalBuffer_ = src;
 
-		if (ret) {
-			buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
-			notifyError(descriptor->frameNumber_, buffer.stream,
-				    CAMERA3_MSG_ERROR_BUFFER);
-		}
+		int ret = cameraStream->process(*src, buffer, descriptor);
+
+		return;
 	}
 
 	captureResult.result = descriptor->resultMetadata_->get();
@@ -1266,6 +1257,38 @@ void CameraDevice::sendCaptureResults()
 	}
 }
 
+void CameraDevice::streamProcessingComplete(CameraStream *cameraStream,
+					    Camera3RequestDescriptor *request,
+					    PostProcessor::Status status)
+{
+	if (status == PostProcessor::Status::Error) {
+		for (camera3_stream_buffer_t &buffer : request->buffers_) {
+			CameraStream *cs = static_cast<CameraStream *>(buffer.stream->priv);
+
+			if (cs->type() == CameraStream::Type::Direct)
+				continue;
+
+			buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+			notifyError(request->frameNumber_, buffer.stream,
+				    CAMERA3_MSG_ERROR_BUFFER);
+		}
+	}
+
+	/*
+	 * Return the FrameBuffer to the CameraStream now that we're
+	 * done processing it.
+	 */
+	if (cameraStream->type() == CameraStream::Type::Internal)
+		cameraStream->putBuffer(request->internalBuffer_);
+
+	if (status == PostProcessor::Status::Success)
+		request->status_ = Camera3RequestDescriptor::Status::Success;
+	else
+		request->status_ = Camera3RequestDescriptor::Status::Error;
+
+	sendCaptureResults();
+}
+
 std::string CameraDevice::logPrefix() const
 {
 	return "'" + camera_->id() + "'";
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 3da8dffa..eee97516 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -32,6 +32,7 @@
 #include "camera_stream.h"
 #include "camera_worker.h"
 #include "jpeg/encoder.h"
+#include "post_processor.h"
 
 struct CameraConfigData;
 
@@ -56,6 +57,7 @@ struct Camera3RequestDescriptor {
 	CameraMetadata settings_;
 	std::unique_ptr<CaptureRequest> request_;
 	std::unique_ptr<CameraMetadata> resultMetadata_;
+	libcamera::FrameBuffer *internalBuffer_;
 
 	camera3_capture_result_t captureResult_ = {};
 	Status status_ = Status::Pending;
@@ -91,6 +93,9 @@ public:
 	int configureStreams(camera3_stream_configuration_t *stream_list);
 	int processCaptureRequest(camera3_capture_request_t *request);
 	void requestComplete(libcamera::Request *request);
+	void streamProcessingComplete(CameraStream *cameraStream,
+				      Camera3RequestDescriptor *request,
+				      PostProcessor::Status status);
 
 protected:
 	std::string logPrefix() const override;
diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp
index 8f47e4d8..d91e7dee 100644
--- a/src/android/camera_stream.cpp
+++ b/src/android/camera_stream.cpp
@@ -93,6 +93,11 @@ int CameraStream::configure()
 		int ret = postProcessor_->configure(configuration(), output);
 		if (ret)
 			return ret;
+
+		postProcessor_->processComplete.connect(
+			this, [&](Camera3RequestDescriptor *request, PostProcessor::Status status) {
+				cameraDevice_->streamProcessingComplete(this, request, status);
+			});
 	}
 
 	if (type_ == Type::Internal) {
diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp
index 656c48b2..81d1efe6 100644
--- a/src/android/jpeg/post_processor_jpeg.cpp
+++ b/src/android/jpeg/post_processor_jpeg.cpp
@@ -197,6 +197,7 @@ int PostProcessorJpeg::process(const FrameBuffer &source,
 					 exif.data(), quality);
 	if (jpeg_size < 0) {
 		LOG(JPEG, Error) << "Failed to encode stream image";
+		processComplete.emit(request, PostProcessor::Status::Error);
 		return jpeg_size;
 	}
 
@@ -210,6 +211,7 @@ int PostProcessorJpeg::process(const FrameBuffer &source,
 
 	/* Update the JPEG result Metadata. */
 	resultMetadata->addEntry(ANDROID_JPEG_SIZE, jpeg_size);
+	processComplete.emit(request, PostProcessor::Status::Success);
 
 	return 0;
 }
diff --git a/src/android/post_processor.h b/src/android/post_processor.h
index fa13c7e0..6e67bcba 100644
--- a/src/android/post_processor.h
+++ b/src/android/post_processor.h
@@ -7,6 +7,8 @@
 #ifndef __ANDROID_POST_PROCESSOR_H__
 #define __ANDROID_POST_PROCESSOR_H__
 
+#include <libcamera/base/signal.h>
+
 #include <libcamera/framebuffer.h>
 #include <libcamera/stream.h>
 
@@ -19,6 +21,11 @@ struct Camera3RequestDescriptor;
 class PostProcessor
 {
 public:
+	enum class Status {
+		Error,
+		Success
+	};
+
 	virtual ~PostProcessor() = default;
 
 	virtual int configure(const libcamera::StreamConfiguration &inCfg,
@@ -26,6 +33,8 @@ public:
 	virtual int process(const libcamera::FrameBuffer &source,
 			    CameraBuffer *destination,
 			    Camera3RequestDescriptor *request) = 0;
+
+	libcamera::Signal<Camera3RequestDescriptor *, Status> processComplete;
 };
 
 #endif /* __ANDROID_POST_PROCESSOR_H__ */
diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp
index 8110a1f1..b34b389d 100644
--- a/src/android/yuv/post_processor_yuv.cpp
+++ b/src/android/yuv/post_processor_yuv.cpp
@@ -18,6 +18,8 @@
 #include "libcamera/internal/formats.h"
 #include "libcamera/internal/mapped_framebuffer.h"
 
+#include "../camera_device.h"
+
 using namespace libcamera;
 
 LOG_DEFINE_CATEGORY(YUV)
@@ -51,14 +53,17 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg,
 
 int PostProcessorYuv::process(const FrameBuffer &source,
 			      CameraBuffer *destination,
-			      [[maybe_unused]] Camera3RequestDescriptor *request)
+			      Camera3RequestDescriptor *request)
 {
-	if (!isValidBuffers(source, *destination))
+	if (!isValidBuffers(source, *destination)) {
+		processComplete.emit(request, PostProcessor::Status::Error);
 		return -EINVAL;
+	}
 
 	const MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read);
 	if (!sourceMapped.isValid()) {
 		LOG(YUV, Error) << "Failed to mmap camera frame buffer";
+		processComplete.emit(request, PostProcessor::Status::Error);
 		return -EINVAL;
 	}
 
@@ -76,9 +81,12 @@ int PostProcessorYuv::process(const FrameBuffer &source,
 				    libyuv::FilterMode::kFilterBilinear);
 	if (ret) {
 		LOG(YUV, Error) << "Failed NV12 scaling: " << ret;
+		processComplete.emit(request, PostProcessor::Status::Error);
 		return -EINVAL;
 	}
 
+	processComplete.emit(request, PostProcessor::Status::Success);
+
 	return 0;
 }
 
-- 
2.31.1



More information about the libcamera-devel mailing list