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