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_TAG "StreamConfigurationMap"
18 #include "StreamConfigurationMap.h"
19 
20 #include <log/log.h>
21 
22 namespace android {
23 const uint32_t kScalerStreamConfigurations =
24     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
25 const uint32_t kScalerStreamConfigurationsMaxRes =
26     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION;
27 
28 const uint32_t kDepthStreamConfigurations =
29     ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS;
30 const uint32_t kDepthStreamConfigurationsMaxRes =
31     ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION;
32 
33 const uint32_t kDynamicDepthStreamConfigurations =
34     ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS;
35 const uint32_t kDynamicDepthStreamConfigurationsMaxRes =
36     ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION;
37 
38 const uint32_t kScalerMinFrameDurations =
39     ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
40 const uint32_t kScalerMinFrameDurationsMaxRes =
41     ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION;
42 
43 const uint32_t kDepthMinFrameDurations =
44     ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS;
45 const uint32_t kDepthMinFrameDurationsMaxRes =
46     ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION;
47 
48 const uint32_t kScalerStallDurations = ANDROID_SCALER_AVAILABLE_STALL_DURATIONS;
49 const uint32_t kScalerStallDurationsMaxRes =
50     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION;
51 
52 const uint32_t kScalerInputOutputFormatsMap =
53     ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP;
54 const uint32_t kScalerInputOutputFormatsMapMaxRes =
55     ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION;
56 
57 const uint32_t kDepthStallDurations =
58     ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS;
59 const uint32_t kDepthStallDurationsMaxRes =
60     ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION;
61 
62 const uint32_t kJpegRStreamConfigurations =
63     ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS;
64 
AppendAvailableStreamConfigurations(const camera_metadata_ro_entry & entry)65 void StreamConfigurationMap::AppendAvailableStreamConfigurations(
66     const camera_metadata_ro_entry& entry) {
67   for (size_t i = 0; i < entry.count; i += kStreamConfigurationSize) {
68     int32_t width = entry.data.i32[i + kStreamWidthOffset];
69     int32_t height = entry.data.i32[i + kStreamHeightOffset];
70     auto format = static_cast<android_pixel_format_t>(
71         entry.data.i32[i + kStreamFormatOffset]);
72     int32_t isInput = entry.data.i32[i + kStreamIsInputOffset];
73     if (!isInput) {
74       stream_output_formats_.insert(format);
75       stream_output_size_map_[format].insert(std::make_pair(width, height));
76     }
77   }
78 }
79 
AppendAvailableDynamicPhysicalStreamConfigurations(const camera_metadata_ro_entry & entry)80 void StreamConfigurationMap::AppendAvailableDynamicPhysicalStreamConfigurations(
81     const camera_metadata_ro_entry& entry) {
82   for (size_t i = 0; i < entry.count; i += kStreamConfigurationSize) {
83     int32_t width = entry.data.i32[i + kStreamWidthOffset];
84     int32_t height = entry.data.i32[i + kStreamHeightOffset];
85     auto format = static_cast<android_pixel_format_t>(
86         entry.data.i32[i + kStreamFormatOffset]);
87 
88     // Both input and output dynamic stream sizes need to be supported as an
89     // output stream.
90     dynamic_physical_stream_output_formats_.insert(format);
91     dynamic_physical_stream_output_size_map_[format].insert(
92         std::make_pair(width, height));
93   }
94 }
95 
AppendAvailableStreamMinDurations(const camera_metadata_ro_entry_t & entry)96 void StreamConfigurationMap::AppendAvailableStreamMinDurations(
97     const camera_metadata_ro_entry_t& entry) {
98   for (size_t i = 0; i < entry.count; i += kStreamConfigurationSize) {
99     auto format = static_cast<android_pixel_format_t>(
100         entry.data.i64[i + kStreamFormatOffset]);
101     uint32_t width = entry.data.i64[i + kStreamWidthOffset];
102     uint32_t height = entry.data.i64[i + kStreamHeightOffset];
103     nsecs_t duration = entry.data.i64[i + kStreamMinDurationOffset];
104     auto streamConfiguration =
105         std::make_pair(format, std::make_pair(width, height));
106     stream_min_duration_map_[streamConfiguration] = duration;
107   }
108 }
109 
AppendAvailableStreamStallDurations(const camera_metadata_ro_entry & entry)110 void StreamConfigurationMap::AppendAvailableStreamStallDurations(
111     const camera_metadata_ro_entry& entry) {
112   for (size_t i = 0; i < entry.count; i += kStreamConfigurationSize) {
113     auto format = static_cast<android_pixel_format_t>(
114         entry.data.i64[i + kStreamFormatOffset]);
115     uint32_t width = entry.data.i64[i + kStreamWidthOffset];
116     uint32_t height = entry.data.i64[i + kStreamHeightOffset];
117     nsecs_t duration = entry.data.i64[i + kStreamStallDurationOffset];
118     auto streamConfiguration =
119         std::make_pair(format, std::make_pair(width, height));
120     stream_stall_map_[streamConfiguration] = duration;
121   }
122 }
123 
StreamConfigurationMap(const HalCameraMetadata & chars,bool maxResolution)124 StreamConfigurationMap::StreamConfigurationMap(const HalCameraMetadata& chars,
125                                                bool maxResolution) {
126   camera_metadata_ro_entry_t entry;
127   const char* maxResolutionStr = maxResolution ? "true" : "false";
128   auto ret = chars.Get(maxResolution ? kScalerStreamConfigurationsMaxRes
129                                      : kScalerStreamConfigurations,
130                        &entry);
131   if (ret != OK) {
132     ALOGW(
133         "%s: ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS missing, "
134         "maxResolution ? %s!",
135         __FUNCTION__, maxResolutionStr);
136     entry.count = 0;
137   }
138   AppendAvailableStreamConfigurations(entry);
139 
140   ret = chars.Get(maxResolution ? kDepthStreamConfigurationsMaxRes
141                                 : kDepthStreamConfigurations,
142                   &entry);
143 
144   if (ret == OK) {
145     AppendAvailableStreamConfigurations(entry);
146   }
147 
148   ret = chars.Get(maxResolution ? kDynamicDepthStreamConfigurations
149                                 : kDynamicDepthStreamConfigurationsMaxRes,
150                   &entry);
151 
152   if (ret == OK) {
153     AppendAvailableStreamConfigurations(entry);
154   }
155 
156   ret = chars.Get(
157       maxResolution ? kScalerMinFrameDurationsMaxRes : kScalerMinFrameDurations,
158       &entry);
159   if (ret != OK) {
160     ALOGW(
161         "%s: ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS missing!, max "
162         "resolution ? %s",
163         __FUNCTION__, maxResolutionStr);
164     entry.count = 0;
165   }
166   AppendAvailableStreamMinDurations(entry);
167 
168   ret = chars.Get(
169       maxResolution ? kDepthMinFrameDurationsMaxRes : kDepthMinFrameDurations,
170       &entry);
171   if (ret == OK) {
172     AppendAvailableStreamMinDurations(entry);
173   }
174 
175   ret = chars.Get(
176       maxResolution ? kScalerStallDurationsMaxRes : kScalerStallDurations,
177       &entry);
178   if (ret != OK) {
179     ALOGW(
180         "%s: ANDROID_SCALER_AVAILABLE_STALL_DURATIONS missing! maxResolution ? "
181         "%s",
182         __FUNCTION__, maxResolutionStr);
183     entry.count = 0;
184   }
185   AppendAvailableStreamStallDurations(entry);
186 
187   ret = chars.Get(
188       maxResolution ? kDepthStallDurationsMaxRes : kDepthStallDurations, &entry);
189   if (ret == OK) {
190     AppendAvailableStreamStallDurations(entry);
191   }
192 
193   ret = chars.Get(maxResolution ? kScalerInputOutputFormatsMapMaxRes
194                                 : kScalerInputOutputFormatsMap,
195                   &entry);
196   if (ret == OK) {
197     size_t i = 0;
198     while (i < entry.count) {
199       auto input_format =
200           static_cast<android_pixel_format_t>(entry.data.i32[i++]);
201       auto output_format_count = entry.data.i32[i++];
202       if (output_format_count <= 0 ||
203           ((output_format_count + i) > entry.count)) {
204         ALOGE("%s: Invalid output format count: %d!", __func__,
205               output_format_count);
206         break;
207       }
208       size_t output_formats_end = output_format_count + i;
209       for (; i < output_formats_end; i++) {
210         stream_input_output_map_[input_format].insert(
211             static_cast<android_pixel_format_t>(entry.data.i32[i]));
212       }
213       stream_input_formats_.insert(input_format);
214     }
215   }
216 
217   ret = chars.Get(
218       ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
219       &entry);
220   if (ret == OK) {
221     AppendAvailableDynamicPhysicalStreamConfigurations(entry);
222   }
223 
224   ret = chars.Get(kJpegRStreamConfigurations, &entry);
225   if (ret == OK) {
226     AppendAvailableJpegRStreamConfigurations(entry);
227   }
228 }
229 
AppendAvailableJpegRStreamConfigurations(const camera_metadata_ro_entry & entry)230 void StreamConfigurationMap::AppendAvailableJpegRStreamConfigurations(
231     const camera_metadata_ro_entry& entry) {
232   for (size_t i = 0; i < entry.count; i += kStreamConfigurationSize) {
233     int32_t width = entry.data.i32[i + kStreamWidthOffset];
234     int32_t height = entry.data.i32[i + kStreamHeightOffset];
235     auto format = static_cast<android_pixel_format_t>(
236         entry.data.i32[i + kStreamFormatOffset]);
237     int32_t isInput = entry.data.i32[i + kStreamIsInputOffset];
238     if (!isInput) {
239       jpegr_stream_output_size_map_[format].insert(
240           std::make_pair(width, height));
241     }
242   }
243 }
244 }  // namespace android
245