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