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 <inttypes.h>
21 #include "utils/LightRefBase.h"
22 #include <mutex>
23 #include <vector>
24 #include <unordered_set>
25 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
26 
27 using android::hardware::graphics::mapper::V2_0::IMapper;
28 using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
29 
30 namespace android {
31 namespace hardware {
32 namespace camera {
33 
34 namespace external {
35 namespace common {
36 
37 struct Size {
38     uint32_t width;
39     uint32_t height;
40 
41     bool operator==(const Size& other) const {
42         return (width == other.width && height == other.height);
43     }
44 };
45 
46 struct SizeHasher {
operatorSizeHasher47     size_t operator()(const Size& sz) const {
48         size_t result = 1;
49         result = 31 * result + sz.width;
50         result = 31 * result + sz.height;
51         return result;
52     }
53 };
54 
55 struct ExternalCameraConfig {
56     static const char* kDefaultCfgPath;
57     static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
58 
59     // List of internal V4L2 video nodes external camera HAL must ignore.
60     std::unordered_set<std::string> mInternalDevices;
61 
62     // Maximal size of a JPEG buffer, in bytes
63     uint32_t maxJpegBufSize;
64 
65     // Maximum Size that can sustain 30fps streaming
66     Size maxVideoSize;
67 
68     // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
69     uint32_t numVideoBuffers;
70 
71     // Size of v4l2 buffer queue when streaming > kMaxVideoSize
72     uint32_t numStillBuffers;
73 
74     struct FpsLimitation {
75         Size size;
76         double fpsUpperBound;
77     };
78     std::vector<FpsLimitation> fpsLimits;
79 
80 private:
81     ExternalCameraConfig();
82 };
83 
84 } // common
85 } // external
86 
87 namespace device {
88 namespace V3_4 {
89 namespace implementation {
90 
91 struct SupportedV4L2Format {
92     uint32_t width;
93     uint32_t height;
94     uint32_t fourcc;
95     // All supported frame rate for this w/h/fourcc combination
96     struct FrameRate {
97         uint32_t durationNumerator;   // frame duration numerator.   Ex: 1
98         uint32_t durationDenominator; // frame duration denominator. Ex: 30
99         double getDouble() const;     // FrameRate in double.        Ex: 30.0
100     };
101     std::vector<FrameRate> frameRates;
102 };
103 
104 // A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)
105 // Also contains necessary information to enqueue the buffer back to V4L2 buffer queue
106 class V4L2Frame : public virtual VirtualLightRefBase {
107 public:
108     V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd,
109               uint32_t dataSize, uint64_t offset);
110     ~V4L2Frame() override;
111     const uint32_t mWidth;
112     const uint32_t mHeight;
113     const uint32_t mFourcc;
114     const int mBufferIndex; // for later enqueue
115     int map(uint8_t** data, size_t* dataSize);
116     int unmap();
117 private:
118     std::mutex mLock;
119     const int mFd; // used for mmap but doesn't claim ownership
120     const size_t mDataSize;
121     const uint64_t mOffset; // used for mmap
122     uint8_t* mData = nullptr;
123     bool  mMapped = false;
124 };
125 
126 // A RAII class representing a CPU allocated YUV frame used as intermeidate buffers
127 // when generating output images.
128 class AllocatedFrame : public virtual VirtualLightRefBase {
129 public:
130     AllocatedFrame(uint32_t w, uint32_t h); // TODO: use Size?
131     ~AllocatedFrame() override;
132     const uint32_t mWidth;
133     const uint32_t mHeight;
134     const uint32_t mFourcc; // Only support YU12 format for now
135     int allocate(YCbCrLayout* out = nullptr);
136     int getLayout(YCbCrLayout* out);
137     int getCroppedLayout(const IMapper::Rect&, YCbCrLayout* out); // return non-zero for bad input
138 private:
139     std::mutex mLock;
140     std::vector<uint8_t> mData;
141 };
142 
143 enum CroppingType {
144     HORIZONTAL = 0,
145     VERTICAL = 1
146 };
147 
148 // Aspect ratio is defined as width/height here and ExternalCameraDevice
149 // will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0)
150 #define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height)
151 const float kMaxAspectRatio = std::numeric_limits<float>::max();
152 const float kMinAspectRatio = 1.f;
153 
154 bool isAspectRatioClose(float ar1, float ar2);
155 
156 }  // namespace implementation
157 }  // namespace V3_4
158 }  // namespace device
159 }  // namespace camera
160 }  // namespace hardware
161 }  // namespace android
162 
163 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_4_EXTCAMUTIL_H
164