diff options
author | vincechiu <vincechiu@google.com> | 2021-08-12 14:51:03 +0800 |
---|---|---|
committer | Vince Chiu <vincechiu@google.com> | 2021-08-13 05:47:58 +0000 |
commit | e99fd0e4477701b94213e00a7e556d731cfc68d7 (patch) | |
tree | 7b09b2954a1ee2e5049f0624a2e66a59336f1115 | |
parent | 03c4ce23715ccf0dae1ce18a722f4bcc99b90860 (diff) | |
download | camera-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.cc | 14 | ||||
-rw-r--r-- | common/hal/google_camera_hal/zsl_snapshot_capture_session.h | 4 | ||||
-rw-r--r-- | common/hal/utils/Android.bp | 1 | ||||
-rw-r--r-- | common/hal/utils/result_dispatcher.h | 1 | ||||
-rw-r--r-- | common/hal/utils/zsl_result_dispatcher.cc | 181 | ||||
-rw-r--r-- | common/hal/utils/zsl_result_dispatcher.h | 117 |
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_ |