1 /* 2 * Copyright (C) 2022 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 #ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_ 18 #define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_ 19 20 #include <CameraMetadata.h> 21 #include <HandleImporter.h> 22 #include <aidl/android/hardware/camera/common/Status.h> 23 #include <aidl/android/hardware/camera/device/CaptureResult.h> 24 #include <aidl/android/hardware/camera/device/ErrorCode.h> 25 #include <aidl/android/hardware/camera/device/NotifyMsg.h> 26 #include <aidl/android/hardware/graphics/common/BufferUsage.h> 27 #include <aidl/android/hardware/graphics/common/PixelFormat.h> 28 #include <android/hardware/graphics/mapper/2.0/IMapper.h> 29 #include <android/hardware/graphics/mapper/3.0/IMapper.h> 30 #include <android/hardware/graphics/mapper/4.0/IMapper.h> 31 #include <tinyxml2.h> 32 #include <map> 33 #include <unordered_map> 34 #include <unordered_set> 35 36 using ::aidl::android::hardware::camera::common::Status; 37 using ::aidl::android::hardware::camera::device::CaptureResult; 38 using ::aidl::android::hardware::camera::device::ErrorCode; 39 using ::aidl::android::hardware::camera::device::NotifyMsg; 40 using ::aidl::android::hardware::graphics::common::BufferUsage; 41 using ::aidl::android::hardware::graphics::common::PixelFormat; 42 using ::android::hardware::camera::common::V1_0::helper::CameraMetadata; 43 using ::android::hardware::camera::common::V1_0::helper::HandleImporter; 44 using ::android::hardware::graphics::mapper::V2_0::IMapper; 45 using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout; 46 47 namespace android { 48 namespace hardware { 49 namespace camera { 50 51 namespace external { 52 namespace common { 53 54 struct Size { 55 int32_t width; 56 int32_t height; 57 58 bool operator==(const Size& other) const { 59 return (width == other.width && height == other.height); 60 } 61 }; 62 63 struct SizeHasher { operatorSizeHasher64 size_t operator()(const Size& sz) const { 65 size_t result = 1; 66 result = 31 * result + sz.width; 67 result = 31 * result + sz.height; 68 return result; 69 } 70 }; 71 72 struct ExternalCameraConfig { 73 static const char* kDefaultCfgPath; 74 static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath); 75 76 // CameraId base offset for numerical representation 77 uint32_t cameraIdOffset; 78 79 // List of internal V4L2 video nodes external camera HAL must ignore. 80 std::unordered_set<std::string> mInternalDevices; 81 82 // Maximal size of a JPEG buffer, in bytes 83 int32_t maxJpegBufSize; 84 85 // Maximum Size that can sustain 30fps streaming 86 Size maxVideoSize; 87 88 // Size of v4l2 buffer queue when streaming <= kMaxVideoSize 89 uint32_t numVideoBuffers; 90 91 // Size of v4l2 buffer queue when streaming > kMaxVideoSize 92 uint32_t numStillBuffers; 93 94 // Indication that the device connected supports depth output 95 bool depthEnabled; 96 97 struct FpsLimitation { 98 Size size; 99 double fpsUpperBound; 100 }; 101 std::vector<FpsLimitation> fpsLimits; 102 std::vector<FpsLimitation> depthFpsLimits; 103 104 // Minimum output stream size 105 Size minStreamSize; 106 107 // The value of android.sensor.orientation 108 int32_t orientation; 109 110 private: 111 ExternalCameraConfig(); 112 static bool updateFpsList(tinyxml2::XMLElement* fpsList, std::vector<FpsLimitation>& fpsLimits); 113 }; 114 115 } // namespace common 116 } // namespace external 117 118 namespace device { 119 namespace implementation { 120 121 struct SupportedV4L2Format { 122 int32_t width; 123 int32_t height; 124 uint32_t fourcc; 125 // All supported frame rate for this w/h/fourcc combination 126 struct FrameRate { 127 // Duration (in seconds) of a single frame. 128 // Numerator and denominator of the frame duration are stored separately. 129 // For ex. a frame lasting 1/30 of a second will be stored as {1, 30} 130 uint32_t durationNumerator; // frame duration numerator. Ex: 1 131 uint32_t durationDenominator; // frame duration denominator. Ex: 30 132 double getFramesPerSecond() const; // FPS as double. Ex: 30.0 133 }; 134 std::vector<FrameRate> frameRates; 135 }; 136 137 // A Base class with basic information about a frame 138 struct Frame : public std::enable_shared_from_this<Frame> { 139 public: 140 Frame(uint32_t width, uint32_t height, uint32_t fourcc); 141 virtual ~Frame(); 142 const int32_t mWidth; 143 const int32_t mHeight; 144 const uint32_t mFourcc; 145 146 // getData might involve map/allocation 147 virtual int getData(uint8_t** outData, size_t* dataSize) = 0; 148 }; 149 150 // A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format) 151 // Also contains necessary information to enqueue the buffer back to V4L2 buffer queue 152 class V4L2Frame : public Frame { 153 public: 154 V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize, 155 uint64_t offset); 156 virtual ~V4L2Frame(); 157 158 virtual int getData(uint8_t** outData, size_t* dataSize) override; 159 160 const int mBufferIndex; // for later enqueue 161 int map(uint8_t** data, size_t* dataSize); 162 int unmap(); 163 164 private: 165 std::mutex mLock; 166 const int mFd; // used for mmap but doesn't claim ownership 167 const size_t mDataSize; 168 const uint64_t mOffset; // used for mmap 169 uint8_t* mData = nullptr; 170 bool mMapped = false; 171 }; 172 173 // A RAII class representing a CPU allocated YUV frame used as intermediate buffers 174 // when generating output images. 175 class AllocatedFrame : public Frame { 176 public: 177 AllocatedFrame(uint32_t w, uint32_t h); // only support V4L2_PIX_FMT_YUV420 for now 178 ~AllocatedFrame() override; 179 180 virtual int getData(uint8_t** outData, size_t* dataSize) override; 181 182 int allocate(YCbCrLayout* out = nullptr); 183 int getLayout(YCbCrLayout* out); 184 int getCroppedLayout(const IMapper::Rect&, YCbCrLayout* out); // return non-zero for bad input 185 private: 186 std::mutex mLock; 187 std::vector<uint8_t> mData; 188 size_t mBufferSize; // size of mData before padding. Actual size of mData might be slightly 189 // bigger to horizontally pad the frame for jpeglib. 190 }; 191 192 enum CroppingType { HORIZONTAL = 0, VERTICAL = 1 }; 193 194 // Aspect ratio is defined as width/height here and ExternalCameraDevice 195 // will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0) 196 #define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height) 197 const float kMaxAspectRatio = std::numeric_limits<float>::max(); 198 const float kMinAspectRatio = 1.f; 199 200 bool isAspectRatioClose(float ar1, float ar2); 201 202 struct HalStreamBuffer { 203 int32_t streamId; 204 int64_t bufferId; 205 int32_t width; 206 int32_t height; 207 ::aidl::android::hardware::graphics::common::PixelFormat format; 208 ::aidl::android::hardware::graphics::common::BufferUsage usage; 209 buffer_handle_t* bufPtr; 210 int acquireFence; 211 bool fenceTimeout; 212 }; 213 214 struct HalRequest { 215 int32_t frameNumber; 216 common::V1_0::helper::CameraMetadata setting; 217 std::shared_ptr<Frame> frameIn; 218 nsecs_t shutterTs; 219 std::vector<HalStreamBuffer> buffers; 220 }; 221 222 static const uint64_t BUFFER_ID_NO_BUFFER = 0; 223 224 // buffers currently circulating between HAL and camera service 225 // key: bufferId sent via HIDL interface 226 // value: imported buffer_handle_t 227 // Buffer will be imported during processCaptureRequest (or requestStreamBuffer 228 // in the case of HAL buffer manager is enabled) and will be freed 229 // when the stream is deleted or camera device session is closed 230 typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers; 231 232 aidl::android::hardware::camera::common::Status importBufferImpl( 233 /*inout*/ std::map<int, CirculatingBuffers>& circulatingBuffers, 234 /*inout*/ HandleImporter& handleImporter, int32_t streamId, uint64_t bufId, 235 buffer_handle_t buf, 236 /*out*/ buffer_handle_t** outBufPtr); 237 238 static const uint32_t FLEX_YUV_GENERIC = 239 static_cast<uint32_t>('F') | static_cast<uint32_t>('L') << 8 | 240 static_cast<uint32_t>('E') << 16 | static_cast<uint32_t>('X') << 24; 241 242 // returns FLEX_YUV_GENERIC for formats other than YV12/YU12/NV12/NV21 243 uint32_t getFourCcFromLayout(const YCbCrLayout&); 244 245 using ::android::hardware::camera::external::common::Size; 246 int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out); 247 248 int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format); 249 250 int encodeJpegYU12(const Size& inSz, const YCbCrLayout& inLayout, int jpegQuality, 251 const void* app1Buffer, size_t app1Size, void* out, size_t maxOutSize, 252 size_t& actualCodeSize); 253 254 Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata&); 255 256 void freeReleaseFences(std::vector<CaptureResult>&); 257 258 status_t fillCaptureResultCommon(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp, 259 camera_metadata_ro_entry& activeArraySize); 260 261 // Interface for OutputThread calling back to parent 262 struct OutputThreadInterface { ~OutputThreadInterfaceOutputThreadInterface263 virtual ~OutputThreadInterface() {} 264 virtual aidl::android::hardware::camera::common::Status importBuffer( 265 int32_t streamId, uint64_t bufId, buffer_handle_t buf, 266 /*out*/ buffer_handle_t** outBufPtr) = 0; 267 268 virtual void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) = 0; 269 270 // Callbacks are fired within the method if msgs/results are nullptr. 271 // Otherwise the callbacks will be returned and caller is responsible to 272 // fire the callback later 273 virtual aidl::android::hardware::camera::common::Status processCaptureRequestError( 274 const std::shared_ptr<HalRequest>&, 275 /*out*/ std::vector<NotifyMsg>* msgs, 276 /*out*/ std::vector<CaptureResult>* results) = 0; 277 processCaptureRequestErrorOutputThreadInterface278 virtual aidl::android::hardware::camera::common::Status processCaptureRequestError( 279 const std::shared_ptr<HalRequest>& reqs) final { 280 return processCaptureRequestError(reqs, nullptr, nullptr); 281 } 282 283 virtual aidl::android::hardware::camera::common::Status processCaptureResult( 284 std::shared_ptr<HalRequest>&) = 0; 285 286 virtual ssize_t getJpegBufferSize(int32_t width, int32_t height) const = 0; 287 }; 288 289 // A CPU copy of a mapped V4L2Frame. Will map the input V4L2 frame. 290 class AllocatedV4L2Frame : public Frame { 291 public: 292 AllocatedV4L2Frame(std::shared_ptr<V4L2Frame> frameIn); 293 ~AllocatedV4L2Frame() override; 294 virtual int getData(uint8_t** outData, size_t* dataSize) override; 295 296 private: 297 std::vector<uint8_t> mData; 298 }; 299 300 } // namespace implementation 301 } // namespace device 302 } // namespace camera 303 } // namespace hardware 304 } // namespace android 305 306 #endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_ 307