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