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_RgbirdRtRequestProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <cutils/properties.h>
21 #include <log/log.h>
22 #include <utils/Trace.h>
23
24 #include "hal_utils.h"
25 #include "rgbird_rt_request_processor.h"
26 #include "vendor_tag_defs.h"
27
28 namespace android {
29 namespace google_camera_hal {
30
Create(CameraDeviceSessionHwl * device_session_hwl,bool is_hdrplus_supported)31 std::unique_ptr<RgbirdRtRequestProcessor> RgbirdRtRequestProcessor::Create(
32 CameraDeviceSessionHwl* device_session_hwl, bool is_hdrplus_supported) {
33 ATRACE_CALL();
34 if (device_session_hwl == nullptr) {
35 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
36 return nullptr;
37 }
38
39 std::vector<uint32_t> physical_camera_ids =
40 device_session_hwl->GetPhysicalCameraIds();
41 if (physical_camera_ids.size() != 3) {
42 ALOGE("%s: Only support 3 cameras", __FUNCTION__);
43 return nullptr;
44 }
45
46 std::unique_ptr<HalCameraMetadata> characteristics;
47 status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
48 if (res != OK) {
49 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
50 return nullptr;
51 }
52
53 uint32_t active_array_width, active_array_height;
54 camera_metadata_ro_entry entry;
55 res = characteristics->Get(
56 ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
57 if (res == OK) {
58 active_array_width = entry.data.i32[2];
59 active_array_height = entry.data.i32[3];
60 ALOGI("%s Active size (%d x %d).", __FUNCTION__, active_array_width,
61 active_array_height);
62 } else {
63 ALOGE("%s Get active size failed: %s (%d).", __FUNCTION__, strerror(-res),
64 res);
65 return nullptr;
66 }
67
68 auto request_processor =
69 std::unique_ptr<RgbirdRtRequestProcessor>(new RgbirdRtRequestProcessor(
70 physical_camera_ids[0], physical_camera_ids[1],
71 physical_camera_ids[2], active_array_width, active_array_height,
72 is_hdrplus_supported, device_session_hwl));
73 if (request_processor == nullptr) {
74 ALOGE("%s: Creating RgbirdRtRequestProcessor failed.", __FUNCTION__);
75 return nullptr;
76 }
77
78 // TODO(b/128633958): remove this after FLL syncing is verified
79 request_processor->force_internal_stream_ =
80 property_get_bool("persist.vendor.camera.rgbird.forceinternal", false);
81 if (request_processor->force_internal_stream_) {
82 ALOGI("%s: Force creating internal streams for IR pipelines", __FUNCTION__);
83 }
84
85 // TODO(b/129910835): This prop should be removed once that logic is in place.
86 request_processor->rgb_ir_auto_cal_enabled_ =
87 property_get_bool("vendor.camera.frontdepth.enableautocal", true);
88 if (request_processor->rgb_ir_auto_cal_enabled_) {
89 ALOGI("%s: ", __FUNCTION__);
90 }
91 request_processor->is_auto_cal_session_ =
92 request_processor->IsAutocalSession();
93
94 return request_processor;
95 }
96
IsAutocalSession() const97 bool RgbirdRtRequestProcessor::IsAutocalSession() const {
98 // TODO(b/129910835): Use more specific logic to determine if a session needs
99 // to run autocal or not. Even if rgb_ir_auto_cal_enabled_ is true, it is
100 // more reasonable to only run auto cal for some sessions(e.g. 1st session
101 // after device boot that has a depth stream configured).
102 // To allow more tests, every session having a depth stream is an autocal
103 // session now.
104 return rgb_ir_auto_cal_enabled_;
105 }
106
IsAutocalRequest(uint32_t frame_number)107 bool RgbirdRtRequestProcessor::IsAutocalRequest(uint32_t frame_number) {
108 // TODO(b/129910835): Refine the logic here to only trigger auto cal for
109 // specific request. The result/request processor and depth process block has
110 // final right to determine if an internal yuv stream buffer will be used for
111 // autocal.
112 // The current logic is to trigger the autocal in the kAutocalFrameNumber
113 // frame. This must be consistent with that of result_request_processor.
114 if (!is_auto_cal_session_ || auto_cal_triggered_ ||
115 frame_number != kAutocalFrameNumber ||
116 depth_stream_id_ == kStreamIdInvalid) {
117 return false;
118 }
119
120 auto_cal_triggered_ = true;
121 return true;
122 }
123
RgbirdRtRequestProcessor(uint32_t rgb_camera_id,uint32_t ir1_camera_id,uint32_t ir2_camera_id,uint32_t active_array_width,uint32_t active_array_height,bool is_hdrplus_supported,CameraDeviceSessionHwl * device_session_hwl)124 RgbirdRtRequestProcessor::RgbirdRtRequestProcessor(
125 uint32_t rgb_camera_id, uint32_t ir1_camera_id, uint32_t ir2_camera_id,
126 uint32_t active_array_width, uint32_t active_array_height,
127 bool is_hdrplus_supported, CameraDeviceSessionHwl* device_session_hwl)
128 : kRgbCameraId(rgb_camera_id),
129 kIr1CameraId(ir1_camera_id),
130 kIr2CameraId(ir2_camera_id),
131 rgb_active_array_width_(active_array_width),
132 rgb_active_array_height_(active_array_height),
133 is_hdrplus_supported_(is_hdrplus_supported),
134 is_hdrplus_zsl_enabled_(is_hdrplus_supported),
135 device_session_hwl_(device_session_hwl) {
136 ALOGI(
137 "%s: Created a RGBIRD RT request processor for RGB %u, IR1 %u, IR2 %u, "
138 "is_hdrplus_supported_ :%d",
139 __FUNCTION__, kRgbCameraId, kIr1CameraId, kIr2CameraId,
140 is_hdrplus_supported_);
141 }
142
FindSmallestNonWarpedYuvStreamResolution(uint32_t * yuv_w_adjusted,uint32_t * yuv_h_adjusted)143 status_t RgbirdRtRequestProcessor::FindSmallestNonWarpedYuvStreamResolution(
144 uint32_t* yuv_w_adjusted, uint32_t* yuv_h_adjusted) {
145 if (yuv_w_adjusted == nullptr || yuv_h_adjusted == nullptr) {
146 ALOGE("%s: yuv_w_adjusted or yuv_h_adjusted is nullptr.", __FUNCTION__);
147 return BAD_VALUE;
148 }
149
150 std::unique_ptr<HalCameraMetadata> characteristics;
151 status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
152 if (res != OK) {
153 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
154 return UNKNOWN_ERROR;
155 }
156 camera_metadata_ro_entry entry;
157 res = characteristics->Get(VendorTagIds::kAvailableNonWarpedYuvSizes, &entry);
158 if (res != OK) {
159 ALOGE("%s Get stream size failed: %s (%d).", __FUNCTION__, strerror(-res),
160 res);
161 return UNKNOWN_ERROR;
162 }
163
164 uint32_t min_area = std::numeric_limits<uint32_t>::max();
165 uint32_t current_area = 0;
166 for (size_t i = 0; i < entry.count; i += 2) {
167 current_area = entry.data.i32[i] * entry.data.i32[i + 1];
168 if (current_area < min_area) {
169 *yuv_w_adjusted = entry.data.i32[i];
170 *yuv_h_adjusted = entry.data.i32[i + 1];
171 min_area = current_area;
172 }
173 }
174
175 return OK;
176 }
177
FindSmallestResolutionForInternalYuvStream(const StreamConfiguration & process_block_stream_config,uint32_t * yuv_w_adjusted,uint32_t * yuv_h_adjusted)178 status_t RgbirdRtRequestProcessor::FindSmallestResolutionForInternalYuvStream(
179 const StreamConfiguration& process_block_stream_config,
180 uint32_t* yuv_w_adjusted, uint32_t* yuv_h_adjusted) {
181 if (yuv_w_adjusted == nullptr || yuv_h_adjusted == nullptr) {
182 ALOGE("%s: yuv_w_adjusted or yuv_h_adjusted is nullptr.", __FUNCTION__);
183 return BAD_VALUE;
184 }
185
186 *yuv_w_adjusted = kDefaultYuvStreamWidth;
187 *yuv_h_adjusted = kDefaultYuvStreamHeight;
188 uint32_t framework_non_raw_w = 0;
189 uint32_t framework_non_raw_h = 0;
190 bool non_raw_non_depth_stream_configured = false;
191 for (auto& stream : process_block_stream_config.streams) {
192 if (!utils::IsRawStream(stream) && !utils::IsDepthStream(stream)) {
193 non_raw_non_depth_stream_configured = true;
194 framework_non_raw_w = stream.width;
195 framework_non_raw_h = stream.height;
196 break;
197 }
198 }
199
200 std::unique_ptr<HalCameraMetadata> characteristics;
201 status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
202 if (res != OK) {
203 ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
204 return UNKNOWN_ERROR;
205 }
206 camera_metadata_ro_entry entry;
207 res = characteristics->Get(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
208 &entry);
209 if (res != OK) {
210 ALOGE("%s Get stream size failed: %s (%d).", __FUNCTION__, strerror(-res),
211 res);
212 return UNKNOWN_ERROR;
213 }
214
215 uint32_t min_area = std::numeric_limits<uint32_t>::max();
216 uint32_t current_area = 0;
217 if (non_raw_non_depth_stream_configured) {
218 bool found_matching_aspect_ratio = false;
219 for (size_t i = 0; i < entry.count; i += 4) {
220 uint8_t format = entry.data.i32[i];
221 if ((format == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
222 (entry.data.i32[i + 3] ==
223 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
224 current_area = entry.data.i32[i + 1] * entry.data.i32[i + 2];
225 if ((entry.data.i32[i + 1] * framework_non_raw_h ==
226 entry.data.i32[i + 2] * framework_non_raw_w) &&
227 (current_area < min_area)) {
228 *yuv_w_adjusted = entry.data.i32[i + 1];
229 *yuv_h_adjusted = entry.data.i32[i + 2];
230 min_area = current_area;
231 found_matching_aspect_ratio = true;
232 }
233 }
234 }
235 if (!found_matching_aspect_ratio) {
236 ALOGE(
237 "%s: No matching aspect ratio can be found in the available stream"
238 "config resolution list.",
239 __FUNCTION__);
240 return UNKNOWN_ERROR;
241 }
242 } else {
243 ALOGI(
244 "No YUV stream configured, ues smallest resolution for internal "
245 "stream.");
246 for (size_t i = 0; i < entry.count; i += 4) {
247 if ((entry.data.i32[i] == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
248 (entry.data.i32[i + 3] ==
249 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
250 current_area = entry.data.i32[i + 1] * entry.data.i32[i + 2];
251 if (current_area < min_area) {
252 *yuv_w_adjusted = entry.data.i32[i + 1];
253 *yuv_h_adjusted = entry.data.i32[i + 2];
254 min_area = current_area;
255 }
256 }
257 }
258 }
259
260 if ((*yuv_w_adjusted == 0) || (*yuv_h_adjusted == 0)) {
261 ALOGE("%s Get internal YUV stream size failed.", __FUNCTION__);
262 return UNKNOWN_ERROR;
263 }
264
265 return OK;
266 }
267
SetNonWarpedYuvStreamId(int32_t non_warped_yuv_stream_id,StreamConfiguration * process_block_stream_config)268 status_t RgbirdRtRequestProcessor::SetNonWarpedYuvStreamId(
269 int32_t non_warped_yuv_stream_id,
270 StreamConfiguration* process_block_stream_config) {
271 if (process_block_stream_config == nullptr) {
272 ALOGE("%s: process_block_stream_config is nullptr.", __FUNCTION__);
273 return BAD_VALUE;
274 }
275
276 if (process_block_stream_config->session_params == nullptr) {
277 uint32_t num_entries = 128;
278 uint32_t data_bytes = 512;
279
280 process_block_stream_config->session_params =
281 HalCameraMetadata::Create(num_entries, data_bytes);
282 if (process_block_stream_config->session_params == nullptr) {
283 ALOGE("%s: Failed to create session parameter.", __FUNCTION__);
284 return UNKNOWN_ERROR;
285 }
286 }
287
288 auto logical_metadata = process_block_stream_config->session_params.get();
289
290 status_t res = logical_metadata->Set(VendorTagIds::kNonWarpedYuvStreamId,
291 &non_warped_yuv_stream_id, 1);
292 if (res != OK) {
293 ALOGE("%s: Failed to update VendorTagIds::kNonWarpedYuvStreamId: %s(%d)",
294 __FUNCTION__, strerror(-res), res);
295 return UNKNOWN_ERROR;
296 }
297
298 return res;
299 }
300
CreateDepthInternalStreams(InternalStreamManager * internal_stream_manager,StreamConfiguration * process_block_stream_config)301 status_t RgbirdRtRequestProcessor::CreateDepthInternalStreams(
302 InternalStreamManager* internal_stream_manager,
303 StreamConfiguration* process_block_stream_config) {
304 ATRACE_CALL();
305
306 uint32_t yuv_w_adjusted = 0;
307 uint32_t yuv_h_adjusted = 0;
308 status_t result = OK;
309
310 if (IsAutocalSession()) {
311 result = FindSmallestNonWarpedYuvStreamResolution(&yuv_w_adjusted,
312 &yuv_h_adjusted);
313 if (result != OK) {
314 ALOGE("%s: Could not find non-warped YUV resolution for internal YUV.",
315 __FUNCTION__);
316 return UNKNOWN_ERROR;
317 }
318 } else {
319 result = FindSmallestResolutionForInternalYuvStream(
320 *process_block_stream_config, &yuv_w_adjusted, &yuv_h_adjusted);
321 if (result != OK) {
322 ALOGE("%s: Could not find compatible resolution for internal YUV.",
323 __FUNCTION__);
324 return UNKNOWN_ERROR;
325 }
326 }
327
328 ALOGI("Depth internal YUV stream (%d x %d)", yuv_w_adjusted, yuv_h_adjusted);
329 // create internal streams:
330 // 1 YUV(must have for autocal and 3-sensor syncing)
331 // 2 RAW(must have to generate depth)
332 Stream yuv_stream;
333 yuv_stream.stream_type = StreamType::kOutput;
334 yuv_stream.width = yuv_w_adjusted;
335 yuv_stream.height = yuv_h_adjusted;
336 yuv_stream.format = HAL_PIXEL_FORMAT_YCBCR_420_888;
337 yuv_stream.usage = 0;
338 yuv_stream.rotation = StreamRotation::kRotation0;
339 yuv_stream.data_space = HAL_DATASPACE_ARBITRARY;
340 yuv_stream.is_physical_camera_stream = true;
341 yuv_stream.physical_camera_id = kRgbCameraId;
342
343 result = internal_stream_manager->RegisterNewInternalStream(
344 yuv_stream, &rgb_yuv_stream_id_);
345 if (result != OK) {
346 ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
347 return UNKNOWN_ERROR;
348 }
349 yuv_stream.id = rgb_yuv_stream_id_;
350
351 if (IsAutocalSession()) {
352 result = SetNonWarpedYuvStreamId(rgb_yuv_stream_id_,
353 process_block_stream_config);
354 }
355
356 if (result != OK) {
357 ALOGE("%s: Failed to set no post processing yuv stream id.", __FUNCTION__);
358 return UNKNOWN_ERROR;
359 }
360
361 Stream raw_stream[2];
362 for (uint32_t i = 0; i < 2; i++) {
363 raw_stream[i].stream_type = StreamType::kOutput;
364 raw_stream[i].width = 640;
365 raw_stream[i].height = 480;
366 raw_stream[i].format = HAL_PIXEL_FORMAT_Y8;
367 raw_stream[i].usage = 0;
368 raw_stream[i].rotation = StreamRotation::kRotation0;
369 raw_stream[i].data_space = HAL_DATASPACE_ARBITRARY;
370 raw_stream[i].is_physical_camera_stream = true;
371
372 status_t result = internal_stream_manager->RegisterNewInternalStream(
373 raw_stream[i], &ir_raw_stream_id_[i]);
374 if (result != OK) {
375 ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
376 return UNKNOWN_ERROR;
377 }
378 raw_stream[i].id = ir_raw_stream_id_[i];
379 }
380
381 raw_stream[0].physical_camera_id = kIr1CameraId;
382 raw_stream[1].physical_camera_id = kIr2CameraId;
383
384 process_block_stream_config->streams.push_back(yuv_stream);
385 process_block_stream_config->streams.push_back(raw_stream[0]);
386 process_block_stream_config->streams.push_back(raw_stream[1]);
387
388 return OK;
389 }
390
RegisterHdrplusInternalRaw(StreamConfiguration * process_block_stream_config)391 status_t RgbirdRtRequestProcessor::RegisterHdrplusInternalRaw(
392 StreamConfiguration* process_block_stream_config) {
393 ATRACE_CALL();
394 if (process_block_stream_config == nullptr) {
395 ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
396 return BAD_VALUE;
397 }
398
399 // Register internal raw stream
400 Stream raw_stream;
401 raw_stream.stream_type = StreamType::kOutput;
402 raw_stream.width = rgb_active_array_width_;
403 raw_stream.height = rgb_active_array_height_;
404 raw_stream.format = HAL_PIXEL_FORMAT_RAW10;
405 raw_stream.usage = 0;
406 raw_stream.rotation = StreamRotation::kRotation0;
407 raw_stream.data_space = HAL_DATASPACE_ARBITRARY;
408
409 status_t result = internal_stream_manager_->RegisterNewInternalStream(
410 raw_stream, &rgb_raw_stream_id_);
411 if (result != OK) {
412 ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
413 return UNKNOWN_ERROR;
414 }
415 // Set id back to raw_stream and then HWL can get correct HAL stream ID
416 raw_stream.id = rgb_raw_stream_id_;
417
418 raw_stream.is_physical_camera_stream = true;
419 raw_stream.physical_camera_id = kRgbCameraId;
420
421 // Add internal RAW stream
422 process_block_stream_config->streams.push_back(raw_stream);
423 return OK;
424 }
425
ConfigureStreams(InternalStreamManager * internal_stream_manager,const StreamConfiguration & stream_config,StreamConfiguration * process_block_stream_config)426 status_t RgbirdRtRequestProcessor::ConfigureStreams(
427 InternalStreamManager* internal_stream_manager,
428 const StreamConfiguration& stream_config,
429 StreamConfiguration* process_block_stream_config) {
430 ATRACE_CALL();
431 if (process_block_stream_config == nullptr) {
432 ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
433 return BAD_VALUE;
434 }
435
436 internal_stream_manager_ = internal_stream_manager;
437 if (is_hdrplus_supported_) {
438 status_t result = RegisterHdrplusInternalRaw(process_block_stream_config);
439 if (result != OK) {
440 ALOGE("%s: RegisterHdrplusInternalRaw failed.", __FUNCTION__);
441 return UNKNOWN_ERROR;
442 }
443 }
444
445 process_block_stream_config->operation_mode = stream_config.operation_mode;
446 process_block_stream_config->session_params =
447 HalCameraMetadata::Clone(stream_config.session_params.get());
448 process_block_stream_config->stream_config_counter =
449 stream_config.stream_config_counter;
450
451 bool has_depth_stream = false;
452 for (auto& stream : stream_config.streams) {
453 if (utils::IsDepthStream(stream)) {
454 has_depth_stream = true;
455 depth_stream_id_ = stream.id;
456 continue;
457 }
458
459 auto pb_stream = stream;
460 // Assign all logical streams to RGB camera.
461 if (!pb_stream.is_physical_camera_stream) {
462 pb_stream.is_physical_camera_stream = true;
463 pb_stream.physical_camera_id = kRgbCameraId;
464 }
465
466 process_block_stream_config->streams.push_back(pb_stream);
467 }
468
469 // TODO(b/128633958): remove the force flag after FLL syncing is verified
470 if (force_internal_stream_ || has_depth_stream) {
471 CreateDepthInternalStreams(internal_stream_manager,
472 process_block_stream_config);
473 }
474
475 return OK;
476 }
477
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)478 status_t RgbirdRtRequestProcessor::SetProcessBlock(
479 std::unique_ptr<ProcessBlock> process_block) {
480 ATRACE_CALL();
481 if (process_block == nullptr) {
482 ALOGE("%s: process_block is nullptr", __FUNCTION__);
483 return BAD_VALUE;
484 }
485
486 std::lock_guard<std::mutex> lock(process_block_lock_);
487 if (process_block_ != nullptr) {
488 ALOGE("%s: Already configured.", __FUNCTION__);
489 return ALREADY_EXISTS;
490 }
491
492 process_block_ = std::move(process_block);
493 return OK;
494 }
495
AddIrRawProcessBlockRequestLocked(std::vector<ProcessBlockRequest> * block_requests,const CaptureRequest & request,uint32_t camera_id)496 status_t RgbirdRtRequestProcessor::AddIrRawProcessBlockRequestLocked(
497 std::vector<ProcessBlockRequest>* block_requests,
498 const CaptureRequest& request, uint32_t camera_id) {
499 ATRACE_CALL();
500 uint32_t stream_id_index = 0;
501
502 if (camera_id == kIr1CameraId) {
503 stream_id_index = 0;
504 } else if (camera_id == kIr2CameraId) {
505 stream_id_index = 1;
506 } else {
507 ALOGE("%s: Unknown IR camera id %d", __FUNCTION__, camera_id);
508 return INVALID_OPERATION;
509 }
510
511 ProcessBlockRequest block_request = {.request_id = camera_id};
512 CaptureRequest& physical_request = block_request.request;
513 physical_request.frame_number = request.frame_number;
514 physical_request.settings = HalCameraMetadata::Clone(request.settings.get());
515
516 // TODO(b/128633958): Remap the crop region for IR sensors properly.
517 // The crop region cloned from logical camera control settings causes mass log
518 // spew from the IR pipelines. Force the crop region for now as a WAR.
519 if (physical_request.settings != nullptr) {
520 camera_metadata_ro_entry_t entry_crop_region_user = {};
521 if (physical_request.settings->Get(ANDROID_SCALER_CROP_REGION,
522 &entry_crop_region_user) == OK) {
523 const uint32_t ir_crop_region[4] = {0, 0, 640, 480};
524 physical_request.settings->Set(
525 ANDROID_SCALER_CROP_REGION,
526 reinterpret_cast<const int32_t*>(&ir_crop_region),
527 sizeof(ir_crop_region) / sizeof(int32_t));
528 }
529 }
530 // Requests for IR pipelines should not include any input buffer or metadata
531 // physical_request.input_buffers
532 // physical_request.input_buffer_metadata
533
534 StreamBuffer internal_buffer = {};
535 status_t res = internal_stream_manager_->GetStreamBuffer(
536 ir_raw_stream_id_[stream_id_index], &internal_buffer);
537 if (res != OK) {
538 ALOGE(
539 "%s: Failed to get internal stream buffer for frame %d, stream id"
540 " %d: %s(%d)",
541 __FUNCTION__, request.frame_number, ir_raw_stream_id_[0],
542 strerror(-res), res);
543 return UNKNOWN_ERROR;
544 }
545 physical_request.output_buffers.push_back(internal_buffer);
546
547 physical_request.physical_camera_settings[camera_id] =
548 HalCameraMetadata::Clone(request.settings.get());
549
550 block_requests->push_back(std::move(block_request));
551
552 return OK;
553 }
554
TryAddRgbProcessBlockRequestLocked(std::vector<ProcessBlockRequest> * block_requests,const CaptureRequest & request)555 status_t RgbirdRtRequestProcessor::TryAddRgbProcessBlockRequestLocked(
556 std::vector<ProcessBlockRequest>* block_requests,
557 const CaptureRequest& request) {
558 ATRACE_CALL();
559 if (block_requests == nullptr) {
560 ALOGE("%s: block_requests is nullptr.", __FUNCTION__);
561 return UNKNOWN_ERROR;
562 }
563
564 ProcessBlockRequest block_request = {.request_id = kRgbCameraId};
565 CaptureRequest& physical_request = block_request.request;
566
567 for (auto& output_buffer : request.output_buffers) {
568 if (output_buffer.stream_id != depth_stream_id_) {
569 physical_request.output_buffers.push_back(output_buffer);
570 }
571 }
572
573 if (is_hdrplus_zsl_enabled_ && request.settings != nullptr) {
574 camera_metadata_ro_entry entry = {};
575 status_t res =
576 request.settings->Get(VendorTagIds::kThermalThrottling, &entry);
577 if (res != OK || entry.count != 1) {
578 ALOGW("%s: Getting thermal throttling entry failed: %s(%d)", __FUNCTION__,
579 strerror(-res), res);
580 } else if (entry.data.u8[0] == true) {
581 // Disable HDR+ once thermal throttles.
582 is_hdrplus_zsl_enabled_ = false;
583 ALOGI("%s: HDR+ ZSL disabled due to thermal throttling", __FUNCTION__);
584 }
585 }
586
587 // Disable HDR+ for thermal throttling.
588 if (is_hdrplus_zsl_enabled_) {
589 status_t res = TryAddHdrplusRawOutputLocked(&physical_request, request);
590 if (res != OK) {
591 ALOGE("%s: AddHdrplusRawOutput fail", __FUNCTION__);
592 return res;
593 }
594 } else if (physical_request.output_buffers.empty() ||
595 IsAutocalRequest(request.frame_number)) {
596 status_t res = TryAddDepthInternalYuvOutputLocked(&physical_request);
597 if (res != OK) {
598 ALOGE("%s: AddDepthOnlyRawOutput failed.", __FUNCTION__);
599 return res;
600 }
601 }
602
603 // In case there is only one depth stream
604 if (!physical_request.output_buffers.empty()) {
605 physical_request.frame_number = request.frame_number;
606 physical_request.settings = HalCameraMetadata::Clone(request.settings.get());
607
608 if (is_hdrplus_zsl_enabled_ && physical_request.settings != nullptr) {
609 status_t res = hal_utils::ModifyRealtimeRequestForHdrplus(
610 physical_request.settings.get());
611 if (res != OK) {
612 ALOGE("%s: ModifyRealtimeRequestForHdrplus (%d) fail", __FUNCTION__,
613 request.frame_number);
614 return UNKNOWN_ERROR;
615 }
616 }
617
618 physical_request.input_buffers = request.input_buffers;
619
620 for (auto& metadata : request.input_buffer_metadata) {
621 physical_request.input_buffer_metadata.push_back(
622 HalCameraMetadata::Clone(metadata.get()));
623 }
624
625 block_requests->push_back(std::move(block_request));
626 }
627 return OK;
628 }
629
TryAddDepthInternalYuvOutputLocked(CaptureRequest * block_request)630 status_t RgbirdRtRequestProcessor::TryAddDepthInternalYuvOutputLocked(
631 CaptureRequest* block_request) {
632 if (block_request == nullptr) {
633 ALOGE("%s: block_request is nullptr.", __FUNCTION__);
634 return UNKNOWN_ERROR;
635 }
636
637 StreamBuffer buffer = {};
638 status_t result =
639 internal_stream_manager_->GetStreamBuffer(rgb_yuv_stream_id_, &buffer);
640 if (result != OK) {
641 ALOGE("%s: GetStreamBuffer failed.", __FUNCTION__);
642 return UNKNOWN_ERROR;
643 }
644 block_request->output_buffers.push_back(buffer);
645
646 return OK;
647 }
648
TryAddHdrplusRawOutputLocked(CaptureRequest * block_request,const CaptureRequest & request)649 status_t RgbirdRtRequestProcessor::TryAddHdrplusRawOutputLocked(
650 CaptureRequest* block_request, const CaptureRequest& request) {
651 ATRACE_CALL();
652 if (block_request == nullptr) {
653 ALOGE("%s: block_request is nullptr.", __FUNCTION__);
654 return UNKNOWN_ERROR;
655 }
656
657 // Update if preview intent has been requested.
658 camera_metadata_ro_entry entry;
659 if (!preview_intent_seen_ && request.settings != nullptr &&
660 request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK) {
661 if (entry.count == 1 &&
662 *entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
663 preview_intent_seen_ = true;
664 ALOGI("%s: First request with preview intent. ZSL starts.", __FUNCTION__);
665 }
666 }
667
668 // Get one RAW bffer from internal stream manager
669 // Add RAW output to capture request
670 if (preview_intent_seen_) {
671 StreamBuffer buffer = {};
672 status_t result =
673 internal_stream_manager_->GetStreamBuffer(rgb_raw_stream_id_, &buffer);
674 if (result != OK) {
675 ALOGE("%s: frame:%d GetStreamBuffer failed.", __FUNCTION__,
676 request.frame_number);
677 return UNKNOWN_ERROR;
678 }
679 block_request->output_buffers.push_back(buffer);
680 }
681
682 return OK;
683 }
684
ProcessRequest(const CaptureRequest & request)685 status_t RgbirdRtRequestProcessor::ProcessRequest(const CaptureRequest& request) {
686 ATRACE_CALL();
687 std::lock_guard<std::mutex> lock(process_block_lock_);
688 if (process_block_ == nullptr) {
689 ALOGE("%s: Not configured yet.", __FUNCTION__);
690 return NO_INIT;
691 }
692
693 // Rgbird should not have phys settings
694 if (!request.physical_camera_settings.empty()) {
695 ALOGE("%s: Rgbird capture session does not support physical settings.",
696 __FUNCTION__);
697 return UNKNOWN_ERROR;
698 }
699
700 {
701 std::vector<ProcessBlockRequest> block_requests;
702 status_t res = TryAddRgbProcessBlockRequestLocked(&block_requests, request);
703 if (res != OK) {
704 ALOGE("%s: Failed to add process block request for rgb pipeline.",
705 __FUNCTION__);
706 return res;
707 }
708
709 // TODO(b/128633958): Remove the force flag after FLL sync is verified
710 if (force_internal_stream_ || depth_stream_id_ != kStreamIdInvalid) {
711 res = AddIrRawProcessBlockRequestLocked(&block_requests, request,
712 kIr1CameraId);
713 if (res != OK) {
714 ALOGE("%s: Failed to add process block request for ir1 pipeline.",
715 __FUNCTION__);
716 return res;
717 }
718 res = AddIrRawProcessBlockRequestLocked(&block_requests, request,
719 kIr2CameraId);
720 if (res != OK) {
721 ALOGE("%s: Failed to add process block request for ir2 pipeline.",
722 __FUNCTION__);
723 return res;
724 }
725 }
726
727 return process_block_->ProcessRequests(block_requests, request);
728 }
729 }
730
Flush()731 status_t RgbirdRtRequestProcessor::Flush() {
732 ATRACE_CALL();
733 std::lock_guard<std::mutex> lock(process_block_lock_);
734 if (process_block_ == nullptr) {
735 return OK;
736 }
737
738 return process_block_->Flush();
739 }
740
741 } // namespace google_camera_hal
742 } // namespace android