blob: d434905bd822e533560beaf0a84300091cbaf827 [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>
Devin Moore523660c2023-10-02 15:55:11 +000028#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>
Avichal Rakeshe1857f82022-06-08 17:47:23 -070031#include <tinyxml2.h>
Devin Moore523660c2023-10-02 15:55:11 +000032#include <map>
Avichal Rakeshe1857f82022-06-08 17:47:23 -070033#include <unordered_map>
34#include <unordered_set>
35
36using ::aidl::android::hardware::camera::common::Status;
37using ::aidl::android::hardware::camera::device::CaptureResult;
38using ::aidl::android::hardware::camera::device::ErrorCode;
39using ::aidl::android::hardware::camera::device::NotifyMsg;
40using ::aidl::android::hardware::graphics::common::BufferUsage;
41using ::aidl::android::hardware::graphics::common::PixelFormat;
42using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
43using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
Devin Moore523660c2023-10-02 15:55:11 +000044using ::android::hardware::graphics::mapper::V2_0::IMapper;
45using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
Avichal Rakeshe1857f82022-06-08 17:47:23 -070046
47namespace android {
48namespace hardware {
49namespace camera {
50
51namespace external {
52namespace common {
53
54struct 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
63struct SizeHasher {
64 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
72struct 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
118namespace device {
119namespace implementation {
120
121struct 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
138struct 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
152class 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.
175class 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
192enum 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)
197const float kMaxAspectRatio = std::numeric_limits<float>::max();
198const float kMinAspectRatio = 1.f;
199
200bool isAspectRatioClose(float ar1, float ar2);
201
202struct 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
214struct 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
222static 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
230typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
231
232aidl::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
238static 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
243uint32_t getFourCcFromLayout(const YCbCrLayout&);
244
245using ::android::hardware::camera::external::common::Size;
246int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
247
248int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format);
249
250int 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
254Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata&);
255
256void freeReleaseFences(std::vector<CaptureResult>&);
257
258status_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
262struct OutputThreadInterface {
263 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
278 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.
290class 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_