summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvincechiu <vincechiu@google.com>2021-08-12 14:51:03 +0800
committerVince Chiu <vincechiu@google.com>2021-08-13 05:47:58 +0000
commite99fd0e4477701b94213e00a7e556d731cfc68d7 (patch)
tree7b09b2954a1ee2e5049f0624a2e66a59336f1115
parent03c4ce23715ccf0dae1ce18a722f4bcc99b90860 (diff)
downloadcamera-e99fd0e4477701b94213e00a7e556d731cfc68d7.tar.gz
Camera: Add ZSL result dispatcher
ZSL result dispatcher supports two instances of dispatcher to treat ZSL requests and normal requests separately. Only create ZSL result dispatcher in ZslSnapshotCaptureSession. Bug: 189539315 Test: P21 camera checklist, IG, Snapchat Change-Id: I4d2d7e960ab8932e3ec7494b53fc166f0c997ee6
-rw-r--r--common/hal/google_camera_hal/zsl_snapshot_capture_session.cc14
-rw-r--r--common/hal/google_camera_hal/zsl_snapshot_capture_session.h4
-rw-r--r--common/hal/utils/Android.bp1
-rw-r--r--common/hal/utils/result_dispatcher.h1
-rw-r--r--common/hal/utils/zsl_result_dispatcher.cc181
-rw-r--r--common/hal/utils/zsl_result_dispatcher.h117
6 files changed, 312 insertions, 6 deletions
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
index 077a880..894b40d 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
@@ -609,8 +609,8 @@ status_t ZslSnapshotCaptureSession::Initialize(
if (res == OK) {
partial_result_count_ = partial_result_entry.data.i32[0];
}
- result_dispatcher_ = ResultDispatcher::Create(partial_result_count_,
- process_capture_result, notify);
+ result_dispatcher_ = ZslResultDispatcher::Create(
+ partial_result_count_, process_capture_result, notify);
if (result_dispatcher_ == nullptr) {
ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
return UNKNOWN_ERROR;
@@ -677,7 +677,15 @@ status_t ZslSnapshotCaptureSession::Initialize(
status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
ATRACE_CALL();
- status_t res = result_dispatcher_->AddPendingRequest(request);
+ bool is_zsl_request = false;
+ camera_metadata_ro_entry entry;
+ if (request.settings != nullptr) {
+ if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
+ *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
+ is_zsl_request = true;
+ }
+ }
+ status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
if (res != OK) {
ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
request.frame_number);
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
index dab4515..74b3cc3 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
@@ -27,10 +27,10 @@
#include "realtime_zsl_request_processor.h"
#include "realtime_zsl_result_processor.h"
#include "request_processor.h"
-#include "result_dispatcher.h"
#include "result_processor.h"
#include "snapshot_request_processor.h"
#include "snapshot_result_processor.h"
+#include "zsl_result_dispatcher.h"
namespace android {
namespace google_camera_hal {
@@ -157,7 +157,7 @@ class ZslSnapshotCaptureSession : public CaptureSession {
int32_t additional_stream_id_ = -1;
- std::unique_ptr<ResultDispatcher> result_dispatcher_;
+ std::unique_ptr<ZslResultDispatcher> result_dispatcher_;
std::mutex callback_lock_;
// The following callbacks must be protected by callback_lock_.
diff --git a/common/hal/utils/Android.bp b/common/hal/utils/Android.bp
index 6b2dc58..635a798 100644
--- a/common/hal/utils/Android.bp
+++ b/common/hal/utils/Android.bp
@@ -47,6 +47,7 @@ cc_library_shared {
"vendor_tag_utils.cc",
"zoom_ratio_mapper.cc",
"zsl_buffer_manager.cc",
+ "zsl_result_dispatcher.cc",
],
shared_libs: [
"lib_profiler",
diff --git a/common/hal/utils/result_dispatcher.h b/common/hal/utils/result_dispatcher.h
index 74f4b4a..5acc90a 100644
--- a/common/hal/utils/result_dispatcher.h
+++ b/common/hal/utils/result_dispatcher.h
@@ -65,7 +65,6 @@ class ResultDispatcher {
// Remove a pending request.
void RemovePendingRequest(uint32_t frame_number);
- protected:
ResultDispatcher(uint32_t partial_result_count,
ProcessCaptureResultFunc process_capture_result,
NotifyFunc notify);
diff --git a/common/hal/utils/zsl_result_dispatcher.cc b/common/hal/utils/zsl_result_dispatcher.cc
new file mode 100644
index 0000000..3b5baa4
--- /dev/null
+++ b/common/hal/utils/zsl_result_dispatcher.cc
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "GCH_ZslResultDispatcher"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+#include <log/log.h>
+#include <utils/Trace.h>
+
+#include <inttypes.h>
+
+#include "utils.h"
+#include "zsl_result_dispatcher.h"
+
+namespace android {
+namespace google_camera_hal {
+
+std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
+ uint32_t partial_result_count,
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
+ ATRACE_CALL();
+ auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
+ new ZslResultDispatcher(process_capture_result, notify));
+ if (dispatcher == nullptr) {
+ ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
+ return nullptr;
+ }
+
+ status_t res = dispatcher->Initialize(partial_result_count);
+ if (res != OK) {
+ ALOGE("%s: Initialize failed.", __FUNCTION__);
+ return nullptr;
+ }
+
+ return dispatcher;
+}
+
+ZslResultDispatcher::ZslResultDispatcher(
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
+ : device_session_process_capture_result_(process_capture_result),
+ device_session_notify_(notify) {
+}
+
+status_t ZslResultDispatcher::Initialize(uint32_t partial_result_count) {
+ ATRACE_CALL();
+ process_capture_result_ =
+ ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
+ ProcessCaptureResult(std::move(result));
+ });
+ notify_ = NotifyFunc(
+ [this](const NotifyMessage& message) { NotifyHalMessage(message); });
+
+ normal_result_dispatcher_ =
+ std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
+ partial_result_count, process_capture_result_, notify_));
+ if (normal_result_dispatcher_ == nullptr) {
+ ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ zsl_result_dispatcher_ =
+ std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
+ partial_result_count, process_capture_result_, notify_));
+ if (zsl_result_dispatcher_ == nullptr) {
+ ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ return OK;
+}
+
+void ZslResultDispatcher::ProcessCaptureResult(
+ std::unique_ptr<CaptureResult> result) {
+ std::lock_guard<std::mutex> lock(process_capture_result_lock_);
+ device_session_process_capture_result_(std::move(result));
+}
+
+bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ if (zsl_frames_.empty()) {
+ return false;
+ }
+ if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
+ zsl_frames_.end()) {
+ return false;
+ }
+ return true;
+}
+
+void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
+ std::lock_guard<std::mutex> lock(result_lock_);
+ device_session_notify_(message);
+}
+
+status_t ZslResultDispatcher::AddPendingRequest(
+ const CaptureRequest& pending_request, bool is_zsl_request) {
+ ATRACE_CALL();
+ if (is_zsl_request) {
+ uint32_t frame_number = pending_request.frame_number;
+ {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.push_back(frame_number);
+ }
+
+ status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
+ if (res != OK) {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.erase(
+ std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
+ }
+ return res;
+ } else {
+ return normal_result_dispatcher_->AddPendingRequest(pending_request);
+ }
+}
+
+status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
+ ATRACE_CALL();
+ if (result == nullptr) {
+ ALOGE("%s: result is nullptr", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ uint32_t frame_number = result->frame_number;
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddResult(std::move(result));
+ } else {
+ return normal_result_dispatcher_->AddResult(std::move(result));
+ }
+}
+
+status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
+ int64_t timestamp_ns) {
+ ATRACE_CALL();
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+ } else {
+ return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+ }
+}
+
+status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
+ ATRACE_CALL();
+ uint32_t frame_number = error.frame_number;
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddError(error);
+ } else {
+ return normal_result_dispatcher_->AddError(error);
+ }
+}
+
+void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
+ ATRACE_CALL();
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ zsl_result_dispatcher_->RemovePendingRequest(frame_number);
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.erase(
+ std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
+ } else {
+ normal_result_dispatcher_->RemovePendingRequest(frame_number);
+ }
+}
+
+} // namespace google_camera_hal
+} // namespace android
diff --git a/common/hal/utils/zsl_result_dispatcher.h b/common/hal/utils/zsl_result_dispatcher.h
new file mode 100644
index 0000000..6297b6b
--- /dev/null
+++ b/common/hal/utils/zsl_result_dispatcher.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_
+
+#include <map>
+#include <thread>
+
+#include "hal_types.h"
+#include "result_dispatcher.h"
+
+namespace android {
+namespace google_camera_hal {
+
+// ZslResultDispatcher dispatches capture results of zsl requests and none-zsl
+// requests in the order of frame numbers, including result metadata, shutters,
+// and stream buffers.
+//
+// The client can add results and shutters via AddResult() and AddShutter() in
+// any order. ZslResultDispatcher will invoke ProcessCaptureResultFunc and
+// NotifyFunc to notify result metadata, shutters, and stream buffers in the
+// in the order of increasing frame numbers.
+class ZslResultDispatcher {
+ public:
+ // Create a ZslResultDispatcher.
+ // partial_result_count is the partial result count.
+ // process_capture_result is the function to notify capture results.
+ // notify is the function to notify shutter messages.
+ // Treat ZSL requests and normal requests separately.
+ // For ZSL requests, it returns zsl shutter and zsl results in order
+ // and is not blocked by normal shutter and results.
+ static std::unique_ptr<ZslResultDispatcher> Create(
+ uint32_t partial_result_count,
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify);
+
+ virtual ~ZslResultDispatcher() = default;
+
+ // Add a pending request. This tells ZslResultDispatcher to watch for
+ // the shutter, result metadata, and stream buffers for this request,
+ // that will be added later via AddResult() and AddShutter().
+ // Treat the request as zsl request if is_zsl_request is true
+ status_t AddPendingRequest(const CaptureRequest& pending_request,
+ bool is_zsl_request);
+
+ // Add a ready result. If the result doesn't belong to a pending request that
+ // was previously added via AddPendingRequest(), an error will be returned.
+ status_t AddResult(std::unique_ptr<CaptureResult> result);
+
+ // Add a shutter for a frame number. If the frame number doesn't belong to a
+ // pending request that was previously added via AddPendingRequest(), an error
+ // will be returned.
+ status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns);
+
+ // Add an error notification for a frame number. When this is called, we no
+ // longer wait for a shutter message or result metadata for the given frame.
+ status_t AddError(const ErrorMessage& error);
+
+ // Remove a pending request.
+ void RemovePendingRequest(uint32_t frame_number);
+
+ protected:
+ ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,
+ NotifyFunc notify);
+
+ private:
+ status_t Initialize(uint32_t partial_result_count);
+
+ // Invoked when receiving a result from ResultDispatcher class.
+ void ProcessCaptureResult(std::unique_ptr<CaptureResult> result);
+
+ // Invoked when receiving a message from ResultDispatcher.
+ void NotifyHalMessage(const NotifyMessage& message);
+
+ // Return true if this frame is zsl request.
+ bool IsZslFrame(uint32_t frame_number);
+
+ std::unique_ptr<ResultDispatcher> normal_result_dispatcher_;
+ std::unique_ptr<ResultDispatcher> zsl_result_dispatcher_;
+
+ std::mutex process_capture_result_lock_;
+ // The following callbacks must be protected by process_capture_result_lock_.
+ // Pass this callback function to ResultDispatcher class
+ ProcessCaptureResultFunc process_capture_result_;
+
+ std::mutex result_lock_;
+ // The following callbacks must be protected by result_lock_.
+ // Pass this callback function to ResultDispatcher class
+ NotifyFunc notify_;
+
+ // Record the callback function for framework callback
+ ProcessCaptureResultFunc device_session_process_capture_result_;
+ NotifyFunc device_session_notify_;
+
+ std::mutex zsl_frames_lock_;
+ // Store the frame number of zsl requests
+ // Protected by zsl_frames_lock_.
+ std::vector<uint32_t> zsl_frames_;
+};
+
+} // namespace google_camera_hal
+} // namespace android
+
+#endif // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_