blob: b37933ce7eb74237760f6108a5c23f9878d61a9e [file] [log] [blame]
Avichal Rakeshe1857f82022-06-08 17:47:23 -07001/*
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
32using ::aidl::android::hardware::camera::common::Status;
33using ::aidl::android::hardware::camera::device::CaptureResult;
34using ::aidl::android::hardware::camera::device::ErrorCode;
35using ::aidl::android::hardware::camera::device::NotifyMsg;
36using ::aidl::android::hardware::graphics::common::BufferUsage;
37using ::aidl::android::hardware::graphics::common::PixelFormat;
38using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
39using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
Avichal Rakeshe1857f82022-06-08 17:47:23 -070040
41namespace android {
42namespace hardware {
43namespace camera {
44
45namespace external {
46namespace common {
47
48struct 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
57struct SizeHasher {
58 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
66struct 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
112namespace device {
113namespace implementation {
114
115struct 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
132struct 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
146class 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.
169class 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
186enum 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)
191const float kMaxAspectRatio = std::numeric_limits<float>::max();
192const float kMinAspectRatio = 1.f;
193
194bool isAspectRatioClose(float ar1, float ar2);
195
196struct 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
208struct 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
216static 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
224typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
225
226aidl::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
232static 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
237uint32_t getFourCcFromLayout(const YCbCrLayout&);
238
239using ::android::hardware::camera::external::common::Size;
240int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
241
242int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format);
243
244int 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
248Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata&);
249
250void freeReleaseFences(std::vector<CaptureResult>&);
251
252status_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
256struct OutputThreadInterface {
257 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
272 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.
284class 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_