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_RealtimeZslRequestProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22 
23 #include "hal_utils.h"
24 #include "realtime_zsl_request_processor.h"
25 #include "vendor_tag_defs.h"
26 
27 namespace android {
28 namespace google_camera_hal {
29 
Create(CameraDeviceSessionHwl * device_session_hwl)30 std::unique_ptr<RealtimeZslRequestProcessor> RealtimeZslRequestProcessor::Create(
31     CameraDeviceSessionHwl* device_session_hwl) {
32   ATRACE_CALL();
33   if (device_session_hwl == nullptr) {
34     ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
35     return nullptr;
36   }
37 
38   uint32_t num_physical_cameras =
39       device_session_hwl->GetPhysicalCameraIds().size();
40   if (num_physical_cameras > 1) {
41     ALOGE("%s: only support 1 physical camera but it has %u", __FUNCTION__,
42           num_physical_cameras);
43     return nullptr;
44   }
45 
46   auto request_processor = std::unique_ptr<RealtimeZslRequestProcessor>(
47       new RealtimeZslRequestProcessor());
48   if (request_processor == nullptr) {
49     ALOGE("%s: Creating RealtimeZslRequestProcessor failed.", __FUNCTION__);
50     return nullptr;
51   }
52 
53   status_t res = request_processor->Initialize(device_session_hwl);
54   if (res != OK) {
55     ALOGE("%s: Initializing RealtimeZslRequestProcessor failed: %s (%d).",
56           __FUNCTION__, strerror(-res), res);
57     return nullptr;
58   }
59 
60   return request_processor;
61 }
62 
Initialize(CameraDeviceSessionHwl * device_session_hwl)63 status_t RealtimeZslRequestProcessor::Initialize(
64     CameraDeviceSessionHwl* device_session_hwl) {
65   ATRACE_CALL();
66   std::unique_ptr<HalCameraMetadata> characteristics;
67   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
68   if (res != OK) {
69     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
70     return BAD_VALUE;
71   }
72 
73   camera_metadata_ro_entry entry;
74   res = characteristics->Get(
75       ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
76   if (res == OK) {
77     active_array_width_ = entry.data.i32[2];
78     active_array_height_ = entry.data.i32[3];
79     ALOGI("%s Active size (%d x %d).", __FUNCTION__, active_array_width_,
80           active_array_height_);
81   } else {
82     ALOGE("%s Get active size failed: %s (%d).", __FUNCTION__, strerror(-res),
83           res);
84     return res;
85   }
86 
87   res = characteristics->Get(VendorTagIds::kHdrUsageMode, &entry);
88   if (res == OK) {
89     hdr_mode_ = static_cast<HdrMode>(entry.data.u8[0]);
90   }
91 
92   return OK;
93 }
94 
ConfigureStreams(InternalStreamManager * internal_stream_manager,const StreamConfiguration & stream_config,StreamConfiguration * process_block_stream_config)95 status_t RealtimeZslRequestProcessor::ConfigureStreams(
96     InternalStreamManager* internal_stream_manager,
97     const StreamConfiguration& stream_config,
98     StreamConfiguration* process_block_stream_config) {
99   ATRACE_CALL();
100   if (process_block_stream_config == nullptr ||
101       internal_stream_manager == nullptr) {
102     ALOGE(
103         "%s: process_block_stream_config (%p) is nullptr or "
104         "internal_stream_manager (%p) is nullptr",
105         __FUNCTION__, process_block_stream_config, internal_stream_manager);
106     return BAD_VALUE;
107   }
108 
109   // Register internal raw stream
110   Stream raw_stream;
111   raw_stream.stream_type = StreamType::kOutput;
112   raw_stream.width = active_array_width_;
113   raw_stream.height = active_array_height_;
114   raw_stream.format = HAL_PIXEL_FORMAT_RAW10;
115   raw_stream.usage = 0;
116   raw_stream.rotation = StreamRotation::kRotation0;
117   raw_stream.data_space = HAL_DATASPACE_ARBITRARY;
118 
119   status_t result = internal_stream_manager->RegisterNewInternalStream(
120       raw_stream, &raw_stream_id_);
121   if (result != OK) {
122     ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
123     return UNKNOWN_ERROR;
124   }
125 
126   internal_stream_manager_ = internal_stream_manager;
127   // Set id back to raw_stream and then HWL can get correct HAL stream ID
128   raw_stream.id = raw_stream_id_;
129 
130   process_block_stream_config->streams = stream_config.streams;
131   // Add internal RAW stream
132   process_block_stream_config->streams.push_back(raw_stream);
133   process_block_stream_config->operation_mode = stream_config.operation_mode;
134   process_block_stream_config->session_params =
135       HalCameraMetadata::Clone(stream_config.session_params.get());
136   process_block_stream_config->stream_config_counter =
137       stream_config.stream_config_counter;
138 
139   return OK;
140 }
141 
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)142 status_t RealtimeZslRequestProcessor::SetProcessBlock(
143     std::unique_ptr<ProcessBlock> process_block) {
144   ATRACE_CALL();
145   if (process_block == nullptr) {
146     ALOGE("%s: process_block is nullptr", __FUNCTION__);
147     return BAD_VALUE;
148   }
149 
150   std::lock_guard<std::mutex> lock(process_block_lock_);
151   if (process_block_ != nullptr) {
152     ALOGE("%s: Already configured.", __FUNCTION__);
153     return ALREADY_EXISTS;
154   }
155 
156   process_block_ = std::move(process_block);
157   return OK;
158 }
159 
ProcessRequest(const CaptureRequest & request)160 status_t RealtimeZslRequestProcessor::ProcessRequest(
161     const CaptureRequest& request) {
162   ATRACE_CALL();
163   std::lock_guard<std::mutex> lock(process_block_lock_);
164   if (process_block_ == nullptr) {
165     ALOGE("%s: Not configured yet.", __FUNCTION__);
166     return NO_INIT;
167   }
168 
169   if (is_hdrplus_zsl_enabled_ && request.settings != nullptr) {
170     camera_metadata_ro_entry entry = {};
171     status_t res =
172         request.settings->Get(VendorTagIds::kThermalThrottling, &entry);
173     if (res != OK || entry.count != 1) {
174       ALOGW("%s: Getting thermal throttling entry failed: %s(%d)", __FUNCTION__,
175             strerror(-res), res);
176     } else if (entry.data.u8[0] == true) {
177       // Disable HDR+ ZSL once thermal throttles.
178       is_hdrplus_zsl_enabled_ = false;
179       ALOGI("%s: HDR+ ZSL disabled due to thermal throttling", __FUNCTION__);
180     }
181   }
182 
183   // Update if preview intent has been requested.
184   camera_metadata_ro_entry entry;
185   if (!preview_intent_seen_ && request.settings != nullptr &&
186       request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK) {
187     if (entry.count == 1 &&
188         *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
189       preview_intent_seen_ = true;
190       ALOGI("%s: First request with preview intent. ZSL starts.", __FUNCTION__);
191     }
192   }
193 
194   CaptureRequest block_request;
195 
196   block_request.frame_number = request.frame_number;
197   block_request.settings = HalCameraMetadata::Clone(request.settings.get());
198   block_request.input_buffers = request.input_buffers;
199   block_request.output_buffers = request.output_buffers;
200 
201   for (auto& metadata : request.input_buffer_metadata) {
202     block_request.input_buffer_metadata.push_back(
203         HalCameraMetadata::Clone(metadata.get()));
204   }
205 
206   for (auto& [camera_id, physical_metadata] : request.physical_camera_settings) {
207     block_request.physical_camera_settings[camera_id] =
208         HalCameraMetadata::Clone(physical_metadata.get());
209   }
210 
211   if (is_hdrplus_zsl_enabled_) {
212     // Get one RAW bffer from internal stream manager
213     StreamBuffer buffer = {};
214     status_t result;
215     if (preview_intent_seen_) {
216       result =
217           internal_stream_manager_->GetStreamBuffer(raw_stream_id_, &buffer);
218       if (result != OK) {
219         ALOGE("%s: frame:%d GetStreamBuffer failed.", __FUNCTION__,
220               request.frame_number);
221         return UNKNOWN_ERROR;
222       }
223     }
224 
225     // Add RAW output to capture request
226     if (preview_intent_seen_) {
227       block_request.output_buffers.push_back(buffer);
228     }
229 
230     if (block_request.settings != nullptr) {
231       bool enable_hybrid_ae =
232           (hdr_mode_ == HdrMode::kNonHdrplusMode ? false : true);
233       result = hal_utils::ModifyRealtimeRequestForHdrplus(
234           block_request.settings.get(), enable_hybrid_ae);
235       if (result != OK) {
236         ALOGE("%s: ModifyRealtimeRequestForHdrplus (%d) fail", __FUNCTION__,
237               request.frame_number);
238         return UNKNOWN_ERROR;
239       }
240 
241       if (hdr_mode_ != HdrMode::kHdrplusMode) {
242         uint8_t processing_mode =
243             static_cast<uint8_t>(ProcessingMode::kIntermediateProcessing);
244         block_request.settings->Set(VendorTagIds::kProcessingMode,
245                                     &processing_mode,
246                                     /*data_count=*/1);
247       }
248     }
249   }
250 
251   std::vector<ProcessBlockRequest> block_requests(1);
252   block_requests[0].request = std::move(block_request);
253 
254   return process_block_->ProcessRequests(block_requests, request);
255 }
256 
Flush()257 status_t RealtimeZslRequestProcessor::Flush() {
258   ATRACE_CALL();
259   std::lock_guard<std::mutex> lock(process_block_lock_);
260   if (process_block_ == nullptr) {
261     return OK;
262   }
263 
264   return process_block_->Flush();
265 }
266 
267 }  // namespace google_camera_hal
268 }  // namespace android