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_Utils"
19
20 #include "utils.h"
21
22 #include <hardware/gralloc.h>
23
24 #include "vendor_tag_defs.h"
25
26 namespace android {
27 namespace google_camera_hal {
28 namespace utils {
29
IsDepthStream(const Stream & stream)30 bool IsDepthStream(const Stream& stream) {
31 if (stream.stream_type == StreamType::kOutput &&
32 stream.data_space == HAL_DATASPACE_DEPTH &&
33 stream.format == HAL_PIXEL_FORMAT_Y16) {
34 return true;
35 }
36
37 return false;
38 }
39
IsPreviewStream(const Stream & stream)40 bool IsPreviewStream(const Stream& stream) {
41 if (stream.stream_type == StreamType::kOutput &&
42 stream.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
43 ((stream.usage & GRALLOC_USAGE_HW_COMPOSER) == GRALLOC_USAGE_HW_COMPOSER ||
44 (stream.usage & GRALLOC_USAGE_HW_TEXTURE) == GRALLOC_USAGE_HW_TEXTURE)) {
45 return true;
46 }
47
48 return false;
49 }
50
IsJPEGSnapshotStream(const Stream & stream)51 bool IsJPEGSnapshotStream(const Stream& stream) {
52 if (stream.stream_type == StreamType::kOutput &&
53 stream.format == HAL_PIXEL_FORMAT_BLOB &&
54 (stream.data_space == HAL_DATASPACE_JFIF ||
55 stream.data_space == HAL_DATASPACE_V0_JFIF)) {
56 return true;
57 }
58
59 return false;
60 }
61
IsOutputZslStream(const Stream & stream)62 bool IsOutputZslStream(const Stream& stream) {
63 if (stream.stream_type == StreamType::kOutput &&
64 (stream.usage & GRALLOC_USAGE_HW_CAMERA_ZSL) ==
65 GRALLOC_USAGE_HW_CAMERA_ZSL) {
66 return true;
67 }
68
69 return false;
70 }
71
IsVideoStream(const Stream & stream)72 bool IsVideoStream(const Stream& stream) {
73 if (stream.stream_type == StreamType::kOutput &&
74 (stream.usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0) {
75 return true;
76 }
77
78 return false;
79 }
80
IsRawStream(const Stream & stream)81 bool IsRawStream(const Stream& stream) {
82 if (stream.stream_type == StreamType::kOutput &&
83 (stream.format == HAL_PIXEL_FORMAT_RAW10 ||
84 stream.format == HAL_PIXEL_FORMAT_RAW16 ||
85 stream.format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
86 return true;
87 }
88
89 return false;
90 }
91
IsInputRawStream(const Stream & stream)92 bool IsInputRawStream(const Stream& stream) {
93 if (stream.stream_type == StreamType::kInput &&
94 (stream.format == HAL_PIXEL_FORMAT_RAW10 ||
95 stream.format == HAL_PIXEL_FORMAT_RAW16 ||
96 stream.format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
97 return true;
98 }
99
100 return false;
101 }
102
IsArbitraryDataSpaceRawStream(const Stream & stream)103 bool IsArbitraryDataSpaceRawStream(const Stream& stream) {
104 return IsRawStream(stream) && (stream.data_space == HAL_DATASPACE_ARBITRARY);
105 }
106
IsYUVSnapshotStream(const Stream & stream)107 bool IsYUVSnapshotStream(const Stream& stream) {
108 if (stream.stream_type == StreamType::kOutput &&
109 stream.format == HAL_PIXEL_FORMAT_YCbCr_420_888 &&
110 !IsVideoStream(stream) && !IsPreviewStream(stream)) {
111 return true;
112 }
113
114 return false;
115 }
116
GetSensorPhysicalSize(const HalCameraMetadata * characteristics,float * width,float * height)117 status_t GetSensorPhysicalSize(const HalCameraMetadata* characteristics,
118 float* width, float* height) {
119 if (characteristics == nullptr || width == nullptr || height == nullptr) {
120 ALOGE("%s: characteristics or width/height is nullptr", __FUNCTION__);
121 return BAD_VALUE;
122 }
123
124 camera_metadata_ro_entry entry;
125 status_t res = characteristics->Get(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, &entry);
126 if (res != OK || entry.count != 2) {
127 ALOGE(
128 "%s: Getting ANDROID_SENSOR_INFO_PHYSICAL_SIZE failed: %s(%d) count: "
129 "%zu",
130 __FUNCTION__, strerror(-res), res, entry.count);
131 return res;
132 }
133
134 *width = entry.data.f[0];
135 *height = entry.data.f[1];
136 return OK;
137 }
138
GetSensorActiveArraySize(const HalCameraMetadata * characteristics,Rect * active_array)139 status_t GetSensorActiveArraySize(const HalCameraMetadata* characteristics,
140 Rect* active_array) {
141 if (characteristics == nullptr || active_array == nullptr) {
142 ALOGE("%s: characteristics or active_array is nullptr", __FUNCTION__);
143 return BAD_VALUE;
144 }
145
146 camera_metadata_ro_entry entry;
147 status_t res =
148 characteristics->Get(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &entry);
149 if (res != OK || entry.count != 4) {
150 ALOGE(
151 "%s: Getting ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE failed: %s(%d) "
152 "count: %zu",
153 __FUNCTION__, strerror(-res), res, entry.count);
154 return res;
155 }
156
157 active_array->left = entry.data.i32[0];
158 active_array->top = entry.data.i32[1];
159 active_array->right = entry.data.i32[0] + entry.data.i32[2] - 1;
160 active_array->bottom = entry.data.i32[1] + entry.data.i32[3] - 1;
161
162 return OK;
163 }
164
GetZoomRatioRange(const HalCameraMetadata * characteristics,ZoomRatioRange * zoom_ratio_range)165 status_t GetZoomRatioRange(const HalCameraMetadata* characteristics,
166 ZoomRatioRange* zoom_ratio_range) {
167 if (characteristics == nullptr || zoom_ratio_range == nullptr) {
168 ALOGE("%s: characteristics or zoom_ratio_range is nullptr", __FUNCTION__);
169 return BAD_VALUE;
170 }
171
172 camera_metadata_ro_entry entry;
173 status_t res = characteristics->Get(ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
174 if (res != OK || entry.count != 2) {
175 ALOGE(
176 "%s: Getting ANDROID_CONTROL_ZOOM_RATIO_RANGE failed: %s(%d) "
177 "count: %zu",
178 __FUNCTION__, strerror(-res), res, entry.count);
179 return res;
180 }
181
182 zoom_ratio_range->min = entry.data.f[0];
183 zoom_ratio_range->max = entry.data.f[1];
184
185 return OK;
186 }
187
GetSensorPixelArraySize(const HalCameraMetadata * characteristics,Dimension * pixel_array)188 status_t GetSensorPixelArraySize(const HalCameraMetadata* characteristics,
189 Dimension* pixel_array) {
190 if (characteristics == nullptr || pixel_array == nullptr) {
191 ALOGE("%s: characteristics or pixel_array is nullptr", __FUNCTION__);
192 return BAD_VALUE;
193 }
194
195 camera_metadata_ro_entry entry;
196 status_t res =
197 characteristics->Get(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, &entry);
198 if (res != OK || entry.count != 2) {
199 ALOGE(
200 "%s: Getting ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE failed: %s(%d) "
201 "count: %zu",
202 __FUNCTION__, strerror(-res), res, entry.count);
203 return res;
204 }
205
206 pixel_array->width = entry.data.i32[0];
207 pixel_array->height = entry.data.i32[1];
208
209 return OK;
210 }
211
GetFocalLength(const HalCameraMetadata * characteristics,float * focal_length)212 status_t GetFocalLength(const HalCameraMetadata* characteristics,
213 float* focal_length) {
214 if (characteristics == nullptr || focal_length == nullptr) {
215 ALOGE("%s: characteristics or focal_length is nullptr", __FUNCTION__);
216 return BAD_VALUE;
217 }
218
219 camera_metadata_ro_entry entry;
220 status_t res =
221 characteristics->Get(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &entry);
222 if (res != OK || entry.count != 1) {
223 ALOGE(
224 "%s: Getting ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS failed: %s(%d) "
225 "count: %zu",
226 __FUNCTION__, strerror(-res), res, entry.count);
227 return res;
228 }
229
230 *focal_length = entry.data.f[0];
231
232 return OK;
233 }
234
IsLiveSnapshotConfigured(const StreamConfiguration & stream_config)235 bool IsLiveSnapshotConfigured(const StreamConfiguration& stream_config) {
236 bool has_video_stream = false;
237 bool has_jpeg_stream = false;
238 for (auto stream : stream_config.streams) {
239 if (utils::IsVideoStream(stream)) {
240 has_video_stream = true;
241 } else if (utils::IsJPEGSnapshotStream(stream)) {
242 has_jpeg_stream = true;
243 }
244 }
245
246 return (has_video_stream & has_jpeg_stream);
247 }
248
IsHighSpeedModeFpsCompatible(StreamConfigurationMode mode,const HalCameraMetadata * old_session,const HalCameraMetadata * new_session)249 bool IsHighSpeedModeFpsCompatible(StreamConfigurationMode mode,
250 const HalCameraMetadata* old_session,
251 const HalCameraMetadata* new_session) {
252 if (mode != StreamConfigurationMode::kConstrainedHighSpeed) {
253 return false;
254 }
255
256 camera_metadata_ro_entry_t ae_target_fps_entry;
257 int32_t old_max_fps = 0;
258 int32_t new_max_fps = 0;
259
260 if (old_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
261 &ae_target_fps_entry) == OK) {
262 old_max_fps = ae_target_fps_entry.data.i32[1];
263 }
264 if (new_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
265 &ae_target_fps_entry) == OK) {
266 new_max_fps = ae_target_fps_entry.data.i32[1];
267 }
268
269 ALOGI("%s: HFR: old max fps: %d, new max fps: %d", __FUNCTION__, old_max_fps,
270 new_max_fps);
271
272 if (new_max_fps == old_max_fps) {
273 return true;
274 }
275
276 return false;
277 }
278
IsSessionParameterCompatible(const HalCameraMetadata * old_session,const HalCameraMetadata * new_session)279 bool IsSessionParameterCompatible(const HalCameraMetadata* old_session,
280 const HalCameraMetadata* new_session) {
281 auto old_session_count = old_session->GetEntryCount();
282 auto new_session_count = new_session->GetEntryCount();
283 if (old_session_count == 0 || new_session_count == 0) {
284 ALOGI("No session paramerter, old:%zu, new:%zu", old_session_count,
285 new_session_count);
286 if (new_session_count != 0) {
287 camera_metadata_ro_entry_t entry;
288 if (new_session->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry) == OK) {
289 int32_t max_fps = entry.data.i32[1];
290 if (max_fps > 30) {
291 ALOGI("new session paramerter max fps:%d", max_fps);
292 return false;
293 }
294 }
295 }
296 return true;
297 }
298
299 if (old_session_count != new_session_count) {
300 ALOGI(
301 "Entry count has changed from %zu "
302 "to %zu",
303 old_session_count, new_session_count);
304 return false;
305 }
306
307 for (size_t entry_index = 0; entry_index < new_session_count; entry_index++) {
308 camera_metadata_ro_entry_t new_entry;
309 // Get the medata from new session first
310 if (new_session->GetByIndex(&new_entry, entry_index) != OK) {
311 ALOGW("Unable to get new session entry for index %zu", entry_index);
312 return false;
313 }
314
315 // Get the same tag from old session
316 camera_metadata_ro_entry_t old_entry;
317 if (old_session->Get(new_entry.tag, &old_entry) != OK) {
318 ALOGW("Unable to get old session tag 0x%x", new_entry.tag);
319 return false;
320 }
321
322 if (new_entry.count != old_entry.count) {
323 ALOGI(
324 "New entry count %zu doesn't "
325 "match old entry count %zu",
326 new_entry.count, old_entry.count);
327 return false;
328 }
329
330 if (new_entry.tag == ANDROID_CONTROL_AE_TARGET_FPS_RANGE) {
331 // Stream reconfiguration is not needed in case the upper
332 // framerate range remains unchanged. Any other modification
333 // to the session parameters must trigger new stream
334 // configuration.
335 int32_t old_min_fps = old_entry.data.i32[0];
336 int32_t old_max_fps = old_entry.data.i32[1];
337 int32_t new_min_fps = new_entry.data.i32[0];
338 int32_t new_max_fps = new_entry.data.i32[1];
339 if (old_max_fps == new_max_fps) {
340 ALOGI("%s: Ignore fps (%d, %d) to (%d, %d)", __FUNCTION__, old_min_fps,
341 old_max_fps, new_min_fps, new_max_fps);
342 continue;
343 }
344
345 return false;
346 } else {
347 // Same type and count, compare values
348 size_t type_size = camera_metadata_type_size[old_entry.type];
349 size_t entry_size = type_size * old_entry.count;
350 int32_t cmp = memcmp(new_entry.data.u8, old_entry.data.u8, entry_size);
351 if (cmp != 0) {
352 ALOGI("Session parameter value has changed");
353 return false;
354 }
355 }
356 }
357
358 return true;
359 }
360
ConvertZoomRatio(const float zoom_ratio,const Dimension & active_array_dimension,int32_t * left,int32_t * top,int32_t * width,int32_t * height)361 void ConvertZoomRatio(const float zoom_ratio,
362 const Dimension& active_array_dimension, int32_t* left,
363 int32_t* top, int32_t* width, int32_t* height) {
364 if (left == nullptr || top == nullptr || width == nullptr ||
365 height == nullptr) {
366 ALOGE("%s, invalid params", __FUNCTION__);
367 return;
368 }
369
370 assert(zoom_ratio != 0);
371 *left = std::round(*left / zoom_ratio + 0.5f * active_array_dimension.width *
372 (1.0f - 1.0f / zoom_ratio));
373 *top = std::round(*top / zoom_ratio + 0.5f * active_array_dimension.height *
374 (1.0f - 1.0f / zoom_ratio));
375 *width = std::round(*width / zoom_ratio);
376 *height = std::round(*height / zoom_ratio);
377
378 if (zoom_ratio >= 1.0f) {
379 utils::ClampBoundary(active_array_dimension, left, top, width, height);
380 }
381 }
382
383 } // namespace utils
384 } // namespace google_camera_hal
385 } // namespace android
386