[libcamera-devel] [PATCH v4 7/7] android: camera_device: Synchronise completion and cleanup of requests

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


Synchronise a way where queued requests in descriptors_ do not end up
with Camera3RequestDescriptor::Status::Pending forever. To ensure this,
stop the camera worker first, which will not let any new requests
queue up to the libcamera::Camera. It is then followed by
libcamera::Camera::stop() which is synchronous and will ensure all
requests in-flight gets completed (and requestComplete() handler is
called for all of them).

Since CameraDevice::requestComplete() handler can even queue
post-processing requests to CameraStream::PostProcessorWorker, ensure
the worker is stopped and all those post-processing requests too, are
purged as per CameraStream::flush() implemented earlier.

All this operations is encapsulated in a a helper function
CameraDevice::stopCamera() which can be used in stop() and flush()
scenarios.

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 src/android/camera_device.cpp | 34 ++++++++++++++++++++++++++++------
 src/android/camera_device.h   |  1 +
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 3541a74b..9433dde7 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -424,13 +424,37 @@ int CameraDevice::open(const hw_module_t *hardwareModule)
 
 void CameraDevice::close()
 {
-	streams_.clear();
-
 	stop();
 
+	streams_.clear();
+
 	camera_->release();
 }
 
+void CameraDevice::stopCamera()
+{
+	/*
+	 * Stopping the worker will prevent any new requests queued to
+	 * libcamera::Camera.
+	 */
+	worker_.stop();
+
+	/*
+	 * libcamera::Camera::stop() will synchronously complete all requests
+	 * thereby, ensuring requestComplete() signal handler is executed for
+	 * all requests which are in-flight.
+	 */
+	camera_->stop();
+
+	/*
+	 * While libcamera::Camera::stop() is completing in-flight requests,
+	 * some of those request might queue post-processing of a stream.
+	 * Purge the post-processsing queue in this case so that the descriptors
+	 * can be processed and get offloaded from descriptors_.
+	 */
+	for (auto &stream : streams_)
+		stream.flush();
+}
 void CameraDevice::flush()
 {
 	{
@@ -441,8 +465,7 @@ void CameraDevice::flush()
 		state_ = State::Flushing;
 	}
 
-	worker_.stop();
-	camera_->stop();
+	stopCamera();
 
 	MutexLocker stateLock(stateMutex_);
 	state_ = State::Stopped;
@@ -454,8 +477,7 @@ void CameraDevice::stop()
 	if (state_ == State::Stopped)
 		return;
 
-	worker_.stop();
-	camera_->stop();
+	stopCamera();
 
 	descriptors_ = {};
 
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 0ce6caeb..20eae704 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -115,6 +115,7 @@ private:
 	};
 
 	void stop();
+	void stopCamera();
 
 	std::unique_ptr<libcamera::FrameBuffer>
 	createFrameBuffer(const buffer_handle_t camera3buffer,
-- 
2.31.1



More information about the libcamera-devel mailing list