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