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 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 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 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