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