• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cstdint>
19 #define LOG_TAG "GCH_Utils"
20 
21 #include <cutils/properties.h>
22 #include <dirent.h>
23 #include <dlfcn.h>
24 #include <hardware/gralloc.h>
25 #include <sys/stat.h>
26 
27 #include <array>
28 
29 #include "utils.h"
30 #include "vendor_tag_defs.h"
31 
32 namespace android {
33 namespace google_camera_hal {
34 namespace utils {
35 
36 namespace {
37 
38 using FpsRange = std::pair<int32_t, int32_t>;
39 
IsAcceptableThrottledFpsChange(const FpsRange & old_fps,const FpsRange & new_fps)40 bool IsAcceptableThrottledFpsChange(const FpsRange& old_fps,
41                                     const FpsRange& new_fps) {
42   // We allow smooth transitions between [30,30] to [60,60] and [24,24] and [24,30].
43   constexpr std::array<std::pair<FpsRange, FpsRange>, 3> kAcceptableTransitions = {
44       std::make_pair<FpsRange, FpsRange>({30, 30}, {60, 60}),
45       std::make_pair<FpsRange, FpsRange>({24, 24}, {24, 30}),
46       std::make_pair<FpsRange, FpsRange>({24, 24}, {30, 30}),
47   };
48 
49   for (const std::pair<FpsRange, FpsRange>& range : kAcceptableTransitions) {
50     // We don't care about the direction of the transition.
51     if ((old_fps == range.first && new_fps == range.second) ||
52         (new_fps == range.first && old_fps == range.second)) {
53       return true;
54     }
55   }
56 
57   return false;
58 }
59 }  // namespace
60 
61 constexpr char kRealtimeThreadSetProp[] =
62     "persist.vendor.camera.realtimethread";
63 
64 constexpr uint32_t kMinSupportedSoftwareDenoiseDimension = 1000;
65 
IsDepthStream(const Stream & stream)66 bool IsDepthStream(const Stream& stream) {
67   if (stream.stream_type == StreamType::kOutput &&
68       stream.data_space == HAL_DATASPACE_DEPTH &&
69       stream.format == HAL_PIXEL_FORMAT_Y16) {
70     return true;
71   }
72 
73   return false;
74 }
75 
IsPreviewStream(const Stream & stream)76 bool IsPreviewStream(const Stream& stream) {
77   if (stream.stream_type == StreamType::kOutput &&
78       stream.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
79       ((stream.usage & GRALLOC_USAGE_HW_COMPOSER) == GRALLOC_USAGE_HW_COMPOSER ||
80        (stream.usage & GRALLOC_USAGE_HW_TEXTURE) == GRALLOC_USAGE_HW_TEXTURE)) {
81     return true;
82   }
83 
84   return false;
85 }
86 
IsJPEGSnapshotStream(const Stream & stream)87 bool IsJPEGSnapshotStream(const Stream& stream) {
88   if (stream.stream_type == StreamType::kOutput &&
89       stream.format == HAL_PIXEL_FORMAT_BLOB &&
90       (stream.data_space == HAL_DATASPACE_JFIF ||
91        stream.data_space == HAL_DATASPACE_V0_JFIF)) {
92     return true;
93   }
94 
95   return false;
96 }
97 
IsOutputZslStream(const Stream & stream)98 bool IsOutputZslStream(const Stream& stream) {
99   if (stream.stream_type == StreamType::kOutput &&
100       (stream.usage & GRALLOC_USAGE_HW_CAMERA_ZSL) ==
101           GRALLOC_USAGE_HW_CAMERA_ZSL) {
102     return true;
103   }
104 
105   return false;
106 }
107 
IsVideoStream(const Stream & stream)108 bool IsVideoStream(const Stream& stream) {
109   if (stream.stream_type == StreamType::kOutput &&
110       (stream.usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0) {
111     return true;
112   }
113 
114   return false;
115 }
116 
IsRawStream(const Stream & stream)117 bool IsRawStream(const Stream& stream) {
118   if (stream.stream_type == StreamType::kOutput &&
119       (stream.format == HAL_PIXEL_FORMAT_RAW10 ||
120        stream.format == HAL_PIXEL_FORMAT_RAW16 ||
121        stream.format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
122     return true;
123   }
124 
125   return false;
126 }
127 
IsInputRawStream(const Stream & stream)128 bool IsInputRawStream(const Stream& stream) {
129   if (stream.stream_type == StreamType::kInput &&
130       (stream.format == HAL_PIXEL_FORMAT_RAW10 ||
131        stream.format == HAL_PIXEL_FORMAT_RAW16 ||
132        stream.format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
133     return true;
134   }
135 
136   return false;
137 }
138 
IsArbitraryDataSpaceRawStream(const Stream & stream)139 bool IsArbitraryDataSpaceRawStream(const Stream& stream) {
140   return IsRawStream(stream) && (stream.data_space == HAL_DATASPACE_ARBITRARY);
141 }
142 
IsYUVSnapshotStream(const Stream & stream)143 bool IsYUVSnapshotStream(const Stream& stream) {
144   if (stream.stream_type == StreamType::kOutput &&
145       stream.format == HAL_PIXEL_FORMAT_YCbCr_420_888 &&
146       !IsVideoStream(stream) && !IsPreviewStream(stream)) {
147     return true;
148   }
149 
150   return false;
151 }
152 
IsSoftwareDenoiseEligibleSnapshotStream(const Stream & stream)153 bool IsSoftwareDenoiseEligibleSnapshotStream(const Stream& stream) {
154   if (utils::IsYUVSnapshotStream(stream) ||
155       utils::IsJPEGSnapshotStream(stream)) {
156     return stream.width >= kMinSupportedSoftwareDenoiseDimension ||
157            stream.height >= kMinSupportedSoftwareDenoiseDimension;
158   }
159   return false;
160 }
161 
GetSensorPhysicalSize(const HalCameraMetadata * characteristics,float * width,float * height)162 status_t GetSensorPhysicalSize(const HalCameraMetadata* characteristics,
163                                float* width, float* height) {
164   if (characteristics == nullptr || width == nullptr || height == nullptr) {
165     ALOGE("%s: characteristics or width/height is nullptr", __FUNCTION__);
166     return BAD_VALUE;
167   }
168 
169   camera_metadata_ro_entry entry;
170   status_t res = characteristics->Get(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, &entry);
171   if (res != OK || entry.count != 2) {
172     ALOGE(
173         "%s: Getting ANDROID_SENSOR_INFO_PHYSICAL_SIZE failed: %s(%d) count: "
174         "%zu",
175         __FUNCTION__, strerror(-res), res, entry.count);
176     return res;
177   }
178 
179   *width = entry.data.f[0];
180   *height = entry.data.f[1];
181   return OK;
182 }
183 
HasCapability(const HalCameraMetadata * metadata,uint8_t capability)184 bool HasCapability(const HalCameraMetadata* metadata, uint8_t capability) {
185   if (metadata == nullptr) {
186     return false;
187   }
188 
189   camera_metadata_ro_entry_t entry;
190   auto ret = metadata->Get(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
191   if (ret != OK) {
192     return false;
193   }
194   for (size_t i = 0; i < entry.count; i++) {
195     if (entry.data.u8[i] == capability) {
196       return true;
197     }
198   }
199   return false;
200 }
201 
GetSensorActiveArraySize(const HalCameraMetadata * characteristics,Rect * active_array,bool maximum_resolution)202 status_t GetSensorActiveArraySize(const HalCameraMetadata* characteristics,
203                                   Rect* active_array, bool maximum_resolution) {
204   if (characteristics == nullptr || active_array == nullptr) {
205     ALOGE("%s: characteristics or active_array is nullptr", __FUNCTION__);
206     return BAD_VALUE;
207   }
208   uint32_t active_array_tag =
209       maximum_resolution
210           ? ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
211           : ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE;
212   camera_metadata_ro_entry entry;
213   status_t res = characteristics->Get(active_array_tag, &entry);
214   if (res != OK || entry.count != 4) {
215     return res;
216   }
217 
218   active_array->left = entry.data.i32[0];
219   active_array->top = entry.data.i32[1];
220   active_array->right = entry.data.i32[0] + entry.data.i32[2] - 1;
221   active_array->bottom = entry.data.i32[1] + entry.data.i32[3] - 1;
222 
223   return OK;
224 }
225 
GetZoomRatioRange(const HalCameraMetadata * characteristics,ZoomRatioRange * zoom_ratio_range)226 status_t GetZoomRatioRange(const HalCameraMetadata* characteristics,
227                            ZoomRatioRange* zoom_ratio_range) {
228   if (characteristics == nullptr || zoom_ratio_range == nullptr) {
229     ALOGE("%s: characteristics or zoom_ratio_range is nullptr", __FUNCTION__);
230     return BAD_VALUE;
231   }
232 
233   camera_metadata_ro_entry entry;
234   status_t res = characteristics->Get(ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
235   if (res != OK || entry.count != 2) {
236     ALOGE(
237         "%s: Getting ANDROID_CONTROL_ZOOM_RATIO_RANGE failed: %s(%d) "
238         "count: %zu",
239         __FUNCTION__, strerror(-res), res, entry.count);
240     return res;
241   }
242 
243   zoom_ratio_range->min = entry.data.f[0];
244   zoom_ratio_range->max = entry.data.f[1];
245 
246   return OK;
247 }
248 
GetSensorPixelArraySize(const HalCameraMetadata * characteristics,Dimension * pixel_array)249 status_t GetSensorPixelArraySize(const HalCameraMetadata* characteristics,
250                                  Dimension* pixel_array) {
251   if (characteristics == nullptr || pixel_array == nullptr) {
252     ALOGE("%s: characteristics or pixel_array is nullptr", __FUNCTION__);
253     return BAD_VALUE;
254   }
255 
256   camera_metadata_ro_entry entry;
257   status_t res =
258       characteristics->Get(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, &entry);
259   if (res != OK || entry.count != 2) {
260     ALOGE(
261         "%s: Getting ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE failed: %s(%d) "
262         "count: %zu",
263         __FUNCTION__, strerror(-res), res, entry.count);
264     return res;
265   }
266 
267   pixel_array->width = entry.data.i32[0];
268   pixel_array->height = entry.data.i32[1];
269 
270   return OK;
271 }
272 
GetFocalLength(const HalCameraMetadata * characteristics,float * focal_length)273 status_t GetFocalLength(const HalCameraMetadata* characteristics,
274                         float* focal_length) {
275   if (characteristics == nullptr || focal_length == nullptr) {
276     ALOGE("%s: characteristics or focal_length is nullptr", __FUNCTION__);
277     return BAD_VALUE;
278   }
279 
280   camera_metadata_ro_entry entry;
281   status_t res =
282       characteristics->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry);
283   if (res != OK || entry.count != 1) {
284     ALOGE(
285         "%s: Getting ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS failed: %s(%d) "
286         "count: %zu",
287         __FUNCTION__, strerror(-res), res, entry.count);
288     return res;
289   }
290 
291   *focal_length = entry.data.f[0];
292 
293   return OK;
294 }
295 
IsLiveSnapshotConfigured(const StreamConfiguration & stream_config)296 bool IsLiveSnapshotConfigured(const StreamConfiguration& stream_config) {
297   bool has_video_stream = false;
298   bool has_jpeg_stream = false;
299   for (auto stream : stream_config.streams) {
300     if (utils::IsVideoStream(stream)) {
301       has_video_stream = true;
302     } else if (utils::IsJPEGSnapshotStream(stream)) {
303       has_jpeg_stream = true;
304     }
305   }
306 
307   return (has_video_stream & has_jpeg_stream);
308 }
309 
IsHighSpeedModeFpsCompatible(StreamConfigurationMode mode,const HalCameraMetadata * old_session,const HalCameraMetadata * new_session)310 bool IsHighSpeedModeFpsCompatible(StreamConfigurationMode mode,
311                                   const HalCameraMetadata* old_session,
312                                   const HalCameraMetadata* new_session) {
313   if (mode != StreamConfigurationMode::kConstrainedHighSpeed) {
314     return false;
315   }
316 
317   camera_metadata_ro_entry_t ae_target_fps_entry;
318   int32_t old_max_fps = 0;
319   int32_t new_max_fps = 0;
320 
321   if (old_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
322                        &ae_target_fps_entry) == OK) {
323     old_max_fps = ae_target_fps_entry.data.i32[1];
324   }
325   if (new_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
326                        &ae_target_fps_entry) == OK) {
327     new_max_fps = ae_target_fps_entry.data.i32[1];
328   }
329 
330   ALOGI("%s: HFR: old max fps: %d, new max fps: %d", __FUNCTION__, old_max_fps,
331         new_max_fps);
332 
333   if (new_max_fps == old_max_fps) {
334     return true;
335   }
336 
337   return false;
338 }
339 
IsSessionParameterCompatible(const HalCameraMetadata * old_session,const HalCameraMetadata * new_session)340 bool IsSessionParameterCompatible(const HalCameraMetadata* old_session,
341                                   const HalCameraMetadata* new_session) {
342   auto old_session_count = old_session->GetEntryCount();
343   auto new_session_count = new_session->GetEntryCount();
344   if (old_session_count == 0 || new_session_count == 0) {
345     ALOGI("No session paramerter, old:%zu, new:%zu", old_session_count,
346           new_session_count);
347     if (new_session_count != 0) {
348       camera_metadata_ro_entry_t entry;
349       if (new_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry) == OK) {
350         int32_t max_fps = entry.data.i32[1];
351         if (max_fps > 30) {
352           ALOGI("new session paramerter max fps:%d", max_fps);
353           return false;
354         }
355       }
356     }
357     return true;
358   }
359 
360   if (old_session_count != new_session_count) {
361     ALOGI(
362         "Entry count has changed from %zu "
363         "to %zu",
364         old_session_count, new_session_count);
365     return false;
366   }
367 
368   for (size_t entry_index = 0; entry_index < new_session_count; entry_index++) {
369     camera_metadata_ro_entry_t new_entry;
370     // Get the medata from new session first
371     if (new_session->GetByIndex(&new_entry, entry_index) != OK) {
372       ALOGW("Unable to get new session entry for index %zu", entry_index);
373       return false;
374     }
375 
376     // Get the same tag from old session
377     camera_metadata_ro_entry_t old_entry;
378     if (old_session->Get(new_entry.tag, &old_entry) != OK) {
379       ALOGW("Unable to get old session tag 0x%x", new_entry.tag);
380       return false;
381     }
382 
383     if (new_entry.count != old_entry.count) {
384       ALOGI(
385           "New entry count %zu doesn't "
386           "match old entry count %zu",
387           new_entry.count, old_entry.count);
388       return false;
389     }
390 
391     if (new_entry.tag == ANDROID_CONTROL_AE_TARGET_FPS_RANGE) {
392       // Stream reconfiguration is not needed in case the upper
393       // framerate range remains unchanged. Any other modification
394       // to the session parameters must trigger new stream
395       // configuration.
396       int32_t old_min_fps = old_entry.data.i32[0];
397       int32_t old_max_fps = old_entry.data.i32[1];
398       int32_t new_min_fps = new_entry.data.i32[0];
399       int32_t new_max_fps = new_entry.data.i32[1];
400       // Do not reconfigure session if max FPS hasn't changed or in
401       // the special case that AE FPS is throttling [60, 60] to [30, 30] or
402       // restored from [30, 30] to [60, 60] from GCA side when session parameter
403       // kVideo60to30FPSThermalThrottle is enabled.
404       // Added kVideoFpsThrottle more generic transitions such
405       // as between [24,24] and [24,30]. kVideoFpsThrottle should be used
406       // over kVideo60to30FPSThermalThrottle going forth. They are functionally
407       // the same, but kVideoFpsThrottle is more generically named.
408       uint8_t video_60_to_30fps_thermal_throttle = 0;
409       camera_metadata_ro_entry_t video_60_to_30fps_throttle_entry;
410       if (new_session->Get(kVideo60to30FPSThermalThrottle,
411                            &video_60_to_30fps_throttle_entry) == OK) {
412         video_60_to_30fps_thermal_throttle =
413             video_60_to_30fps_throttle_entry.data.u8[0];
414       }
415 
416       uint8_t video_fps_throttle = 0;
417       camera_metadata_ro_entry_t video_fps_throttle_entry;
418       if (new_session->Get(kVideoFpsThrottle, &video_fps_throttle_entry) == OK) {
419         video_fps_throttle = video_fps_throttle_entry.data.u8[0];
420       }
421 
422       bool ignore_fps_range_diff = false;
423       if (video_60_to_30fps_thermal_throttle || video_fps_throttle) {
424         ignore_fps_range_diff = IsAcceptableThrottledFpsChange(
425             /*old_fps=*/{old_min_fps, old_max_fps},
426             /*new_fps=*/{new_min_fps, new_max_fps});
427       }
428 
429       if (old_max_fps == new_max_fps || ignore_fps_range_diff) {
430         ALOGI(
431             "%s: Ignore fps (%d, %d) to (%d, %d). "
432             "video_60_to_30fps_thermal_throttle: %u",
433             __FUNCTION__, old_min_fps, old_max_fps, new_min_fps, new_max_fps,
434             video_60_to_30fps_thermal_throttle);
435         continue;
436       }
437 
438       return false;
439     } else {
440       // Same type and count, compare values
441       size_t type_size = camera_metadata_type_size[old_entry.type];
442       size_t entry_size = type_size * old_entry.count;
443       int32_t cmp = memcmp(new_entry.data.u8, old_entry.data.u8, entry_size);
444       if (cmp != 0) {
445         ALOGI("Session parameter value has changed");
446         return false;
447       }
448     }
449   }
450 
451   return true;
452 }
453 
ConvertZoomRatio(const float zoom_ratio,const Dimension & active_array_dimension,int32_t * left,int32_t * top,int32_t * width,int32_t * height)454 void ConvertZoomRatio(const float zoom_ratio,
455                       const Dimension& active_array_dimension, int32_t* left,
456                       int32_t* top, int32_t* width, int32_t* height) {
457   if (left == nullptr || top == nullptr || width == nullptr ||
458       height == nullptr) {
459     ALOGE("%s, invalid params", __FUNCTION__);
460     return;
461   }
462 
463   assert(zoom_ratio != 0);
464   *left = std::round(*left / zoom_ratio + 0.5f * active_array_dimension.width *
465                                               (1.0f - 1.0f / zoom_ratio));
466   *top = std::round(*top / zoom_ratio + 0.5f * active_array_dimension.height *
467                                             (1.0f - 1.0f / zoom_ratio));
468   *width = std::round(*width / zoom_ratio);
469   *height = std::round(*height / zoom_ratio);
470 
471   if (zoom_ratio >= 1.0f) {
472     utils::ClampBoundary(active_array_dimension, left, top, width, height);
473   }
474 }
475 
SupportRealtimeThread()476 bool SupportRealtimeThread() {
477   static bool support_real_time = false;
478   static bool first_time = false;
479   if (first_time == false) {
480     first_time = true;
481     support_real_time = property_get_bool(kRealtimeThreadSetProp, false);
482   }
483 
484   return support_real_time;
485 }
486 
SetRealtimeThread(pthread_t thread)487 status_t SetRealtimeThread(pthread_t thread) {
488   struct sched_param param = {
489       .sched_priority = 1,
490   };
491   int32_t res =
492       pthread_setschedparam(thread, SCHED_FIFO | SCHED_RESET_ON_FORK, &param);
493   if (res != 0) {
494     ALOGE("%s: Couldn't set SCHED_FIFO", __FUNCTION__);
495     return BAD_VALUE;
496   }
497 
498   return OK;
499 }
500 
UpdateThreadSched(pthread_t thread,int32_t policy,struct sched_param * param)501 status_t UpdateThreadSched(pthread_t thread, int32_t policy,
502                            struct sched_param* param) {
503   if (param == nullptr) {
504     ALOGE("%s: sched_param is nullptr", __FUNCTION__);
505     return BAD_VALUE;
506   }
507   int32_t res = pthread_setschedparam(thread, policy, param);
508   if (res != 0) {
509     ALOGE("%s: Couldn't set schedparam", __FUNCTION__);
510     return BAD_VALUE;
511   }
512 
513   return OK;
514 }
515 
516 // Returns an array of regular files under dir_path.
FindLibraryPaths(const char * dir_path)517 std::vector<std::string> FindLibraryPaths(const char* dir_path) {
518   std::vector<std::string> libs;
519 
520   errno = 0;
521   DIR* dir = opendir(dir_path);
522   if (!dir) {
523     ALOGD("%s: Unable to open directory %s (%s)", __FUNCTION__, dir_path,
524           strerror(errno));
525     return libs;
526   }
527 
528   struct dirent* entry = nullptr;
529   while ((entry = readdir(dir)) != nullptr) {
530     std::string lib_path(dir_path);
531     lib_path += entry->d_name;
532     struct stat st;
533     if (stat(lib_path.c_str(), &st) == 0) {
534       if (S_ISREG(st.st_mode)) {
535         libs.push_back(lib_path);
536       }
537     }
538   }
539 
540   return libs;
541 }
542 
IsStreamUseCaseSupported(const StreamConfiguration & stream_config,const std::set<int64_t> & stream_use_cases,bool log_if_not_supported)543 bool IsStreamUseCaseSupported(const StreamConfiguration& stream_config,
544                               const std::set<int64_t>& stream_use_cases,
545                               bool log_if_not_supported) {
546   for (const auto& stream : stream_config.streams) {
547     if (stream_use_cases.find(stream.use_case) == stream_use_cases.end()) {
548       if (log_if_not_supported) {
549         ALOGE("Stream use case %d not in set of supported use cases",
550               stream.use_case);
551       }
552       return false;
553     }
554   }
555   return true;
556 }
557 
GetStreamUseCases(const HalCameraMetadata * static_metadata,std::set<int64_t> * stream_use_cases)558 status_t GetStreamUseCases(const HalCameraMetadata* static_metadata,
559                            std::set<int64_t>* stream_use_cases) {
560   if (static_metadata == nullptr || stream_use_cases == nullptr) {
561     return BAD_VALUE;
562   }
563 
564   camera_metadata_ro_entry entry;
565   status_t ret =
566       static_metadata->Get(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
567   if (ret != OK) {
568     ALOGV("%s: No available stream use cases!", __FUNCTION__);
569     stream_use_cases->insert(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
570     return OK;
571   }
572   stream_use_cases->insert(entry.data.i64, entry.data.i64 + entry.count);
573 
574   return OK;
575 }
576 
IsSecuredStream(const Stream & stream)577 bool IsSecuredStream(const Stream& stream) {
578   return (stream.usage & GRALLOC_USAGE_PROTECTED) != 0u;
579 }
580 
IsStreamUseCasesVideoCall(const Stream & stream)581 bool IsStreamUseCasesVideoCall(const Stream& stream) {
582   return (stream.use_case ==
583           ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL)
584              ? true
585              : false;
586 }
587 
IsHdrStream(const Stream & stream)588 bool IsHdrStream(const Stream& stream) {
589   return stream.dynamic_profile !=
590          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
591 }
592 
593 }  // namespace utils
594 }  // namespace google_camera_hal
595 }  // namespace android
596