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 24namespace v4l2_camera_hal { 25 26static 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 52static 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 60int 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