1 /* 2 * Copyright (C) 2023 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 #pragma once 18 19 #include "ConfigManagerUtil.h" 20 21 #include <aidl/android/hardware/automotive/evs/CameraParam.h> 22 #include <aidl/android/hardware/graphics/common/PixelFormat.h> 23 #include <android-base/logging.h> 24 #include <system/camera_metadata.h> 25 26 #include <tinyxml2.h> 27 28 #include <limits> 29 #include <string> 30 #include <string_view> 31 #include <type_traits> 32 #include <unordered_map> 33 #include <unordered_set> 34 #include <vector> 35 36 /* 37 * Please note that this is different from what is defined in 38 * libhardware/modules/camera/3_4/metadata/types.h; this has one additional 39 * field to store a framerate. 40 */ 41 typedef struct { 42 int id; 43 int width; 44 int height; 45 ::aidl::android::hardware::graphics::common::PixelFormat format; 46 int type; 47 int framerate; 48 } StreamConfiguration; 49 50 class ConfigManager final { 51 public: 52 static std::unique_ptr<ConfigManager> Create(); 53 static std::unique_ptr<ConfigManager> Create(const std::string path); 54 ConfigManager(const ConfigManager&) = delete; 55 ConfigManager& operator=(const ConfigManager&) = delete; 56 57 /* Camera device's capabilities and metadata */ 58 class CameraInfo { 59 public: 60 enum class DeviceType : std::int32_t { 61 NONE = 0, 62 MOCK = 1, 63 V4L2 = 2, 64 VIDEO = 3, 65 66 UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(), 67 }; 68 69 enum class PixelFormat : std::int32_t { 70 NV12 = 0, 71 NV21 = 1, 72 YV12 = 2, 73 I420 = 3, 74 75 UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(), 76 }; 77 CameraInfo()78 CameraInfo() : characteristics(nullptr) {} 79 80 virtual ~CameraInfo(); 81 82 /* Allocate memory for camera_metadata_t */ allocate(size_t entry_cap,size_t data_cap)83 bool allocate(size_t entry_cap, size_t data_cap) { 84 if (characteristics != nullptr) { 85 LOG(ERROR) << "Camera metadata is already allocated"; 86 return false; 87 } 88 89 characteristics = allocate_camera_metadata(entry_cap, data_cap); 90 return characteristics != nullptr; 91 } 92 93 static DeviceType deviceTypeFromSV(const std::string_view sv); 94 95 static PixelFormat pixelFormatFromSV(const std::string_view sv); 96 97 DeviceType deviceType{DeviceType::NONE}; 98 99 /* 100 * List of supported controls that the primary client can program. 101 * Paraemters are stored with its valid range 102 */ 103 std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam, 104 std::tuple<int32_t, int32_t, int32_t>> 105 controls; 106 107 /* 108 * List of supported output stream configurations. 109 */ 110 std::unordered_map<int32_t, StreamConfiguration> streamConfigurations; 111 112 /* 113 * Internal storage for camera metadata. Each entry holds a pointer to 114 * data and number of elements 115 */ 116 std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata; 117 118 /* Camera module characteristics */ 119 camera_metadata_t* characteristics; 120 121 /* Format of media in a given media container. This field is effective 122 * only for DeviceType::VIDEO. 123 */ 124 PixelFormat format; 125 }; 126 127 class CameraGroupInfo : public CameraInfo { 128 public: CameraGroupInfo()129 CameraGroupInfo() {} 130 131 /* ID of member camera devices */ 132 std::unordered_set<std::string> devices; 133 134 /* The capture operation of member camera devices are synchronized */ 135 int32_t synchronized = 0; 136 }; 137 138 class SystemInfo { 139 public: 140 /* number of available cameras */ 141 int32_t numCameras = 0; 142 }; 143 144 class DisplayInfo { 145 public: 146 /* 147 * List of supported input stream configurations. 148 */ 149 std::unordered_map<int32_t, StreamConfiguration> streamConfigurations; 150 }; 151 152 /* 153 * Return system information 154 * 155 * @return SystemInfo 156 * Constant reference of SystemInfo. 157 */ getSystemInfo()158 const SystemInfo& getSystemInfo() { 159 std::unique_lock<std::mutex> lock(mConfigLock); 160 mConfigCond.wait(lock, [this] { return mIsReady; }); 161 return mSystemInfo; 162 } 163 164 /* 165 * Return a list of camera identifiers 166 * 167 * This function assumes that it is not being called frequently. 168 * 169 * @return std::vector<std::string> 170 * A vector that contains unique camera device identifiers. 171 */ getCameraIdList()172 std::vector<std::string> getCameraIdList() { 173 std::unique_lock<std::mutex> lock(mConfigLock); 174 mConfigCond.wait(lock, [this] { return mIsReady; }); 175 176 std::vector<std::string> aList; 177 aList.reserve(mCameraInfo.size()); 178 for (auto&& v : mCameraInfo) { 179 aList.push_back(v.first); 180 } 181 182 return aList; 183 } 184 185 /* 186 * Return a list of camera group identifiers 187 * 188 * This function assumes that it is not being called frequently. 189 * 190 * @return std::vector<std::string> 191 * A vector that contains unique camera device identifiers. 192 */ getCameraGroupIdList()193 std::vector<std::string> getCameraGroupIdList() { 194 std::unique_lock<std::mutex> lock(mConfigLock); 195 mConfigCond.wait(lock, [this] { return mIsReady; }); 196 197 std::vector<std::string> aList; 198 aList.reserve(mCameraGroups.size()); 199 for (auto&& v : mCameraGroups) { 200 aList.push_back(v.first); 201 } 202 203 return aList; 204 } 205 206 /* 207 * Return a pointer to the camera group 208 * 209 * @return CameraGroup 210 * A pointer to a camera group identified by a given id. 211 */ getCameraGroupInfo(const std::string & gid)212 std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) { 213 std::unique_lock<std::mutex> lock(mConfigLock); 214 mConfigCond.wait(lock, [this] { return mIsReady; }); 215 216 return mCameraGroups[gid]; 217 } 218 219 /* 220 * Return a camera metadata 221 * 222 * @param cameraId 223 * Unique camera node identifier in string 224 * 225 * @return unique_ptr<CameraInfo> 226 * A pointer to CameraInfo that is associated with a given camera 227 * ID. This returns a null pointer if this does not recognize a 228 * given camera identifier. 229 */ getCameraInfo(const std::string & cameraId)230 std::unique_ptr<CameraInfo>& getCameraInfo(const std::string& cameraId) noexcept { 231 std::unique_lock<std::mutex> lock(mConfigLock); 232 mConfigCond.wait(lock, [this] { return mIsReady; }); 233 234 return mCameraInfo[cameraId]; 235 } 236 237 /* 238 * Tell whether the configuration data is ready to be used 239 * 240 * @return bool 241 * True if configuration data is ready to be consumed. 242 */ isReady()243 bool isReady() const { return mIsReady; } 244 245 private: 246 /* Constructors */ ConfigManager()247 ConfigManager() : mBinaryFilePath("") {} 248 249 static std::string_view sConfigDefaultPath; 250 static std::string_view sConfigOverridePath; 251 252 /* System configuration */ 253 SystemInfo mSystemInfo; 254 255 /* Internal data structure for camera device information */ 256 std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo; 257 258 /* Internal data structure for camera device information */ 259 std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo; 260 261 /* Camera groups are stored in <groud id, CameraGroup> hash map */ 262 std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups; 263 264 /* 265 * Camera positions are stored in <position, camera id set> hash map. 266 * The position must be one of front, rear, left, and right. 267 */ 268 std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition; 269 270 /* Configuration data lock */ 271 mutable std::mutex mConfigLock; 272 273 /* 274 * This condition is signalled when it completes a configuration data 275 * preparation. 276 */ 277 std::condition_variable mConfigCond; 278 279 /* A path to a binary configuration file */ 280 const char* mBinaryFilePath; 281 282 /* Configuration data readiness */ 283 bool mIsReady = false; 284 285 /* 286 * Parse a given EVS configuration file and store the information 287 * internally. 288 * 289 * @return bool 290 * True if it completes parsing a file successfully. 291 */ 292 bool readConfigDataFromXML(const std::string path) noexcept; 293 294 /* 295 * read the information of the vehicle 296 * 297 * @param aSysElem 298 * A pointer to "system" XML element. 299 */ 300 void readSystemInfo(const tinyxml2::XMLElement* const aSysElem); 301 302 /* 303 * read the information of camera devices 304 * 305 * @param aCameraElem 306 * A pointer to "camera" XML element that may contain multiple 307 * "device" elements. 308 */ 309 void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem); 310 311 /* 312 * read display device information 313 * 314 * @param aDisplayElem 315 * A pointer to "display" XML element that may contain multiple 316 * "device" elements. 317 */ 318 void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem); 319 320 /* 321 * read camera device information 322 * 323 * @param aCamera 324 * A pointer to CameraInfo that will be completed by this 325 * method. 326 * aDeviceElem 327 * A pointer to "device" XML element that contains camera module 328 * capability info and its characteristics. 329 * 330 * @return bool 331 * Return false upon any failure in reading and processing camera 332 * device information. 333 */ 334 bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem); 335 336 /* 337 * read camera metadata 338 * 339 * @param aCapElem 340 * A pointer to "cap" XML element. 341 * @param aCamera 342 * A pointer to CameraInfo that is being filled by this method. 343 * @param dataSize 344 * Required size of memory to store camera metadata found in this 345 * method. This is calculated in this method and returned to the 346 * caller for camera_metadata allocation. 347 * 348 * @return size_t 349 * Number of camera metadata entries 350 */ 351 size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera, 352 size_t& dataSize); 353 354 /* 355 * read camera metadata 356 * 357 * @param aParamElem 358 * A pointer to "characteristics" XML element. 359 * @param aCamera 360 * A pointer to CameraInfo that is being filled by this method. 361 * @param dataSize 362 * Required size of memory to store camera metadata found in this 363 * method. 364 * 365 * @return size_t 366 * Number of camera metadata entries 367 */ 368 size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera, 369 size_t& dataSize); 370 371 /* 372 * construct camera_metadata_t from camera capabilities and metadata 373 * 374 * @param aCamera 375 * A pointer to CameraInfo that is being filled by this method. 376 * @param totalEntries 377 * Number of camera metadata entries to be added. 378 * @param totalDataSize 379 * Sum of sizes of camera metadata entries to be added. 380 * 381 * @return bool 382 * False if either it fails to allocate memory for camera metadata 383 * or its size is not large enough to add all found camera metadata 384 * entries. 385 */ 386 bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries, 387 const size_t totalDataSize); 388 389 /* 390 * Read configuration data from the binary file 391 * 392 * @return bool 393 * True if it succeeds to read configuration data from a binary 394 * file. 395 */ 396 bool readConfigDataFromBinary(); 397 398 /* 399 * Store configuration data to the file 400 * 401 * @return bool 402 * True if it succeeds to serialize mCameraInfo to the file. 403 */ 404 bool writeConfigDataToBinary(); 405 406 /* 407 * debugging method to print out all XML elements and their attributes in 408 * logcat message. 409 * 410 * @param aNode 411 * A pointer to the root XML element to navigate. 412 * @param prefix 413 * A prefix to XML string. 414 */ 415 void printElementNames(const tinyxml2::XMLElement* aNode, const std::string& prefix = "") const; 416 }; 417