[libcamera-devel] [PATCH] android: Implement flush()
Hirokazu Honda
hiroh at chromium.org
Tue Apr 6 11:13:34 CEST 2021
This implements camera3_device_ops::flush().
Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
src/android/camera_device.cpp | 48 +++++++++++++++++++++++++++++++----
src/android/camera_device.h | 3 +++
src/android/camera_ops.cpp | 3 ++-
3 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 4a3f6f8e..5a56fe4b 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -2029,20 +2029,22 @@ void CameraDevice::requestComplete(Request *request)
camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
std::unique_ptr<CameraMetadata> resultMetadata;
- decltype(descriptors_)::node_type node;
+ Camera3RequestDescriptor descriptor;
{
std::scoped_lock<std::mutex> lock(mutex_);
auto it = descriptors_.find(request->cookie());
if (it == descriptors_.end()) {
LOG(HAL, Fatal)
<< "Unknown request: " << request->cookie();
- status = CAMERA3_BUFFER_STATUS_ERROR;
return;
}
- node = descriptors_.extract(it);
+ descriptor = std::move(it->second);
+ /* Restore frameNumber_ because it is used in the case of flush
+ * timeout case.
+ */
+ it->second.frameNumber_ = descriptor.frameNumber_;
}
- Camera3RequestDescriptor &descriptor = node.mapped();
if (request->status() != Request::RequestComplete) {
LOG(HAL, Error) << "Request not successfully completed: "
@@ -2122,7 +2124,43 @@ void CameraDevice::requestComplete(Request *request)
descriptor.buffers_[0].stream);
}
- callbacks_->process_capture_result(callbacks_, &captureResult);
+ {
+ std::scoped_lock<std::mutex> lock(mutex_);
+ if (descriptors_.erase(request->cookie()) == 0) {
+ // flush() cleans up the descriptor due to time out
+ // during a post processing.
+ return;
+ }
+ callbacks_->process_capture_result(callbacks_, &captureResult);
+ conditionVariable_.notify_one();
+ }
+}
+
+int CameraDevice::flush()
+{
+ std::unique_lock<std::mutex> lock(mutex_);
+ /* flush() should return in less than one second. Sets the timeout to 900ms. */
+ auto flushTimeout =
+ std::chrono::system_clock::now() + std::chrono::milliseconds(900);
+ bool completeAllRequests = conditionVariable_.wait_until(
+ lock, flushTimeout, [this]() { return descriptors_.empty(); });
+
+ if (!completeAllRequests) {
+ for (auto &node : descriptors_) {
+ auto &descriptor = node.second;
+ camera3_capture_result_t captureResult{};
+ captureResult.frame_number = descriptor.frameNumber_;
+ for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
+ buffer.acquire_fence = -1;
+ buffer.release_fence = -1;
+ buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+ }
+ callbacks_->process_capture_result(callbacks_, &captureResult);
+ }
+ descriptors_.clear();
+ }
+
+ return 0;
}
std::string CameraDevice::logPrefix() const
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index c63e8e21..dd5336ee 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -7,6 +7,7 @@
#ifndef __ANDROID_CAMERA_DEVICE_H__
#define __ANDROID_CAMERA_DEVICE_H__
+#include <condition_variable>
#include <map>
#include <memory>
#include <mutex>
@@ -62,6 +63,7 @@ public:
int configureStreams(camera3_stream_configuration_t *stream_list);
int processCaptureRequest(camera3_capture_request_t *request);
void requestComplete(libcamera::Request *request);
+ int flush();
protected:
std::string logPrefix() const override;
@@ -128,6 +130,7 @@ private:
std::vector<CameraStream> streams_;
std::mutex mutex_; /* Protect descriptors_ */
+ std::condition_variable conditionVariable_;
std::map<uint64_t, Camera3RequestDescriptor> descriptors_;
std::string maker_;
diff --git a/src/android/camera_ops.cpp b/src/android/camera_ops.cpp
index 696e8043..1b73af13 100644
--- a/src/android/camera_ops.cpp
+++ b/src/android/camera_ops.cpp
@@ -68,7 +68,8 @@ static void hal_dev_dump([[maybe_unused]] const struct camera3_device *dev,
static int hal_dev_flush([[maybe_unused]] const struct camera3_device *dev)
{
- return 0;
+ CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
+ return camera->flush();
}
int hal_dev_close(hw_device_t *hw_device)
--
2.31.0.208.g409f899ff0-goog
More information about the libcamera-devel
mailing list