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