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