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_RealtimeZslResultProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include <inttypes.h>
24
25 #include "hal_utils.h"
26 #include "realtime_zsl_result_processor.h"
27
28 namespace android {
29 namespace google_camera_hal {
30
Create(InternalStreamManager * internal_stream_manager,int32_t raw_stream_id)31 std::unique_ptr<RealtimeZslResultProcessor> RealtimeZslResultProcessor::Create(
32 InternalStreamManager* internal_stream_manager, int32_t raw_stream_id) {
33 ATRACE_CALL();
34 if (internal_stream_manager == nullptr) {
35 ALOGE("%s: internal_stream_manager is nullptr.", __FUNCTION__);
36 return nullptr;
37 }
38
39 auto result_processor = std::unique_ptr<RealtimeZslResultProcessor>(
40 new RealtimeZslResultProcessor(internal_stream_manager, raw_stream_id));
41 if (result_processor == nullptr) {
42 ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
43 return nullptr;
44 }
45
46 return result_processor;
47 }
48
RealtimeZslResultProcessor(InternalStreamManager * internal_stream_manager,int32_t raw_stream_id)49 RealtimeZslResultProcessor::RealtimeZslResultProcessor(
50 InternalStreamManager* internal_stream_manager, int32_t raw_stream_id) {
51 internal_stream_manager_ = internal_stream_manager;
52 raw_stream_id_ = raw_stream_id;
53 }
54
SetResultCallback(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify)55 void RealtimeZslResultProcessor::SetResultCallback(
56 ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
57 std::lock_guard<std::mutex> lock(callback_lock_);
58 process_capture_result_ = process_capture_result;
59 notify_ = notify;
60 }
61
SaveLsForHdrplus(const CaptureRequest & request)62 void RealtimeZslResultProcessor::SaveLsForHdrplus(const CaptureRequest& request) {
63 if (request.settings != nullptr) {
64 uint8_t lens_shading_map_mode;
65 status_t res =
66 hal_utils::GetLensShadingMapMode(request, &lens_shading_map_mode);
67 if (res == OK) {
68 current_lens_shading_map_mode_ = lens_shading_map_mode;
69 }
70 }
71
72 {
73 std::lock_guard<std::mutex> lock(lens_shading_lock_);
74 requested_lens_shading_map_modes_.emplace(request.frame_number,
75 current_lens_shading_map_mode_);
76 }
77 }
78
HandleLsResultForHdrplus(uint32_t frameNumber,HalCameraMetadata * metadata)79 status_t RealtimeZslResultProcessor::HandleLsResultForHdrplus(
80 uint32_t frameNumber, HalCameraMetadata* metadata) {
81 if (metadata == nullptr) {
82 ALOGE("%s: metadata is nullptr", __FUNCTION__);
83 return BAD_VALUE;
84 }
85 std::lock_guard<std::mutex> lock(lens_shading_lock_);
86 auto iter = requested_lens_shading_map_modes_.find(frameNumber);
87 if (iter == requested_lens_shading_map_modes_.end()) {
88 ALOGW("%s: can't find frame (%d)", __FUNCTION__, frameNumber);
89 return OK;
90 }
91
92 if (iter->second == ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF) {
93 status_t res = hal_utils::RemoveLsInfoFromResult(metadata);
94 if (res != OK) {
95 ALOGW("%s: RemoveLsInfoFromResult fail", __FUNCTION__);
96 }
97 }
98 requested_lens_shading_map_modes_.erase(iter);
99
100 return OK;
101 }
102
SaveFdForHdrplus(const CaptureRequest & request)103 void RealtimeZslResultProcessor::SaveFdForHdrplus(const CaptureRequest& request) {
104 // Enable face detect mode for internal use
105 if (request.settings != nullptr) {
106 uint8_t fd_mode;
107 status_t res = hal_utils::GetFdMode(request, &fd_mode);
108 if (res == OK) {
109 current_face_detect_mode_ = fd_mode;
110 }
111 }
112
113 {
114 std::lock_guard<std::mutex> lock(face_detect_lock_);
115 requested_face_detect_modes_.emplace(request.frame_number,
116 current_face_detect_mode_);
117 }
118 }
119
HandleFdResultForHdrplus(uint32_t frameNumber,HalCameraMetadata * metadata)120 status_t RealtimeZslResultProcessor::HandleFdResultForHdrplus(
121 uint32_t frameNumber, HalCameraMetadata* metadata) {
122 if (metadata == nullptr) {
123 ALOGE("%s: metadata is nullptr", __FUNCTION__);
124 return BAD_VALUE;
125 }
126 std::lock_guard<std::mutex> lock(face_detect_lock_);
127 auto iter = requested_face_detect_modes_.find(frameNumber);
128 if (iter == requested_face_detect_modes_.end()) {
129 ALOGW("%s: can't find frame (%d)", __FUNCTION__, frameNumber);
130 return OK;
131 }
132
133 if (iter->second == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
134 status_t res = hal_utils::RemoveFdInfoFromResult(metadata);
135 if (res != OK) {
136 ALOGW("%s: RestoreFdMetadataForHdrplus fail", __FUNCTION__);
137 }
138 }
139 requested_face_detect_modes_.erase(iter);
140
141 return OK;
142 }
143
AddPendingRequests(const std::vector<ProcessBlockRequest> & process_block_requests,const CaptureRequest & remaining_session_request)144 status_t RealtimeZslResultProcessor::AddPendingRequests(
145 const std::vector<ProcessBlockRequest>& process_block_requests,
146 const CaptureRequest& remaining_session_request) {
147 ATRACE_CALL();
148 // This is the last result processor. Sanity check if requests contains
149 // all remaining output buffers.
150 if (!hal_utils::AreAllRemainingBuffersRequested(process_block_requests,
151 remaining_session_request)) {
152 ALOGE("%s: Some output buffers will not be completed.", __FUNCTION__);
153 return BAD_VALUE;
154 }
155
156 SaveFdForHdrplus(remaining_session_request);
157 SaveLsForHdrplus(remaining_session_request);
158
159 return OK;
160 }
161
ProcessResult(ProcessBlockResult block_result)162 void RealtimeZslResultProcessor::ProcessResult(ProcessBlockResult block_result) {
163 ATRACE_CALL();
164 std::lock_guard<std::mutex> lock(callback_lock_);
165 std::unique_ptr<CaptureResult> result = std::move(block_result.result);
166 if (result == nullptr) {
167 ALOGW("%s: Received a nullptr result.", __FUNCTION__);
168 return;
169 }
170
171 if (process_capture_result_ == nullptr) {
172 ALOGE("%s: process_capture_result_ is nullptr. Dropping a result.",
173 __FUNCTION__);
174 return;
175 }
176
177 // Return filled raw buffer to internal stream manager
178 // And remove raw buffer from result
179 bool raw_output = false;
180 status_t res;
181 std::vector<StreamBuffer> modified_output_buffers;
182 for (uint32_t i = 0; i < result->output_buffers.size(); i++) {
183 if (raw_stream_id_ == result->output_buffers[i].stream_id) {
184 raw_output = true;
185 res = internal_stream_manager_->ReturnFilledBuffer(
186 result->frame_number, result->output_buffers[i]);
187 if (res != OK) {
188 ALOGW("%s: (%d)ReturnStreamBuffer fail", __FUNCTION__,
189 result->frame_number);
190 }
191 } else {
192 modified_output_buffers.push_back(result->output_buffers[i]);
193 }
194 }
195
196 if (result->output_buffers.size() > 0) {
197 result->output_buffers.clear();
198 result->output_buffers = modified_output_buffers;
199 }
200
201 if (result->result_metadata) {
202 res = internal_stream_manager_->ReturnMetadata(
203 raw_stream_id_, result->frame_number, result->result_metadata.get());
204 if (res != OK) {
205 ALOGW("%s: (%d)ReturnMetadata fail", __FUNCTION__, result->frame_number);
206 }
207
208 res = hal_utils::SetEnableZslMetadata(result->result_metadata.get(), false);
209 if (res != OK) {
210 ALOGW("%s: SetEnableZslMetadata (%d) fail", __FUNCTION__,
211 result->frame_number);
212 }
213
214 res = HandleFdResultForHdrplus(result->frame_number,
215 result->result_metadata.get());
216 if (res != OK) {
217 ALOGE("%s: HandleFdResultForHdrplus(%d) fail", __FUNCTION__,
218 result->frame_number);
219 return;
220 }
221
222 res = HandleLsResultForHdrplus(result->frame_number,
223 result->result_metadata.get());
224 if (res != OK) {
225 ALOGE("%s: HandleLsResultForHdrplus(%d) fail", __FUNCTION__,
226 result->frame_number);
227 return;
228 }
229 }
230
231 // Don't send result to framework if only internal raw callback
232 if (raw_output && result->result_metadata == nullptr &&
233 result->output_buffers.size() == 0) {
234 return;
235 }
236 process_capture_result_(std::move(result));
237 }
238
Notify(const ProcessBlockNotifyMessage & block_message)239 void RealtimeZslResultProcessor::Notify(
240 const ProcessBlockNotifyMessage& block_message) {
241 ATRACE_CALL();
242 std::lock_guard<std::mutex> lock(callback_lock_);
243 const NotifyMessage& message = block_message.message;
244 if (notify_ == nullptr) {
245 ALOGE("%s: notify_ is nullptr. Dropping a message.", __FUNCTION__);
246 return;
247 }
248
249 notify_(message);
250 }
251
FlushPendingRequests()252 status_t RealtimeZslResultProcessor::FlushPendingRequests() {
253 ATRACE_CALL();
254 return INVALID_OPERATION;
255 }
256
257 } // namespace google_camera_hal
258 } // namespace android