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