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 "utils.h"
27
28 namespace android {
29 namespace google_camera_hal {
30
Create(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,const StreamConfiguration & stream_config)31 std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
32 uint32_t partial_result_count,
33 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
34 const StreamConfiguration& stream_config) {
35 ATRACE_CALL();
36 auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
37 new ZslResultDispatcher(process_capture_result, notify));
38 if (dispatcher == nullptr) {
39 ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
40 return nullptr;
41 }
42
43 status_t res = dispatcher->Initialize(partial_result_count, stream_config);
44 if (res != OK) {
45 ALOGE("%s: Initialize failed.", __FUNCTION__);
46 return nullptr;
47 }
48
49 return dispatcher;
50 }
51
ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)52 ZslResultDispatcher::ZslResultDispatcher(
53 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
54 : device_session_process_capture_result_(process_capture_result),
55 device_session_notify_(notify) {
56 }
57
Initialize(uint32_t partial_result_count,const StreamConfiguration & stream_config)58 status_t ZslResultDispatcher::Initialize(
59 uint32_t partial_result_count, const StreamConfiguration& stream_config) {
60 ATRACE_CALL();
61 process_capture_result_ =
62 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
63 ProcessCaptureResult(std::move(result));
64 });
65 notify_ = NotifyFunc(
66 [this](const NotifyMessage& message) { NotifyHalMessage(message); });
67
68 normal_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
69 new ResultDispatcher(partial_result_count, process_capture_result_,
70 /*process_batch_capture_result=*/nullptr, notify_,
71 stream_config, "ZslNormalDispatcher"));
72 if (normal_result_dispatcher_ == nullptr) {
73 ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
74 return BAD_VALUE;
75 }
76
77 zsl_result_dispatcher_ = std::unique_ptr<ResultDispatcher>(
78 new ResultDispatcher(partial_result_count, process_capture_result_,
79 /*process_batch_capture_result=*/nullptr, notify_,
80 stream_config, "ZslZslDispatcher"));
81 if (zsl_result_dispatcher_ == nullptr) {
82 ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
83 return BAD_VALUE;
84 }
85
86 return OK;
87 }
88
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)89 void ZslResultDispatcher::ProcessCaptureResult(
90 std::unique_ptr<CaptureResult> result) {
91 std::lock_guard<std::mutex> lock(process_capture_result_lock_);
92 device_session_process_capture_result_(std::move(result));
93 }
94
IsZslFrame(uint32_t frame_number)95 bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
96 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
97 if (zsl_frames_.empty()) {
98 return false;
99 }
100 if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
101 zsl_frames_.end()) {
102 return false;
103 }
104 return true;
105 }
106
NotifyHalMessage(const NotifyMessage & message)107 void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
108 std::lock_guard<std::mutex> lock(result_lock_);
109 device_session_notify_(message);
110 }
111
AddPendingRequest(const CaptureRequest & pending_request,bool is_zsl_request)112 status_t ZslResultDispatcher::AddPendingRequest(
113 const CaptureRequest& pending_request, bool is_zsl_request) {
114 ATRACE_CALL();
115 if (is_zsl_request) {
116 uint32_t frame_number = pending_request.frame_number;
117 {
118 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
119 zsl_frames_.push_back(frame_number);
120 }
121
122 status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
123 if (res != OK) {
124 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
125 zsl_frames_.erase(
126 std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
127 }
128 return res;
129 } else {
130 return normal_result_dispatcher_->AddPendingRequest(pending_request);
131 }
132 }
133
AddResult(std::unique_ptr<CaptureResult> result)134 status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
135 ATRACE_CALL();
136 if (result == nullptr) {
137 ALOGE("%s: result is nullptr", __FUNCTION__);
138 return BAD_VALUE;
139 }
140 uint32_t frame_number = result->frame_number;
141 bool is_zsl_request = IsZslFrame(frame_number);
142 if (is_zsl_request) {
143 return zsl_result_dispatcher_->AddResult(std::move(result));
144 } else {
145 return normal_result_dispatcher_->AddResult(std::move(result));
146 }
147 }
148
AddShutter(uint32_t frame_number,int64_t timestamp_ns,int64_t readout_timestamp_ns)149 status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
150 int64_t timestamp_ns,
151 int64_t readout_timestamp_ns) {
152 ATRACE_CALL();
153 bool is_zsl_request = IsZslFrame(frame_number);
154 if (is_zsl_request) {
155 return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
156 readout_timestamp_ns);
157 } else {
158 return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns,
159 readout_timestamp_ns);
160 }
161 }
162
AddError(const ErrorMessage & error)163 status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
164 ATRACE_CALL();
165 uint32_t frame_number = error.frame_number;
166 bool is_zsl_request = IsZslFrame(frame_number);
167 if (is_zsl_request) {
168 return zsl_result_dispatcher_->AddError(error);
169 } else {
170 return normal_result_dispatcher_->AddError(error);
171 }
172 }
173
RemovePendingRequest(uint32_t frame_number)174 void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
175 ATRACE_CALL();
176 bool is_zsl_request = IsZslFrame(frame_number);
177 if (is_zsl_request) {
178 zsl_result_dispatcher_->RemovePendingRequest(frame_number);
179 std::lock_guard<std::mutex> lock(zsl_frames_lock_);
180 zsl_frames_.erase(
181 std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
182 } else {
183 normal_result_dispatcher_->RemovePendingRequest(frame_number);
184 }
185 }
186
187 } // namespace google_camera_hal
188 } // namespace android
189