1 /*
2 * Copyright (C) 2016 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 "MetadataReader"
19
20 #include "metadata_reader.h"
21
22 #include <cutils/log.h>
23 #include <system/camera.h>
24
25 #include "metadata_common.h"
26
27 namespace default_camera_hal {
28
MetadataReader(std::unique_ptr<const android::CameraMetadata> metadata)29 MetadataReader::MetadataReader(
30 std::unique_ptr<const android::CameraMetadata> metadata)
31 : metadata_(std::move(metadata)) {}
32
~MetadataReader()33 MetadataReader::~MetadataReader() {}
34
Facing(int * facing) const35 int MetadataReader::Facing(int* facing) const {
36 uint8_t metadata_facing = 0;
37 int res = v4l2_camera_hal::SingleTagValue(
38 *metadata_, ANDROID_LENS_FACING, &metadata_facing);
39 if (res) {
40 ALOGE("%s: Failed to get facing from static metadata.", __func__);
41 return res;
42 }
43
44 switch (metadata_facing) {
45 case (ANDROID_LENS_FACING_FRONT):
46 *facing = CAMERA_FACING_FRONT;
47 break;
48 case (ANDROID_LENS_FACING_BACK):
49 *facing = CAMERA_FACING_BACK;
50 break;
51 case (ANDROID_LENS_FACING_EXTERNAL):
52 *facing = CAMERA_FACING_EXTERNAL;
53 break;
54 default:
55 ALOGE("%s: Invalid facing from static metadata: %d.",
56 __func__,
57 metadata_facing);
58 return -EINVAL;
59 }
60 return 0;
61 }
62
Orientation(int * orientation) const63 int MetadataReader::Orientation(int* orientation) const {
64 int32_t metadata_orientation = 0;
65 int res = v4l2_camera_hal::SingleTagValue(
66 *metadata_, ANDROID_SENSOR_ORIENTATION, &metadata_orientation);
67 if (res) {
68 ALOGE("%s: Failed to get orientation from static metadata.", __func__);
69 return res;
70 }
71
72 // Orientation must be 0, 90, 180, or 270.
73 if (metadata_orientation < 0 || metadata_orientation > 270 ||
74 metadata_orientation % 90 != 0) {
75 ALOGE(
76 "%s: Invalid orientation %d "
77 "(must be a 90-degree increment in [0, 360)).",
78 __func__,
79 metadata_orientation);
80 return -EINVAL;
81 }
82
83 *orientation = static_cast<int>(metadata_orientation);
84 return 0;
85 }
86
MaxInputStreams(int32_t * max_input) const87 int MetadataReader::MaxInputStreams(int32_t* max_input) const {
88 int res = v4l2_camera_hal::SingleTagValue(
89 *metadata_, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, max_input);
90 if (res == -ENOENT) {
91 // Not required; default to 0.
92 *max_input = 0;
93 } else if (res) {
94 ALOGE("%s: Failed to get max output streams from static metadata.",
95 __func__);
96 return res;
97 }
98 return 0;
99 }
100
MaxOutputStreams(int32_t * max_raw,int32_t * max_non_stalling,int32_t * max_stalling) const101 int MetadataReader::MaxOutputStreams(int32_t* max_raw,
102 int32_t* max_non_stalling,
103 int32_t* max_stalling) const {
104 std::array<int32_t, 3> max_output_streams;
105 int res = v4l2_camera_hal::SingleTagValue(
106 *metadata_, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams);
107 if (res) {
108 ALOGE("%s: Failed to get max output streams from static metadata.",
109 __func__);
110 return res;
111 }
112 *max_raw = max_output_streams[0];
113 *max_non_stalling = max_output_streams[1];
114 *max_stalling = max_output_streams[2];
115 return 0;
116 }
117
RequestCapabilities(std::set<uint8_t> * capabilities) const118 int MetadataReader::RequestCapabilities(std::set<uint8_t>* capabilities) const {
119 std::vector<uint8_t> raw_capabilities;
120 int res = v4l2_camera_hal::VectorTagValue(
121 *metadata_, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &raw_capabilities);
122 if (res) {
123 ALOGE("%s: Failed to get request capabilities from static metadata.",
124 __func__);
125 return res;
126 }
127
128 // Move from vector to set.
129 capabilities->insert(raw_capabilities.begin(), raw_capabilities.end());
130 return 0;
131 }
132
StreamConfigurations(std::vector<StreamConfiguration> * configs) const133 int MetadataReader::StreamConfigurations(
134 std::vector<StreamConfiguration>* configs) const {
135 std::vector<RawStreamConfiguration> raw_stream_configs;
136 int res = v4l2_camera_hal::VectorTagValue(
137 *metadata_,
138 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
139 &raw_stream_configs);
140 if (res) {
141 ALOGE("%s: Failed to get stream configs from static metadata.", __func__);
142 return res;
143 }
144
145 // TODO(b/31384253): check for required configs.
146
147 // Convert from raw.
148 configs->insert(
149 configs->end(), raw_stream_configs.begin(), raw_stream_configs.end());
150
151 // Check that all configs are valid.
152 for (const auto& config : *configs) {
153 // Must have positive dimensions.
154 if (config.spec.width < 1 || config.spec.height < 1) {
155 ALOGE("%s: Invalid stream config: non-positive dimensions (%d, %d).",
156 __func__,
157 config.spec.width,
158 config.spec.height);
159 return -EINVAL;
160 }
161 // Must have a known direction enum.
162 switch (config.direction) {
163 case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT:
164 case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT:
165 break;
166 default:
167 ALOGE("%s: Invalid stream config direction: %d.",
168 __func__,
169 config.direction);
170 return -EINVAL;
171 }
172 }
173 return 0;
174 }
175
StreamStallDurations(std::vector<StreamStallDuration> * stalls) const176 int MetadataReader::StreamStallDurations(
177 std::vector<StreamStallDuration>* stalls) const {
178 std::vector<RawStreamStallDuration> raw_stream_stall_durations;
179 int res =
180 v4l2_camera_hal::VectorTagValue(*metadata_,
181 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
182 &raw_stream_stall_durations);
183 if (res) {
184 ALOGE("%s: Failed to get stall durations from static metadata.", __func__);
185 return res;
186 }
187
188 // Convert from raw.
189 stalls->insert(stalls->end(),
190 raw_stream_stall_durations.begin(),
191 raw_stream_stall_durations.end());
192 // Check that all stalls are valid.
193 for (const auto& stall : *stalls) {
194 // Must have positive dimensions.
195 if (stall.spec.width < 1 || stall.spec.height < 1) {
196 ALOGE("%s: Invalid stall duration: non-positive dimensions (%d, %d).",
197 __func__,
198 stall.spec.width,
199 stall.spec.height);
200 return -EINVAL;
201 }
202 // Must have a non-negative stall.
203 if (stall.duration < 0) {
204 ALOGE("%s: Invalid stall duration: negative stall %lld.",
205 __func__,
206 static_cast<long long>(stall.duration));
207 return -EINVAL;
208 }
209 // TODO(b/31384253): YUV_420_888, RAW10, RAW12, RAW_OPAQUE,
210 // and IMPLEMENTATION_DEFINED must have 0 stall duration.
211 }
212
213 return 0;
214 }
215
ReprocessFormats(ReprocessFormatMap * reprocess_map) const216 int MetadataReader::ReprocessFormats(ReprocessFormatMap* reprocess_map) const {
217 std::vector<int32_t> input_output_formats;
218 int res = v4l2_camera_hal::VectorTagValue(
219 *metadata_,
220 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
221 &input_output_formats);
222 if (res) {
223 ALOGE("%s: Failed to get input output format map from static metadata.",
224 __func__);
225 return res;
226 }
227
228 // Convert from the raw vector.
229 for (size_t i = 0; i < input_output_formats.size();) {
230 // The map is represented as variable-length entries of the format
231 // input, num_outputs, <outputs>.
232
233 // Get the input format.
234 int32_t input_format = input_output_formats[i++];
235
236 // Find the output begin and end for this format.
237 int32_t num_output_formats = input_output_formats[i++];
238 if (num_output_formats < 1) {
239 ALOGE(
240 "%s: No output formats for input format %d.", __func__, input_format);
241 return -EINVAL;
242 }
243 size_t outputs_end = i + num_output_formats;
244 if (outputs_end > input_output_formats.size()) {
245 ALOGE("%s: Input format %d requests more data than available.",
246 __func__,
247 input_format);
248 return -EINVAL;
249 }
250
251 // Copy all the output formats into the map.
252 (*reprocess_map)[input_format].insert(
253 input_output_formats.data() + i,
254 input_output_formats.data() + outputs_end);
255
256 // Move on to the next entry.
257 i = outputs_end;
258 }
259
260 // TODO(b/31384253): check for required mappings.
261
262 return 0;
263 }
264
265 } // namespace default_camera_hal
266