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, ¶m);
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