[libcamera-devel] [PATCH v8 3/7] android: camera_device: Refactor descriptor status and sendCaptureResults()

Umang Jain umang.jain at ideasonboard.com
Tue Oct 26 09:21:44 CEST 2021


Currently, we use Camera3RequestDescriptor::Status to determine:
- When the descriptor has been completely processed by HAL
- Whether any errors were encountered, during its processing

Both of these are essential to know whether the descriptor is eligible
to call process_capture_results() through sendCaptureResults().
When a status(Success/Error) is set on the descriptor, it is ready to
be sent back via sendCaptureResults(). However, this might lead to
undesired results especially when sendCaptureResults() runs in a
different thread (for e.g. stream's post-processor async completion
slot).

This patch decouples the descriptor status (Success/Error) from the
descriptor's completion status (pending or complete). The advantage
of this is we can set the completion status when the descriptor has
been processed fully by the layer and we can set the error status on
the descriptor wherever an error is encountered, throughout the
lifetime of the descriptor in the HAL layer.

While at it, introduce a wrapper completeDescriptor() around
sendCaptureResults(). completeDescriptor() as the name suggests will
mark the descriptor as complete, so it is ready to be sent back.
The locking mechanism is moved from sendCaptureResults() to this wrapper
since the intention is to use completeDescriptor() in place of existing
sendCaptureResults() calls.

Also make sure the sequence of abortRequest() call happens in the same
order at all places i.e. after its added to the descriptors_ queue. Fix
one of the abortRequest() call accordingly.

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh at chromium.org>
---
 src/android/camera_device.cpp  | 29 ++++++++++++++---------------
 src/android/camera_device.h    |  1 +
 src/android/camera_request.cpp |  2 +-
 src/android/camera_request.h   |  6 +++---
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 806b4090..bf9a2e69 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -982,13 +982,13 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 	MutexLocker stateLock(stateMutex_);
 
 	if (state_ == State::Flushing) {
-		abortRequest(descriptor.get());
+		Camera3RequestDescriptor *rawDescriptor = descriptor.get();
 		{
 			MutexLocker descriptorsLock(descriptorsMutex_);
 			descriptors_.push(std::move(descriptor));
 		}
-
-		sendCaptureResults();
+		abortRequest(rawDescriptor);
+		completeDescriptor(rawDescriptor);
 
 		return 0;
 	}
@@ -1079,7 +1079,7 @@ void CameraDevice::requestComplete(Request *request)
 				<< request->status();
 
 		abortRequest(descriptor);
-		sendCaptureResults();
+		completeDescriptor(descriptor);
 
 		return;
 	}
@@ -1129,6 +1129,7 @@ void CameraDevice::requestComplete(Request *request)
 			buffer.status = Camera3RequestDescriptor::Status::Error;
 			notifyError(descriptor->frameNumber_, stream->camera3Stream(),
 				    CAMERA3_MSG_ERROR_BUFFER);
+			descriptor->status_ = Camera3RequestDescriptor::Status::Error;
 			continue;
 		}
 
@@ -1145,27 +1146,27 @@ void CameraDevice::requestComplete(Request *request)
 			buffer.status = Camera3RequestDescriptor::Status::Error;
 			notifyError(descriptor->frameNumber_, stream->camera3Stream(),
 				    CAMERA3_MSG_ERROR_BUFFER);
+			descriptor->status_ = Camera3RequestDescriptor::Status::Error;
 		}
 	}
 
-	descriptor->status_ = Camera3RequestDescriptor::Status::Success;
+	completeDescriptor(descriptor);
+}
+
+void CameraDevice::completeDescriptor(Camera3RequestDescriptor *descriptor)
+{
+	MutexLocker lock(descriptorsMutex_);
+	descriptor->complete_ = true;
+
 	sendCaptureResults();
 }
 
 void CameraDevice::sendCaptureResults()
 {
-	MutexLocker lock(descriptorsMutex_);
 	while (!descriptors_.empty() && !descriptors_.front()->isPending()) {
 		auto descriptor = std::move(descriptors_.front());
 		descriptors_.pop();
 
-		/*
-		 * \todo Releasing and re-acquiring the critical section for
-		 * every request completion (grain-locking) might have an
-		 * impact on performance which should be measured.
-		 */
-		lock.unlock();
-
 		camera3_capture_result_t captureResult = {};
 
 		captureResult.frame_number = descriptor->frameNumber_;
@@ -1201,8 +1202,6 @@ void CameraDevice::sendCaptureResults()
 			captureResult.partial_result = 1;
 
 		callbacks_->process_capture_result(callbacks_, &captureResult);
-
-		lock.lock();
 	}
 }
 
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index 863cf414..e544f2bd 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -93,6 +93,7 @@ private:
 	void notifyError(uint32_t frameNumber, camera3_stream_t *stream,
 			 camera3_error_msg_code code) const;
 	int processControls(Camera3RequestDescriptor *descriptor);
+	void completeDescriptor(Camera3RequestDescriptor *descriptor);
 	void sendCaptureResults();
 	std::unique_ptr<CameraMetadata> getResultMetadata(
 		const Camera3RequestDescriptor &descriptor) const;
diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp
index faa85ada..16cf266f 100644
--- a/src/android/camera_request.cpp
+++ b/src/android/camera_request.cpp
@@ -36,7 +36,7 @@ Camera3RequestDescriptor::Camera3RequestDescriptor(
 			static_cast<CameraStream *>(buffer.stream->priv);
 
 		buffers_.push_back({ stream, buffer.buffer, nullptr,
-				     buffer.acquire_fence, Status::Pending });
+				     buffer.acquire_fence, Status::Success });
 	}
 
 	/* Clone the controls associated with the camera3 request. */
diff --git a/src/android/camera_request.h b/src/android/camera_request.h
index 05dabf89..4d80ef32 100644
--- a/src/android/camera_request.h
+++ b/src/android/camera_request.h
@@ -26,7 +26,6 @@ class Camera3RequestDescriptor
 {
 public:
 	enum class Status {
-		Pending,
 		Success,
 		Error,
 	};
@@ -43,7 +42,7 @@ public:
 				 const camera3_capture_request_t *camera3Request);
 	~Camera3RequestDescriptor();
 
-	bool isPending() const { return status_ == Status::Pending; }
+	bool isPending() const { return !complete_; }
 
 	uint32_t frameNumber_ = 0;
 
@@ -53,7 +52,8 @@ public:
 	std::unique_ptr<CaptureRequest> request_;
 	std::unique_ptr<CameraMetadata> resultMetadata_;
 
-	Status status_ = Status::Pending;
+	bool complete_ = false;
+	Status status_ = Status::Success;
 
 private:
 	LIBCAMERA_DISABLE_COPY(Camera3RequestDescriptor)
-- 
2.31.1



More information about the libcamera-devel mailing list