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