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