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