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