1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // #define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_ZslResultDispatcher"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "zsl_result_dispatcher.h"
21
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <utils/Trace.h>
25
26 #include "hal_types.h"
27 #include "utils.h"
28
29 namespace android {
30 namespace google_camera_hal {
31
Create(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,const StreamConfiguration & stream_config)32 std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
33 uint32_t partial_result_count,
34 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
35 const StreamConfiguration& stream_config) {
36 ATRACE_CALL();
37 auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
38 new ZslResultDispatcher(process_capture_result, notify));
39 if (dispatcher == nullptr) {
40 ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
41 return nullptr;
42 }
43
44 status_t res = dispatcher->Initialize(partial_result_count, stream_config);
45 if (res != OK) {
46 ALOGE("%s: Initialize failed.", __FUNCTION__);
47 return nullptr;
48 }
49
50 return dispatcher;
51 }
52
ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)53 ZslResultDispatcher::ZslResultDispatcher(
54 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
55 : device_session_process_capture_result_(process_capture_result),
56 device_session_notify_(notify) {
57 }
58
Initialize(uint32_t partial_result_count,const StreamConfiguration & stream_config)59 status_t ZslResultDispatcher::Initialize(
60 uint32_t partial_result_count, const StreamConfiguration& stream_config) {
61 ATRACE_CALL();
62 process_capture_result_ =
63 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
64 ProcessCaptureResult(std::move(result));
65 });
66 notify_ = NotifyFunc(
67 [this](const NotifyMessage& message) { NotifyHalMessage(message); });
68
69 normal_result_dispatcher_ =
70 std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
71 partial_result_count, process_capture_result_,
72 /*process_batch_capture_result=*/nullptr, notify_,
73 /*notify_batch=*/nullptr, stream_config, "ZslNormalDispatcher"));
74 if (normal_result_dispatcher_ == nullptr) {
75 ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
76 return BAD_VALUE;
77 }
78
79 zsl_result_dispatcher_ =
80 std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
81 partial_result_count, process_capture_result_,
82 /*process_batch_capture_result=*/nullptr, notify_,
83 /*notify_batch=*/nullptr, stream_config, "ZslZslDispatcher"));
84 if (zsl_result_dispatcher_ == nullptr) {
85 ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
86 return BAD_VALUE;
87 }
88
89 return OK;
90 }
91
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)92 void ZslResultDispatcher::ProcessCaptureResult(
93 std::unique_ptr<CaptureResult> result) {
94 std::lock_guard<std::mutex> lock(process_capture_result_lock_);
95 device_session_process_capture_result_(std::move(result));
96 }
97
IsZslFrame(uint32_t frame_number)98 bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
99 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
100 if (zsl_frames_.empty()) {
101 return false;
102 }
103 if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
104 zsl_frames_.end()) {
105 return false;
106 }
107 return true;
108 }
109
NotifyHalMessage(const NotifyMessage & message)110 void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
111 std::lock_guard<std::mutex> lock(result_lock_);
112 device_session_notify_(message);
113 }
114
AddPendingRequest(const CaptureRequest & pending_request,bool is_zsl_request)115 status_t ZslResultDispatcher::AddPendingRequest(
116 const CaptureRequest& pending_request, bool is_zsl_request) {
117 ATRACE_CALL();
118 if (is_zsl_request) {
119 uint32_t frame_number = pending_request.frame_number;
120 {
121 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
122 zsl_frames_.push_back(frame_number);
123 }
124
125 status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
126 if (res != OK) {
127 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
128 zsl_frames_.erase(
129 std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
130 }
131 return res;
132 } else {
133 return normal_result_dispatcher_->AddPendingRequest(pending_request);
134 }
135 }
136
AddResult(std::unique_ptr<CaptureResult> result)137 status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
138 ATRACE_CALL();
139 if (result == nullptr) {
140 ALOGE("%s: result is nullptr", __FUNCTION__);
141 return BAD_VALUE;
142 }
143 uint32_t frame_number = result->frame_number;
144 bool is_zsl_request = IsZslFrame(frame_number);
145 if (is_zsl_request) {
146 return zsl_result_dispatcher_->AddResult(std::move(result));
147 } else {
148 return normal_result_dispatcher_->AddResult(std::move(result));
149 }
150 }
151
AddShutter(const ShutterMessage & shutter)152 status_t ZslResultDispatcher::AddShutter(const ShutterMessage& shutter) {
153 ATRACE_CALL();
154 bool is_zsl_request = IsZslFrame(shutter.frame_number);
155 if (is_zsl_request) {
156 return zsl_result_dispatcher_->AddShutter(shutter);
157 } else {
158 return normal_result_dispatcher_->AddShutter(shutter);
159 }
160 }
161
AddError(const ErrorMessage & error)162 status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
163 ATRACE_CALL();
164 uint32_t frame_number = error.frame_number;
165 bool is_zsl_request = IsZslFrame(frame_number);
166 if (is_zsl_request) {
167 return zsl_result_dispatcher_->AddError(error);
168 } else {
169 return normal_result_dispatcher_->AddError(error);
170 }
171 }
172
RemovePendingRequest(uint32_t frame_number)173 void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
174 ATRACE_CALL();
175 bool is_zsl_request = IsZslFrame(frame_number);
176 if (is_zsl_request) {
177 zsl_result_dispatcher_->RemovePendingRequest(frame_number);
178 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
179 zsl_frames_.erase(
180 std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
181 } else {
182 normal_result_dispatcher_->RemovePendingRequest(frame_number);
183 }
184 }
185
186 } // namespace google_camera_hal
187 } // namespace android
188