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 "FormatMetadataFactory"
19
20 #include "format_metadata_factory.h"
21
22 #include <algorithm>
23 #include <set>
24
25 #include "arc/image_processor.h"
26 #include "common.h"
27 #include "metadata/array_vector.h"
28 #include "metadata/partial_metadata_factory.h"
29 #include "metadata/property.h"
30
31 namespace v4l2_camera_hal {
32
GetHalFormats(const std::shared_ptr<V4L2Wrapper> & device,std::set<int32_t> * result_formats)33 static int GetHalFormats(const std::shared_ptr<V4L2Wrapper>& device,
34 std::set<int32_t>* result_formats) {
35 if (!result_formats) {
36 HAL_LOGE("Null result formats pointer passed");
37 return -EINVAL;
38 }
39
40 std::set<uint32_t> v4l2_formats;
41 int res = device->GetFormats(&v4l2_formats);
42 if (res) {
43 HAL_LOGE("Failed to get device formats.");
44 return res;
45 }
46
47 for (auto v4l2_format : v4l2_formats) {
48 int32_t hal_format = StreamFormat::V4L2ToHalPixelFormat(v4l2_format);
49 if (hal_format < 0) {
50 // Unrecognized/unused format. Skip it.
51 continue;
52 }
53 result_formats->insert(hal_format);
54 }
55
56 return 0;
57 }
58
FpsRangesCompare(std::array<int32_t,2> a,std::array<int32_t,2> b)59 static int FpsRangesCompare(std::array<int32_t, 2> a,
60 std::array<int32_t, 2> b) {
61 if (a[1] == b[1]) {
62 return a[0] > b[0];
63 }
64 return a[1] > b[1];
65 }
66
AddFormatComponents(std::shared_ptr<V4L2Wrapper> device,std::insert_iterator<PartialMetadataSet> insertion_point)67 int AddFormatComponents(
68 std::shared_ptr<V4L2Wrapper> device,
69 std::insert_iterator<PartialMetadataSet> insertion_point) {
70 HAL_LOG_ENTER();
71
72 // Get all supported formats.
73 std::set<int32_t> hal_formats;
74 int res = GetHalFormats(device, &hal_formats);
75 if (res) {
76 return res;
77 }
78
79 std::set<int32_t> unsupported_hal_formats;
80 if (hal_formats.find(HAL_PIXEL_FORMAT_YCbCr_420_888) == hal_formats.end()) {
81 HAL_LOGW("YCbCr_420_888 (0x%x) not directly supported by device.",
82 HAL_PIXEL_FORMAT_YCbCr_420_888);
83 hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888);
84 unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888);
85 }
86 if (hal_formats.find(HAL_PIXEL_FORMAT_BLOB) == hal_formats.end()) {
87 HAL_LOGW("JPEG (0x%x) not directly supported by device.",
88 HAL_PIXEL_FORMAT_BLOB);
89 hal_formats.insert(HAL_PIXEL_FORMAT_BLOB);
90 unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_BLOB);
91 }
92
93 // As hal_formats is populated by reading and converting V4L2 formats to the
94 // matching HAL formats, we will never see an implementation defined format in
95 // the list. We populate it ourselves and map it to a qualified format. If no
96 // qualified formats exist, this will be the first available format.
97 hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
98 unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
99
100 // Qualified formats are the set of formats supported by this camera that the
101 // image processor can translate into the YU12 format. We additionally check
102 // that the conversion from YU12 to the desired hal format is supported.
103 std::vector<uint32_t> qualified_formats;
104 res = device->GetQualifiedFormats(&qualified_formats);
105 if (res && unsupported_hal_formats.size() > 1) {
106 HAL_LOGE(
107 "Failed to retrieve qualified formats, cannot perform conversions.");
108 return res;
109 }
110
111 HAL_LOGI("Supports %zu qualified formats.", qualified_formats.size());
112
113 // Find sizes and frame/stall durations for all formats.
114 // We also want to find the smallest max frame duration amongst all formats,
115 // And the largest min frame duration amongst YUV (i.e. largest max frame rate
116 // supported by all YUV sizes).
117 // Stream configs are {format, width, height, direction} (input or output).
118 ArrayVector<int32_t, 4> stream_configs;
119 // Frame durations are {format, width, height, duration} (duration in ns).
120 ArrayVector<int64_t, 4> min_frame_durations;
121 // Stall durations are {format, width, height, duration} (duration in ns).
122 ArrayVector<int64_t, 4> stall_durations;
123 int64_t min_max_frame_duration = std::numeric_limits<int64_t>::max();
124 std::vector<std::array<int32_t, 2>> fps_ranges;
125 for (auto hal_format : hal_formats) {
126 // Get the corresponding V4L2 format.
127 uint32_t v4l2_format = StreamFormat::HalToV4L2PixelFormat(hal_format);
128 if (v4l2_format == 0) {
129 // Unrecognized/unused format. Should never happen since hal_formats
130 // came from translating a bunch of V4L2 formats above.
131 HAL_LOGE("Couldn't find V4L2 format for HAL format %d", hal_format);
132 return -ENODEV;
133 } else if (unsupported_hal_formats.find(hal_format) !=
134 unsupported_hal_formats.end()) {
135 if (hal_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
136 if (qualified_formats.size() != 0) {
137 v4l2_format = qualified_formats[0];
138 } else if (unsupported_hal_formats.size() == 1) {
139 v4l2_format = StreamFormat::HalToV4L2PixelFormat(
140 HAL_PIXEL_FORMAT_YCbCr_420_888);
141 } else {
142 // No-op. If there are no qualified formats, and implementation
143 // defined is not the only unsupported format, then other unsupported
144 // formats will throw an error.
145 }
146 HAL_LOGW(
147 "Implementation-defined format is set to V4L2 pixel format 0x%x",
148 v4l2_format);
149 } else if (qualified_formats.size() == 0) {
150 HAL_LOGE(
151 "Camera does not support required format: 0x%x, and there are no "
152 "qualified"
153 "formats to transform from.",
154 hal_format);
155 return -ENODEV;
156 } else if (!arc::ImageProcessor::SupportsConversion(V4L2_PIX_FMT_YUV420,
157 v4l2_format)) {
158 HAL_LOGE(
159 "The image processor does not support conversion to required "
160 "format: 0x%x",
161 hal_format);
162 return -ENODEV;
163 } else {
164 v4l2_format = qualified_formats[0];
165 HAL_LOGW(
166 "Hal format 0x%x will be converted from V4L2 pixel format 0x%x",
167 hal_format, v4l2_format);
168 }
169 }
170
171 // Get the available sizes for this format.
172 std::set<std::array<int32_t, 2>> frame_sizes;
173 res = device->GetFormatFrameSizes(v4l2_format, &frame_sizes);
174 if (res) {
175 HAL_LOGE("Failed to get all frame sizes for format %d", v4l2_format);
176 return res;
177 }
178
179 for (const auto& frame_size : frame_sizes) {
180 // Note the format and size combination in stream configs.
181 stream_configs.push_back(
182 {{hal_format,
183 frame_size[0],
184 frame_size[1],
185 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}});
186
187 // Find the duration range for this format and size.
188 std::array<int64_t, 2> duration_range;
189 res = device->GetFormatFrameDurationRange(
190 v4l2_format, frame_size, &duration_range);
191 if (res) {
192 HAL_LOGE(
193 "Failed to get frame duration range for format %d, "
194 "size %u x %u",
195 v4l2_format,
196 frame_size[0],
197 frame_size[1]);
198 return res;
199 }
200 int64_t size_min_frame_duration = duration_range[0];
201 int64_t size_max_frame_duration = duration_range[1];
202 min_frame_durations.push_back({{hal_format,
203 frame_size[0],
204 frame_size[1],
205 size_min_frame_duration}});
206
207 // Note the stall duration for this format and size.
208 // Usually 0 for non-jpeg, non-zero for JPEG.
209 // Randomly choosing absurd 1 sec for JPEG. Unsure what this breaks.
210 int64_t stall_duration = 0;
211 if (hal_format == HAL_PIXEL_FORMAT_BLOB) {
212 stall_duration = 1000000000;
213 }
214 stall_durations.push_back(
215 {{hal_format, frame_size[0], frame_size[1], stall_duration}});
216
217 // Update our search for general min & max frame durations.
218 // In theory max frame duration (min frame rate) should be consistent
219 // between all formats, but we check and only advertise the smallest
220 // available max duration just in case.
221 if (size_max_frame_duration < min_max_frame_duration) {
222 min_max_frame_duration = size_max_frame_duration;
223 }
224 // ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES will contain all
225 // the fps ranges for YUV_420_888 only since YUV_420_888 format is
226 // the default camera format by Android.
227 if (hal_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
228 // Convert from frame durations measured in ns.
229 // Min, max fps supported by all YUV formats.
230 const int32_t min_fps = 1000000000 / size_max_frame_duration;
231 const int32_t max_fps = 1000000000 / size_min_frame_duration;
232 if (std::find(fps_ranges.begin(), fps_ranges.end(),
233 std::array<int32_t, 2>{min_fps, max_fps}) ==
234 fps_ranges.end()) {
235 fps_ranges.push_back({min_fps, max_fps});
236 }
237 }
238 }
239 }
240
241 // Sort fps ranges in descending order.
242 std::sort(fps_ranges.begin(), fps_ranges.end(), FpsRangesCompare);
243
244 // Construct the metadata components.
245 insertion_point = std::make_unique<Property<ArrayVector<int32_t, 4>>>(
246 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
247 std::move(stream_configs));
248 insertion_point = std::make_unique<Property<ArrayVector<int64_t, 4>>>(
249 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
250 std::move(min_frame_durations));
251 insertion_point = std::make_unique<Property<ArrayVector<int64_t, 4>>>(
252 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, std::move(stall_durations));
253 insertion_point = std::make_unique<Property<int64_t>>(
254 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, min_max_frame_duration);
255 // TODO(b/31019725): This should probably not be a NoEffect control.
256 insertion_point = NoEffectMenuControl<std::array<int32_t, 2>>(
257 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
258 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fps_ranges,
259 {{CAMERA3_TEMPLATE_VIDEO_RECORD, fps_ranges.front()},
260 {OTHER_TEMPLATES, fps_ranges.back()}});
261
262 return 0;
263 }
264
265 } // namespace v4l2_camera_hal
266