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