• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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