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_RgbirdCaptureSession"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "rgbird_capture_session.h"
21 
22 #include <cutils/properties.h>
23 #include <inttypes.h>
24 #include <log/log.h>
25 #include <utils/Trace.h>
26 
27 #include <set>
28 
29 #include "basic_result_processor.h"
30 #include "depth_process_block.h"
31 #include "hal_utils.h"
32 #include "hdrplus_process_block.h"
33 #include "hdrplus_request_processor.h"
34 #include "hdrplus_result_processor.h"
35 #include "multicam_realtime_process_block.h"
36 #include "rgbird_depth_result_processor.h"
37 #include "rgbird_result_request_processor.h"
38 #include "rgbird_rt_request_processor.h"
39 
40 namespace android {
41 namespace google_camera_hal {
42 
IsStreamConfigurationSupported(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration &)43 bool RgbirdCaptureSession::IsStreamConfigurationSupported(
44     CameraDeviceSessionHwl* device_session_hwl,
45     const StreamConfiguration& /*stream_config*/) {
46   ATRACE_CALL();
47   if (device_session_hwl == nullptr) {
48     ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
49     return false;
50   }
51 
52   std::vector<uint32_t> physical_camera_ids =
53       device_session_hwl->GetPhysicalCameraIds();
54   if (physical_camera_ids.size() != 3) {
55     ALOGD("%s: RgbirdCaptureSession doesn't support %zu physical cameras",
56           __FUNCTION__, physical_camera_ids.size());
57     return false;
58   }
59 
60   // Check if this is a logical camera containing two IR cameras.
61   uint32_t num_ir_camera = 0;
62   for (auto id : physical_camera_ids) {
63     std::unique_ptr<HalCameraMetadata> characteristics;
64     status_t res = device_session_hwl->GetPhysicalCameraCharacteristics(
65         id, &characteristics);
66 
67     if (res != OK) {
68       ALOGE("%s: Cannot get physical camera characteristics for camera %u",
69             __FUNCTION__, id);
70       return false;
71     }
72 
73     // TODO(b/129088371): Work around b/129088371 because current IR camera's
74     // CFA is MONO instead of NIR.
75     if (hal_utils::IsIrCamera(characteristics.get()) ||
76         hal_utils::IsMonoCamera(characteristics.get())) {
77       num_ir_camera++;
78     }
79   }
80 
81   if (num_ir_camera != 2) {
82     ALOGD("%s: RgbirdCaptureSession only supports 2 ir cameras", __FUNCTION__);
83     return false;
84   }
85 
86   ALOGD("%s: RgbirdCaptureSession supports the stream config", __FUNCTION__);
87   return true;
88 }
89 
Create(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,ProcessBatchCaptureResultFunc,NotifyFunc notify,HwlSessionCallback session_callback,std::vector<HalStream> * hal_configured_streams,CameraBufferAllocatorHwl *)90 std::unique_ptr<CaptureSession> RgbirdCaptureSession::Create(
91     CameraDeviceSessionHwl* device_session_hwl,
92     const StreamConfiguration& stream_config,
93     ProcessCaptureResultFunc process_capture_result,
94     ProcessBatchCaptureResultFunc /*process_batch_capture_result*/,
95     NotifyFunc notify, HwlSessionCallback session_callback,
96     std::vector<HalStream>* hal_configured_streams,
97     CameraBufferAllocatorHwl* /*camera_allocator_hwl*/) {
98   ATRACE_CALL();
99   auto session =
100       std::unique_ptr<RgbirdCaptureSession>(new RgbirdCaptureSession());
101   if (session == nullptr) {
102     ALOGE("%s: Creating RgbirdCaptureSession failed.", __FUNCTION__);
103     return nullptr;
104   }
105 
106   status_t res = session->Initialize(
107       device_session_hwl, stream_config, process_capture_result, notify,
108       session_callback.request_stream_buffers, hal_configured_streams);
109   if (res != OK) {
110     ALOGE("%s: Initializing RgbirdCaptureSession failed: %s (%d).",
111           __FUNCTION__, strerror(-res), res);
112     return nullptr;
113   }
114 
115   return session;
116 }
117 
~RgbirdCaptureSession()118 RgbirdCaptureSession::~RgbirdCaptureSession() {
119   if (device_session_hwl_ != nullptr) {
120     device_session_hwl_->DestroyPipelines();
121   }
122 
123   rt_request_processor_ = nullptr;
124   hdrplus_request_processor_ = nullptr;
125   result_dispatcher_ = nullptr;
126 }
127 
AreAllStreamsConfigured(const StreamConfiguration & stream_config,const StreamConfiguration & process_block_stream_config) const128 bool RgbirdCaptureSession::AreAllStreamsConfigured(
129     const StreamConfiguration& stream_config,
130     const StreamConfiguration& process_block_stream_config) const {
131   ATRACE_CALL();
132   // Check all streams are configured.
133   if (stream_config.streams.size() > process_block_stream_config.streams.size()) {
134     ALOGE("%s: stream_config has %zu streams but only configured %zu streams",
135           __FUNCTION__, stream_config.streams.size(),
136           process_block_stream_config.streams.size());
137     return false;
138   }
139 
140   for (auto& stream : stream_config.streams) {
141     bool found = false;
142     for (auto& configured_stream : process_block_stream_config.streams) {
143       if (stream.id == configured_stream.id) {
144         found = true;
145         break;
146       }
147     }
148 
149     if (!found) {
150       ALOGE("%s: Cannot find stream %u in configured streams.", __FUNCTION__,
151             stream.id);
152       return false;
153     }
154   }
155 
156   return true;
157 }
158 
ConfigureStreams(const StreamConfiguration & stream_config,RequestProcessor * request_processor,ProcessBlock * process_block,StreamConfiguration * process_block_stream_config)159 status_t RgbirdCaptureSession::ConfigureStreams(
160     const StreamConfiguration& stream_config,
161     RequestProcessor* request_processor, ProcessBlock* process_block,
162     StreamConfiguration* process_block_stream_config) {
163   ATRACE_CALL();
164   if (request_processor == nullptr || process_block == nullptr ||
165       process_block_stream_config == nullptr) {
166     ALOGE(
167         "%s: request_processor(%p) or process_block(%p) or "
168         "process_block_stream_config(%p) is nullptr",
169         __FUNCTION__, request_processor, process_block,
170         process_block_stream_config);
171     return BAD_VALUE;
172   }
173 
174   status_t res = request_processor->ConfigureStreams(
175       internal_stream_manager_.get(), stream_config,
176       process_block_stream_config);
177   if (res != OK) {
178     ALOGE("%s: Configuring stream for RequestProcessor failed: %s(%d)",
179           __FUNCTION__, strerror(-res), res);
180     return res;
181   }
182 
183   res = process_block->ConfigureStreams(*process_block_stream_config,
184                                         stream_config);
185   if (res != OK) {
186     ALOGE("%s: Configuring streams for ProcessBlock failed: %s(%d)",
187           __FUNCTION__, strerror(-res), res);
188     return res;
189   }
190 
191   return OK;
192 }
193 
SetDepthInternalStreamId(const StreamConfiguration & process_block_stream_config,const StreamConfiguration & stream_config)194 status_t RgbirdCaptureSession::SetDepthInternalStreamId(
195     const StreamConfiguration& process_block_stream_config,
196     const StreamConfiguration& stream_config) {
197   // Assuming there is at most one internal YUV stream configured when this
198   // function is called(i.e. when depth stream is configured).
199   for (auto& configured_stream : process_block_stream_config.streams) {
200     if (configured_stream.format == HAL_PIXEL_FORMAT_YCBCR_420_888) {
201       bool matching_found = false;
202       for (auto& framework_stream : stream_config.streams) {
203         if (configured_stream.id == framework_stream.id) {
204           matching_found = true;
205           break;
206         }
207       }
208       if (!matching_found) {
209         rgb_internal_yuv_stream_id_ = configured_stream.id;
210       }
211     } else if (configured_stream.format == HAL_PIXEL_FORMAT_Y8) {
212       if (configured_stream.physical_camera_id == ir1_camera_id_) {
213         ir1_internal_raw_stream_id_ = configured_stream.id;
214       } else if (configured_stream.physical_camera_id == ir2_camera_id_) {
215         ir2_internal_raw_stream_id_ = configured_stream.id;
216       } else {
217         ALOGV("%s: Y8 stream found from non-IR sensors.", __FUNCTION__);
218       }
219     }
220   }
221 
222   if (rgb_internal_yuv_stream_id_ == kInvalidStreamId ||
223       ir1_internal_raw_stream_id_ == kInvalidStreamId ||
224       ir2_internal_raw_stream_id_ == kInvalidStreamId) {
225     ALOGE(
226         "%s: Internal YUV or IR stream not found in "
227         "process_block_stream_config.",
228         __FUNCTION__);
229     return UNKNOWN_ERROR;
230   }
231 
232   return OK;
233 }
234 
ConfigureHdrplusRawStreamId(const StreamConfiguration & process_block_stream_config)235 status_t RgbirdCaptureSession::ConfigureHdrplusRawStreamId(
236     const StreamConfiguration& process_block_stream_config) {
237   ATRACE_CALL();
238   std::unique_ptr<HalCameraMetadata> characteristics;
239   status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
240   if (res != OK) {
241     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
242     return BAD_VALUE;
243   }
244 
245   uint32_t active_array_width, active_array_height;
246   camera_metadata_ro_entry entry;
247   res = characteristics->Get(
248       ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
249   if (res == OK) {
250     active_array_width = entry.data.i32[2];
251     active_array_height = entry.data.i32[3];
252     ALOGI("%s Active size (%d x %d).", __FUNCTION__, active_array_width,
253           active_array_height);
254   } else {
255     ALOGE("%s Get active size failed: %s (%d).", __FUNCTION__, strerror(-res),
256           res);
257     return UNKNOWN_ERROR;
258   }
259 
260   for (auto& configured_stream : process_block_stream_config.streams) {
261     if (configured_stream.format == kHdrplusRawFormat &&
262         configured_stream.width == active_array_width &&
263         configured_stream.height == active_array_height) {
264       rgb_raw_stream_id_ = configured_stream.id;
265       break;
266     }
267   }
268 
269   if (rgb_raw_stream_id_ == -1) {
270     ALOGE("%s: Configuring stream fail due to wrong raw_stream_id",
271           __FUNCTION__);
272     return UNKNOWN_ERROR;
273   }
274 
275   return OK;
276 }
277 
AllocateInternalBuffers(const StreamConfiguration & framework_stream_config,std::vector<HalStream> * hal_configured_streams,ProcessBlock * hdrplus_process_block)278 status_t RgbirdCaptureSession::AllocateInternalBuffers(
279     const StreamConfiguration& framework_stream_config,
280     std::vector<HalStream>* hal_configured_streams,
281     ProcessBlock* hdrplus_process_block) {
282   ATRACE_CALL();
283   status_t res = OK;
284 
285   std::set<int32_t> framework_stream_id_set;
286   for (auto& stream : framework_stream_config.streams) {
287     framework_stream_id_set.insert(stream.id);
288   }
289 
290   for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
291     HalStream& hal_stream = hal_configured_streams->at(i);
292 
293     if (framework_stream_id_set.find(hal_stream.id) ==
294         framework_stream_id_set.end()) {
295       // hdrplus rgb raw stream buffers is allocated separately
296       if (hal_stream.id == rgb_raw_stream_id_) {
297         continue;
298       }
299 
300       uint32_t additional_num_buffers =
301           (hal_stream.max_buffers >= kDefaultInternalBufferCount)
302               ? 0
303               : (kDefaultInternalBufferCount - hal_stream.max_buffers);
304       res = internal_stream_manager_->AllocateBuffers(
305           hal_stream, hal_stream.max_buffers + additional_num_buffers);
306       if (res != OK) {
307         ALOGE("%s: Failed to allocate buffer for internal stream %d: %s(%d)",
308               __FUNCTION__, hal_stream.id, strerror(-res), res);
309         return res;
310       } else {
311         ALOGI("%s: Allocating %d internal buffers for stream %d", __FUNCTION__,
312               additional_num_buffers + hal_stream.max_buffers, hal_stream.id);
313       }
314     }
315   }
316 
317   if (is_hdrplus_supported_) {
318     std::vector<HalStream> hdrplus_hal_configured_streams;
319     res = hdrplus_process_block->GetConfiguredHalStreams(
320         &hdrplus_hal_configured_streams);
321     if (res != OK) {
322       ALOGE("%s: Getting HDR+ HAL streams failed: %s(%d)", __FUNCTION__,
323             strerror(-res), res);
324       return res;
325     }
326 
327     res = ConfigureHdrplusUsageAndBuffers(hal_configured_streams,
328                                           &hdrplus_hal_configured_streams);
329     if (res != OK) {
330       ALOGE("%s: ConfigureHdrplusUsageAndBuffer failed: %s(%d)", __FUNCTION__,
331             strerror(-res), res);
332       return res;
333     }
334   }
335   return res;
336 }
337 
PurgeHalConfiguredStream(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_configured_streams)338 status_t RgbirdCaptureSession::PurgeHalConfiguredStream(
339     const StreamConfiguration& stream_config,
340     std::vector<HalStream>* hal_configured_streams) {
341   if (hal_configured_streams == nullptr) {
342     ALOGE("%s: HAL configured stream list is null.", __FUNCTION__);
343     return BAD_VALUE;
344   }
345 
346   std::set<int32_t> framework_stream_id_set;
347   for (auto& stream : stream_config.streams) {
348     framework_stream_id_set.insert(stream.id);
349   }
350 
351   std::vector<HalStream> configured_streams;
352   for (auto& hal_stream : *hal_configured_streams) {
353     if (framework_stream_id_set.find(hal_stream.id) !=
354         framework_stream_id_set.end()) {
355       configured_streams.push_back(hal_stream);
356     }
357   }
358   *hal_configured_streams = configured_streams;
359   return OK;
360 }
361 
NeedDepthProcessBlock() const362 bool RgbirdCaptureSession::NeedDepthProcessBlock() const {
363   // TODO(b/128633958): remove force flag after FLL syncing is verified
364   return force_internal_stream_ || has_depth_stream_;
365 }
366 
CreateDepthChainSegment(std::unique_ptr<DepthProcessBlock> * depth_process_block,std::unique_ptr<RgbirdDepthResultProcessor> * depth_result_processor,RgbirdResultRequestProcessor * rt_result_processor,const StreamConfiguration & stream_config,const StreamConfiguration & overall_config,StreamConfiguration * depth_block_stream_config)367 status_t RgbirdCaptureSession::CreateDepthChainSegment(
368     std::unique_ptr<DepthProcessBlock>* depth_process_block,
369     std::unique_ptr<RgbirdDepthResultProcessor>* depth_result_processor,
370     RgbirdResultRequestProcessor* rt_result_processor,
371     const StreamConfiguration& stream_config,
372     const StreamConfiguration& overall_config,
373     StreamConfiguration* depth_block_stream_config) {
374   ATRACE_CALL();
375   DepthProcessBlock::DepthProcessBlockCreateData data = {
376       .rgb_internal_yuv_stream_id = rgb_internal_yuv_stream_id_,
377       .ir1_internal_raw_stream_id = ir1_internal_raw_stream_id_,
378       .ir2_internal_raw_stream_id = ir2_internal_raw_stream_id_};
379   auto process_block = DepthProcessBlock::Create(device_session_hwl_,
380                                                  request_stream_buffers_, data);
381   if (process_block == nullptr) {
382     ALOGE("%s: Creating DepthProcessBlock failed.", __FUNCTION__);
383     return UNKNOWN_ERROR;
384   }
385 
386   auto result_processor =
387       RgbirdDepthResultProcessor::Create(internal_stream_manager_.get());
388   if (result_processor == nullptr) {
389     ALOGE("%s: Creating RgbirdDepthResultProcessor", __FUNCTION__);
390     return UNKNOWN_ERROR;
391   }
392 
393   status_t res = rt_result_processor->ConfigureStreams(
394       internal_stream_manager_.get(), stream_config, depth_block_stream_config);
395   if (res != OK) {
396     ALOGE("%s: Configuring streams for ResultRequestProcessor failed: %s(%d)",
397           __FUNCTION__, strerror(-res), res);
398     return res;
399   }
400 
401   res = process_block->ConfigureStreams(*depth_block_stream_config,
402                                         overall_config);
403   if (res != OK) {
404     ALOGE("%s: Configuring streams for DepthProcessBlock failed: %s(%d)",
405           __FUNCTION__, strerror(-res), res);
406     return res;
407   }
408 
409   *depth_process_block = std::move(process_block);
410   *depth_result_processor = std::move(result_processor);
411 
412   return OK;
413 }
414 
SetupDepthChainSegment(const StreamConfiguration & stream_config,RgbirdResultRequestProcessor * realtime_result_processor,std::unique_ptr<ProcessBlock> * depth_process_block,std::unique_ptr<ResultProcessor> * depth_result_processor,StreamConfiguration * rt_process_block_stream_config)415 status_t RgbirdCaptureSession::SetupDepthChainSegment(
416     const StreamConfiguration& stream_config,
417     RgbirdResultRequestProcessor* realtime_result_processor,
418     std::unique_ptr<ProcessBlock>* depth_process_block,
419     std::unique_ptr<ResultProcessor>* depth_result_processor,
420     StreamConfiguration* rt_process_block_stream_config) {
421   ATRACE_CALL();
422   // Create the depth segment of realtime process chain if need depth processing
423   std::unique_ptr<DepthProcessBlock> d_process_block;
424   std::unique_ptr<RgbirdDepthResultProcessor> d_result_processor;
425   if (NeedDepthProcessBlock()) {
426     StreamConfiguration depth_chain_segment_stream_config;
427     status_t res =
428         MakeDepthStreamConfig(*rt_process_block_stream_config, stream_config,
429                               &depth_chain_segment_stream_config);
430     if (res != OK) {
431       ALOGE(
432           "%s: Making depth chain segment stream configuration failed: "
433           "%s(%d).",
434           __FUNCTION__, strerror(-res), res);
435       return res;
436     }
437 
438     StreamConfiguration depth_block_stream_config;
439     res = CreateDepthChainSegment(&d_process_block, &d_result_processor,
440                                   realtime_result_processor,
441                                   depth_chain_segment_stream_config,
442                                   stream_config, &depth_block_stream_config);
443     if (res != OK) {
444       ALOGE("%s: Creating depth chain segment failed: %s(%d).", __FUNCTION__,
445             strerror(-res), res);
446       return res;
447     }
448 
449     // process_block_stream_config may contain internal streams(some may be
450     // duplicated as both input and output for bridging the rt and depth
451     // segments of the realtime process chain.)
452     rt_process_block_stream_config->streams.insert(
453         rt_process_block_stream_config->streams.end(),
454         depth_block_stream_config.streams.begin(),
455         depth_block_stream_config.streams.end());
456 
457     *depth_process_block = std::move(d_process_block);
458     *depth_result_processor = std::move(d_result_processor);
459   }
460 
461   return OK;
462 }
463 
MakeDepthStreamConfig(const StreamConfiguration & rt_process_block_stream_config,const StreamConfiguration & stream_config,StreamConfiguration * depth_stream_config)464 status_t RgbirdCaptureSession::MakeDepthStreamConfig(
465     const StreamConfiguration& rt_process_block_stream_config,
466     const StreamConfiguration& stream_config,
467     StreamConfiguration* depth_stream_config) {
468   ATRACE_CALL();
469   if (depth_stream_config == nullptr) {
470     ALOGE("%s: depth_stream_config is nullptr", __FUNCTION__);
471     return BAD_VALUE;
472   }
473 
474   if (!NeedDepthProcessBlock()) {
475     ALOGE("%s: No need to create depth process chain segment stream config.",
476           __FUNCTION__);
477     return BAD_VALUE;
478   }
479 
480   // Assuming all internal streams must be for depth process block as input,
481   // if depth stream is configured by framework.
482   depth_stream_config->operation_mode = stream_config.operation_mode;
483   depth_stream_config->session_params =
484       HalCameraMetadata::Clone(stream_config.session_params.get());
485   depth_stream_config->stream_config_counter =
486       stream_config.stream_config_counter;
487   depth_stream_config->streams = stream_config.streams;
488   for (auto& stream : rt_process_block_stream_config.streams) {
489     bool is_internal_stream = true;
490     for (auto& framework_stream : stream_config.streams) {
491       if (stream.id == framework_stream.id) {
492         is_internal_stream = false;
493         break;
494       }
495     }
496 
497     // Change all internal streams to input streams and keep others untouched
498     if (is_internal_stream) {
499       Stream input_stream = stream;
500       input_stream.stream_type = StreamType::kInput;
501       depth_stream_config->streams.push_back(input_stream);
502     }
503   }
504 
505   return OK;
506 }
507 
SetupRealtimeProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::unique_ptr<ProcessBlock> * realtime_process_block,std::unique_ptr<RgbirdResultRequestProcessor> * realtime_result_processor,std::unique_ptr<ProcessBlock> * depth_process_block,std::unique_ptr<ResultProcessor> * depth_result_processor)508 status_t RgbirdCaptureSession::SetupRealtimeProcessChain(
509     const StreamConfiguration& stream_config,
510     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
511     std::unique_ptr<ProcessBlock>* realtime_process_block,
512     std::unique_ptr<RgbirdResultRequestProcessor>* realtime_result_processor,
513     std::unique_ptr<ProcessBlock>* depth_process_block,
514     std::unique_ptr<ResultProcessor>* depth_result_processor) {
515   ATRACE_CALL();
516   if (realtime_process_block == nullptr ||
517       realtime_result_processor == nullptr) {
518     ALOGE("%s: realtime_process_block(%p) or realtime_result_processor(%p) or ",
519           __FUNCTION__, realtime_process_block, realtime_result_processor);
520     return BAD_VALUE;
521   }
522 
523   auto rt_process_block = MultiCameraRtProcessBlock::Create(device_session_hwl_);
524   if (rt_process_block == nullptr) {
525     ALOGE("%s: Creating RealtimeProcessBlock failed.", __FUNCTION__);
526     return UNKNOWN_ERROR;
527   }
528 
529   // TODO(b/128632740): Create and connect depth process block.
530   rt_request_processor_ = RgbirdRtRequestProcessor::Create(
531       device_session_hwl_, is_hdrplus_supported_);
532   if (rt_request_processor_ == nullptr) {
533     ALOGE("%s: Creating RealtimeZslsRequestProcessor failed.", __FUNCTION__);
534     return UNKNOWN_ERROR;
535   }
536 
537   StreamConfiguration process_block_stream_config;
538   status_t res =
539       ConfigureStreams(stream_config, rt_request_processor_.get(),
540                        rt_process_block.get(), &process_block_stream_config);
541   if (res != OK) {
542     ALOGE("%s: Configuring stream failed: %s(%d)", __FUNCTION__, strerror(-res),
543           res);
544     return res;
545   }
546 
547   if (is_hdrplus_supported_) {
548     res = ConfigureHdrplusRawStreamId(process_block_stream_config);
549     if (res != OK) {
550       ALOGE("%s: ConfigureHdrplusRawStreamId failed: %s(%d)", __FUNCTION__,
551             strerror(-res), res);
552       return res;
553     }
554   }
555 
556   if (has_depth_stream_) {
557     res = SetDepthInternalStreamId(process_block_stream_config, stream_config);
558     if (res != OK) {
559       ALOGE("%s: ConfigureDepthOnlyRawStreamId failed: %s(%d)", __FUNCTION__,
560             strerror(-res), res);
561       return res;
562     }
563   }
564 
565   // Create realtime result processor.
566   RgbirdResultRequestProcessor::RgbirdResultRequestProcessorCreateData data = {
567       .rgb_camera_id = rgb_camera_id_,
568       .ir1_camera_id = ir1_camera_id_,
569       .ir2_camera_id = ir2_camera_id_,
570       .rgb_raw_stream_id = rgb_raw_stream_id_,
571       .is_hdrplus_supported = is_hdrplus_supported_,
572       .rgb_internal_yuv_stream_id = rgb_internal_yuv_stream_id_};
573   auto rt_result_processor = RgbirdResultRequestProcessor::Create(data);
574   if (rt_result_processor == nullptr) {
575     ALOGE("%s: Creating RgbirdResultRequestProcessor failed.", __FUNCTION__);
576     return UNKNOWN_ERROR;
577   }
578   rt_result_processor->SetResultCallback(
579       process_capture_result, notify, /*process_batch_capture_result=*/nullptr);
580 
581   if (is_hdrplus_supported_) {
582     res = rt_result_processor->ConfigureStreams(internal_stream_manager_.get(),
583                                                 stream_config,
584                                                 &process_block_stream_config);
585     if (res != OK) {
586       ALOGE("%s: Configuring streams for ResultRequestProcessor failed: %s(%d)",
587             __FUNCTION__, strerror(-res), res);
588       return res;
589     }
590   }
591 
592   res = SetupDepthChainSegment(stream_config, rt_result_processor.get(),
593                                depth_process_block, depth_result_processor,
594                                &process_block_stream_config);
595   if (res != OK) {
596     ALOGE("%s: Failed to setup depth chain segment.", __FUNCTION__);
597     return UNKNOWN_ERROR;
598   }
599 
600   // TODO(b/128632740): Remove force internal flag after depth block is in place
601   //                    and the FLL sync is verified.
602   //                    This should be done after depth process block stream
603   //                    configuration.
604   if (!AreAllStreamsConfigured(stream_config, process_block_stream_config) &&
605       !force_internal_stream_) {
606     // TODO(b/127322570): Handle the case where RT request processor configures
607     // internal streams for depth.
608     ALOGE("%s: Not all streams are configured.", __FUNCTION__);
609     return INVALID_OPERATION;
610   }
611 
612   *realtime_process_block = std::move(rt_process_block);
613   *realtime_result_processor = std::move(rt_result_processor);
614 
615   return OK;
616 }
617 
SetupHdrplusProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::unique_ptr<ProcessBlock> * hdrplus_process_block,std::unique_ptr<ResultProcessor> * hdrplus_result_processor)618 status_t RgbirdCaptureSession::SetupHdrplusProcessChain(
619     const StreamConfiguration& stream_config,
620     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
621     std::unique_ptr<ProcessBlock>* hdrplus_process_block,
622     std::unique_ptr<ResultProcessor>* hdrplus_result_processor) {
623   ATRACE_CALL();
624   if (hdrplus_process_block == nullptr || hdrplus_result_processor == nullptr) {
625     ALOGE(
626         "%s: hdrplus_process_block(%p) or hdrplus_result_processor(%p) is "
627         "nullptr",
628         __FUNCTION__, hdrplus_process_block, hdrplus_result_processor);
629     return BAD_VALUE;
630   }
631 
632   // Create hdrplus process block.
633   std::vector<uint32_t> physical_camera_ids =
634       device_session_hwl_->GetPhysicalCameraIds();
635   // TODO: Check the static metadata and determine which one is rgb camera
636   auto process_block =
637       HdrplusProcessBlock::Create(device_session_hwl_, physical_camera_ids[0]);
638   if (process_block == nullptr) {
639     ALOGE("%s: Creating HdrplusProcessBlock failed.", __FUNCTION__);
640     return UNKNOWN_ERROR;
641   }
642 
643   // Create hdrplus request processor.
644   hdrplus_request_processor_ = HdrplusRequestProcessor::Create(
645       device_session_hwl_, rgb_raw_stream_id_, physical_camera_ids[0]);
646   if (hdrplus_request_processor_ == nullptr) {
647     ALOGE("%s: Creating HdrplusRequestProcessor failed.", __FUNCTION__);
648     return UNKNOWN_ERROR;
649   }
650 
651   // Create hdrplus result processor.
652   auto result_processor = HdrplusResultProcessor::Create(
653       internal_stream_manager_.get(), rgb_raw_stream_id_);
654   if (result_processor == nullptr) {
655     ALOGE("%s: Creating HdrplusResultProcessor failed.", __FUNCTION__);
656     return UNKNOWN_ERROR;
657   }
658   result_processor->SetResultCallback(process_capture_result, notify,
659                                       /*process_batch_capture_result=*/nullptr);
660 
661   StreamConfiguration process_block_stream_config;
662   status_t res =
663       ConfigureStreams(stream_config, hdrplus_request_processor_.get(),
664                        process_block.get(), &process_block_stream_config);
665   if (res != OK) {
666     ALOGE("%s: Configuring hdrplus stream failed: %s(%d)", __FUNCTION__,
667           strerror(-res), res);
668     return res;
669   }
670 
671   *hdrplus_process_block = std::move(process_block);
672   *hdrplus_result_processor = std::move(result_processor);
673 
674   return OK;
675 }
676 
CreateProcessChain(const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,std::vector<HalStream> * hal_configured_streams)677 status_t RgbirdCaptureSession::CreateProcessChain(
678     const StreamConfiguration& stream_config,
679     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
680     std::vector<HalStream>* hal_configured_streams) {
681   ATRACE_CALL();
682   // Setup realtime process chain
683   std::unique_ptr<ProcessBlock> realtime_process_block;
684   std::unique_ptr<RgbirdResultRequestProcessor> realtime_result_processor;
685   std::unique_ptr<ProcessBlock> depth_process_block;
686   std::unique_ptr<ResultProcessor> depth_result_processor;
687 
688   status_t res = SetupRealtimeProcessChain(
689       stream_config, process_capture_result, notify, &realtime_process_block,
690       &realtime_result_processor, &depth_process_block, &depth_result_processor);
691   if (res != OK) {
692     ALOGE("%s: SetupRealtimeProcessChain fail: %s(%d)", __FUNCTION__,
693           strerror(-res), res);
694     return res;
695   }
696 
697   // Setup hdrplus process chain
698   std::unique_ptr<ProcessBlock> hdrplus_process_block;
699   std::unique_ptr<ResultProcessor> hdrplus_result_processor;
700   if (is_hdrplus_supported_) {
701     res = SetupHdrplusProcessChain(stream_config, process_capture_result,
702                                    notify, &hdrplus_process_block,
703                                    &hdrplus_result_processor);
704     if (res != OK) {
705       ALOGE("%s: SetupHdrplusProcessChain fail: %s(%d)", __FUNCTION__,
706             strerror(-res), res);
707       return res;
708     }
709   }
710   // Realtime and HDR+ streams are configured
711   // Start to build pipleline
712   res = BuildPipelines(stream_config, realtime_process_block.get(),
713                        depth_process_block.get(), hdrplus_process_block.get(),
714                        hal_configured_streams);
715   if (res != OK) {
716     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
717           res);
718     return res;
719   }
720 
721   // Connecting the depth segment of the realtime process chain.
722   if (NeedDepthProcessBlock()) {
723     depth_result_processor->SetResultCallback(
724         process_capture_result, notify,
725         /*process_batch_capture_result=*/nullptr);
726 
727     res = ConnectProcessChain(realtime_result_processor.get(),
728                               std::move(depth_process_block),
729                               std::move(depth_result_processor));
730     if (res != OK) {
731       ALOGE("%s: Connecting depth segment of realtime chain failed: %s(%d)",
732             __FUNCTION__, strerror(-res), res);
733       return res;
734     }
735   }
736 
737   // Connect realtime process chain
738   res = ConnectProcessChain(rt_request_processor_.get(),
739                             std::move(realtime_process_block),
740                             std::move(realtime_result_processor));
741   if (res != OK) {
742     ALOGE("%s: Connecting process chain failed: %s(%d)", __FUNCTION__,
743           strerror(-res), res);
744     return res;
745   }
746 
747   if (is_hdrplus_supported_) {
748     // Connect HDR+ process chain
749     res = ConnectProcessChain(hdrplus_request_processor_.get(),
750                               std::move(hdrplus_process_block),
751                               std::move(hdrplus_result_processor));
752     if (res != OK) {
753       ALOGE("%s: Connecting HDR+ process chain failed: %s(%d)", __FUNCTION__,
754             strerror(-res), res);
755       return res;
756     }
757   }
758   return OK;
759 }
760 
ConnectProcessChain(RequestProcessor * request_processor,std::unique_ptr<ProcessBlock> process_block,std::unique_ptr<ResultProcessor> result_processor)761 status_t RgbirdCaptureSession::ConnectProcessChain(
762     RequestProcessor* request_processor,
763     std::unique_ptr<ProcessBlock> process_block,
764     std::unique_ptr<ResultProcessor> result_processor) {
765   ATRACE_CALL();
766   if (request_processor == nullptr) {
767     ALOGE("%s: request_processor is nullptr", __FUNCTION__);
768     return BAD_VALUE;
769   }
770 
771   status_t res = process_block->SetResultProcessor(std::move(result_processor));
772   if (res != OK) {
773     ALOGE("%s: Setting result process in process block failed.", __FUNCTION__);
774     return res;
775   }
776 
777   res = request_processor->SetProcessBlock(std::move(process_block));
778   if (res != OK) {
779     ALOGE("%s: Setting process block for request processor failed: %s(%d)",
780           __FUNCTION__, strerror(-res), res);
781     return res;
782   }
783 
784   return OK;
785 }
786 
ConfigureHdrplusUsageAndBuffers(std::vector<HalStream> * hal_configured_streams,std::vector<HalStream> * hdrplus_hal_configured_streams)787 status_t RgbirdCaptureSession::ConfigureHdrplusUsageAndBuffers(
788     std::vector<HalStream>* hal_configured_streams,
789     std::vector<HalStream>* hdrplus_hal_configured_streams) {
790   ATRACE_CALL();
791   if (hal_configured_streams == nullptr ||
792       hdrplus_hal_configured_streams == nullptr) {
793     ALOGE(
794         "%s: hal_configured_streams (%p) or hdrplus_hal_configured_streams "
795         "(%p) is nullptr",
796         __FUNCTION__, hal_configured_streams, hdrplus_hal_configured_streams);
797     return BAD_VALUE;
798   }
799   // Combine realtime and HDR+ hal stream.
800   // Only usage of internal raw stream is different, so combine usage directly
801   uint64_t consumer_usage = 0;
802   for (uint32_t i = 0; i < (*hdrplus_hal_configured_streams).size(); i++) {
803     if (hdrplus_hal_configured_streams->at(i).override_format ==
804             kHdrplusRawFormat &&
805         hdrplus_hal_configured_streams->at(i).id == rgb_raw_stream_id_) {
806       consumer_usage = hdrplus_hal_configured_streams->at(i).consumer_usage;
807       break;
808     }
809   }
810 
811   for (uint32_t i = 0; i < hal_configured_streams->size(); i++) {
812     if (hal_configured_streams->at(i).override_format == kHdrplusRawFormat &&
813         hal_configured_streams->at(i).id == rgb_raw_stream_id_) {
814       hal_configured_streams->at(i).consumer_usage = consumer_usage;
815       // Allocate internal raw stream buffers
816       if (hal_configured_streams->at(i).max_buffers < kRgbMinRawBufferCount) {
817         hal_configured_streams->at(i).max_buffers = kRgbMinRawBufferCount;
818       }
819 
820       uint32_t additional_num_buffers =
821           (hal_configured_streams->at(i).max_buffers >= kRgbRawBufferCount)
822               ? 0
823               : (kRgbRawBufferCount - hal_configured_streams->at(i).max_buffers);
824       status_t res = internal_stream_manager_->AllocateBuffers(
825           hal_configured_streams->at(i), additional_num_buffers);
826       if (res != OK) {
827         ALOGE("%s: AllocateBuffers failed.", __FUNCTION__);
828         return UNKNOWN_ERROR;
829       }
830       break;
831     }
832   }
833 
834   return OK;
835 }
836 
BuildPipelines(const StreamConfiguration & stream_config,ProcessBlock * realtime_process_block,ProcessBlock * depth_process_block,ProcessBlock * hdrplus_process_block,std::vector<HalStream> * hal_configured_streams)837 status_t RgbirdCaptureSession::BuildPipelines(
838     const StreamConfiguration& stream_config,
839     ProcessBlock* realtime_process_block, ProcessBlock* depth_process_block,
840     ProcessBlock* hdrplus_process_block,
841     std::vector<HalStream>* hal_configured_streams) {
842   ATRACE_CALL();
843   if (realtime_process_block == nullptr) {
844     ALOGE("%s: realtime_process_block (%p) is nullptr", __FUNCTION__,
845           realtime_process_block);
846     return BAD_VALUE;
847   }
848 
849   if (depth_process_block == nullptr && has_depth_stream_) {
850     ALOGE("%s: depth_process_block (%p) is nullptr", __FUNCTION__,
851           depth_process_block);
852     return BAD_VALUE;
853   }
854 
855   if (hal_configured_streams == nullptr) {
856     ALOGE("%s: hal_configured_streams (%p) is nullptr", __FUNCTION__,
857           hal_configured_streams);
858     return BAD_VALUE;
859   }
860 
861   if (is_hdrplus_supported_ && hdrplus_process_block == nullptr) {
862     ALOGE("%s: hdrplus_process_block is nullptr", __FUNCTION__);
863     return BAD_VALUE;
864   }
865 
866   status_t res = device_session_hwl_->BuildPipelines();
867   if (res != OK) {
868     ALOGE("%s: Building pipelines failed: %s(%d)", __FUNCTION__, strerror(-res),
869           res);
870     return res;
871   }
872 
873   res = realtime_process_block->GetConfiguredHalStreams(hal_configured_streams);
874   if (res != OK) {
875     ALOGE("%s: Getting HAL streams failed: %s(%d)", __FUNCTION__,
876           strerror(-res), res);
877     return res;
878   }
879 
880   res = AllocateInternalBuffers(stream_config, hal_configured_streams,
881                                 hdrplus_process_block);
882 
883   // Need to update hal_configured_streams if there is a depth stream
884   std::vector<HalStream> depth_streams;
885   if (has_depth_stream_) {
886     res = depth_process_block->GetConfiguredHalStreams(&depth_streams);
887     if (res != OK) {
888       ALOGE("%s: Failed to get configured hal streams from DepthProcessBlock",
889             __FUNCTION__);
890       return UNKNOWN_ERROR;
891     }
892 
893     // Depth Process Block can only configure one depth stream so far
894     if (depth_streams.size() != 1) {
895       ALOGE("%s: DepthProcessBlock configured more than one stream.",
896             __FUNCTION__);
897       return UNKNOWN_ERROR;
898     }
899 
900     hal_configured_streams->push_back(depth_streams[0]);
901   }
902 
903   if (res != OK) {
904     ALOGE("%s: Allocating buffer for internal stream managers failed: %s(%d)",
905           __FUNCTION__, strerror(-res), res);
906     return res;
907   }
908 
909   hal_utils::DumpHalConfiguredStreams(*hal_configured_streams,
910                                       "hal_configured_streams BEFORE purge");
911 
912   // TODO(b/128633958): cover the streams Depth PB processes
913   res = PurgeHalConfiguredStream(stream_config, hal_configured_streams);
914   if (res != OK) {
915     ALOGE("%s: Removing internal streams from configured stream failed: %s(%d)",
916           __FUNCTION__, strerror(-res), res);
917     return res;
918   }
919 
920   hal_utils::DumpHalConfiguredStreams(*hal_configured_streams,
921                                       "hal_configured_streams AFTER purge");
922 
923   return OK;
924 }
925 
InitializeCameraIds(CameraDeviceSessionHwl * device_session_hwl)926 status_t RgbirdCaptureSession::InitializeCameraIds(
927     CameraDeviceSessionHwl* device_session_hwl) {
928   ATRACE_CALL();
929   if (device_session_hwl == nullptr) {
930     ALOGE("%s: Device session hwl is null.", __FUNCTION__);
931     return BAD_VALUE;
932   }
933 
934   std::vector<uint32_t> physical_camera_ids =
935       device_session_hwl->GetPhysicalCameraIds();
936   if (physical_camera_ids.size() != 3) {
937     ALOGE("%s: Failed to initialize camera ids. Only support 3 cameras",
938           __FUNCTION__);
939     return UNKNOWN_ERROR;
940   }
941 
942   // TODO(b/127322570): Figure out physical camera IDs from static metadata.
943   rgb_camera_id_ = physical_camera_ids[0];
944   ir1_camera_id_ = physical_camera_ids[1];
945   ir2_camera_id_ = physical_camera_ids[2];
946   return OK;
947 }
948 
Initialize(CameraDeviceSessionHwl * device_session_hwl,const StreamConfiguration & stream_config,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,HwlRequestBuffersFunc request_stream_buffers,std::vector<HalStream> * hal_configured_streams)949 status_t RgbirdCaptureSession::Initialize(
950     CameraDeviceSessionHwl* device_session_hwl,
951     const StreamConfiguration& stream_config,
952     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
953     HwlRequestBuffersFunc request_stream_buffers,
954     std::vector<HalStream>* hal_configured_streams) {
955   ATRACE_CALL();
956   if (!IsStreamConfigurationSupported(device_session_hwl, stream_config)) {
957     ALOGE("%s: stream configuration is not supported.", __FUNCTION__);
958     return BAD_VALUE;
959   }
960 
961   // TODO(b/128633958): remove this after FLL syncing is verified
962   force_internal_stream_ =
963       property_get_bool("persist.vendor.camera.rgbird.forceinternal", false);
964   if (force_internal_stream_) {
965     ALOGI("%s: Force creating internal streams for IR pipelines", __FUNCTION__);
966   }
967 
968   device_session_hwl_ = device_session_hwl;
969   internal_stream_manager_ = InternalStreamManager::Create();
970   if (internal_stream_manager_ == nullptr) {
971     ALOGE("%s: Cannot create internal stream manager.", __FUNCTION__);
972     return UNKNOWN_ERROR;
973   }
974 
975   std::unique_ptr<HalCameraMetadata> characteristics;
976   status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
977   if (res != OK) {
978     ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
979     return BAD_VALUE;
980   }
981 
982   is_hdrplus_supported_ = hal_utils::IsStreamHdrplusCompatible(
983       stream_config, characteristics.get());
984 
985   if (is_hdrplus_supported_) {
986     for (auto stream : stream_config.streams) {
987       if (utils::IsPreviewStream(stream)) {
988         hal_preview_stream_id_ = stream.id;
989         break;
990       }
991     }
992   }
993 
994   // Create result dispatcher
995   result_dispatcher_ =
996       ResultDispatcher::Create(kPartialResult, process_capture_result,
997                                /*process_batch_capture_result=*/nullptr, notify,
998                                stream_config, "RgbirdDispatcher");
999   if (result_dispatcher_ == nullptr) {
1000     ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
1001     return UNKNOWN_ERROR;
1002   }
1003 
1004   // Reroute callback functions
1005   device_session_notify_ = notify;
1006   process_capture_result_ =
1007       ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
1008         ProcessCaptureResult(std::move(result));
1009       });
1010   notify_ = NotifyFunc(
1011       [this](const NotifyMessage& message) { NotifyHalMessage(message); });
1012   request_stream_buffers_ = request_stream_buffers;
1013 
1014   // Initialize physical camera ids
1015   res = InitializeCameraIds(device_session_hwl_);
1016   if (res != OK) {
1017     ALOGE("%s: Initializing camera ids failed: %s(%d)", __FUNCTION__,
1018           strerror(-res), res);
1019     return res;
1020   }
1021 
1022   for (auto& stream : stream_config.streams) {
1023     if (utils::IsDepthStream(stream)) {
1024       ALOGI("%s: Depth stream exists in the stream config.", __FUNCTION__);
1025       has_depth_stream_ = true;
1026     }
1027   }
1028 
1029   // Finally create the process chains
1030   res = CreateProcessChain(stream_config, process_capture_result_, notify_,
1031                            hal_configured_streams);
1032   if (res != OK) {
1033     ALOGE("%s: Creating the process  chain failed: %s(%d)", __FUNCTION__,
1034           strerror(-res), res);
1035     return res;
1036   }
1037 
1038   return OK;
1039 }
1040 
ProcessRequest(const CaptureRequest & request)1041 status_t RgbirdCaptureSession::ProcessRequest(const CaptureRequest& request) {
1042   ATRACE_CALL();
1043   bool is_hdrplus_request = false;
1044   if (is_hdrplus_supported_) {
1045     is_hdrplus_request =
1046         hal_utils::IsRequestHdrplusCompatible(request, hal_preview_stream_id_);
1047     // TODO: Check if request is HDR+ request when contains a depth buffer
1048   }
1049 
1050   status_t res = result_dispatcher_->AddPendingRequest(request);
1051   if (res != OK) {
1052     ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
1053           request.frame_number);
1054     return BAD_VALUE;
1055   }
1056 
1057   if (is_hdrplus_request) {
1058     ALOGI("%s: hdrplus snapshot (%d), output stream size:%zu", __FUNCTION__,
1059           request.frame_number, request.output_buffers.size());
1060     res = hdrplus_request_processor_->ProcessRequest(request);
1061     if (res != OK) {
1062       ALOGI("%s: hdrplus snapshot frame(%d) request to realtime process",
1063             __FUNCTION__, request.frame_number);
1064       res = rt_request_processor_->ProcessRequest(request);
1065     }
1066   } else {
1067     res = rt_request_processor_->ProcessRequest(request);
1068   }
1069 
1070   if (res != OK) {
1071     ALOGE("%s: ProcessRequest (%d) fail and remove pending request",
1072           __FUNCTION__, request.frame_number);
1073     result_dispatcher_->RemovePendingRequest(request.frame_number);
1074   }
1075   return res;
1076 }
1077 
Flush()1078 status_t RgbirdCaptureSession::Flush() {
1079   ATRACE_CALL();
1080   return rt_request_processor_->Flush();
1081 }
1082 
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)1083 void RgbirdCaptureSession::ProcessCaptureResult(
1084     std::unique_ptr<CaptureResult> result) {
1085   ATRACE_CALL();
1086   std::lock_guard<std::mutex> lock(callback_lock_);
1087   status_t res = result_dispatcher_->AddResult(std::move(result));
1088   if (res != OK) {
1089     ALOGE("%s: fail to AddResult", __FUNCTION__);
1090     return;
1091   }
1092 }
1093 
NotifyHalMessage(const NotifyMessage & message)1094 void RgbirdCaptureSession::NotifyHalMessage(const NotifyMessage& message) {
1095   ATRACE_CALL();
1096   std::lock_guard<std::mutex> lock(callback_lock_);
1097   if (device_session_notify_ == nullptr) {
1098     ALOGE("%s: device_session_notify_ is nullptr. Dropping a message.",
1099           __FUNCTION__);
1100     return;
1101   }
1102 
1103   if (message.type == MessageType::kShutter) {
1104     status_t res = result_dispatcher_->AddShutter(
1105         message.message.shutter.frame_number,
1106         message.message.shutter.timestamp_ns,
1107         message.message.shutter.readout_timestamp_ns);
1108     if (res != OK) {
1109       ALOGE("%s: frame(%d) fail to AddShutter", __FUNCTION__,
1110             message.message.shutter.frame_number);
1111       return;
1112     }
1113   } else if (message.type == MessageType::kError) {
1114     // drop the error notifications for the internal streams
1115     auto error_stream_id = message.message.error.error_stream_id;
1116     if (has_depth_stream_ &&
1117         message.message.error.error_code == ErrorCode::kErrorBuffer &&
1118         error_stream_id != kInvalidStreamId &&
1119         (error_stream_id == rgb_internal_yuv_stream_id_ ||
1120          error_stream_id == ir1_internal_raw_stream_id_ ||
1121          error_stream_id == ir2_internal_raw_stream_id_)) {
1122       return;
1123     }
1124 
1125     status_t res = result_dispatcher_->AddError(message.message.error);
1126     if (res != OK) {
1127       ALOGE("%s: AddError for frame %u failed: %s (%d).", __FUNCTION__,
1128             message.message.error.frame_number, strerror(-res), res);
1129       return;
1130     }
1131   } else {
1132     ALOGW("%s: Unsupported message type: %u", __FUNCTION__, message.type);
1133     device_session_notify_(message);
1134   }
1135 }
1136 }  // namespace google_camera_hal
1137 }  // namespace android
1138