1 /*
2  * Copyright (C) 2023 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 /*
18  *  Manage the producer and consumer buffers needed by FrameProviders.
19  */
20 #pragma once
21 
22 #include <Utils.h>
23 #include <linux/videodev2.h>
24 #include <condition_variable>
25 #include <map>
26 #include <mutex>
27 #include <queue>
28 #include <variant>
29 #include <vector>
30 
31 namespace android {
32 namespace webcam {
33 
34 enum BufferType {
35     V4L2 = 0,
36 };
37 
38 struct YuvHardwareBufferDesc {
39     uint8_t* yData = nullptr;
40     uint32_t yDataLength = 0;
41     uint32_t yRowStride = 0;
42 
43     uint8_t* uData = nullptr;
44     uint32_t uDataLength = 0;
45     uint32_t uRowStride = 0;
46 
47     uint8_t* vData = nullptr;
48     uint32_t vDataLength = 0;
49     uint32_t vRowStride = 0;
50 
51     uint32_t uvPixelStride = 0;
52 };
53 
54 struct ARGBHardwareBufferDesc {
55     uint8_t *buf = nullptr;
56     uint32_t rowStride = 0;
57 };
58 
59 struct HardwareBufferDesc {
60     uint32_t width = 0;
61     uint32_t height = 0;
62     uint32_t format = 0;
63     uint32_t bufferId = 0;
64     std::variant<ARGBHardwareBufferDesc, YuvHardwareBufferDesc> bufferDesc;
65 };
66 
67 class BufferManager;
68 
69 // Base class for Buffer, for future types apart from V4L2
70 // Thin wrapper over struct v4l2_buffer. The client should not free the memory obtained from
71 // getMem(). All Buffers are created by BufferManager through BufferCreatorAndDestroyer which is
72 // transport specific.
73 // TODO(b/267794640): Change Buffer to have either a std::shared_ptr to BufferManager or have
74 //                    BufferManager be a singleton. BufferManager should implement
75 //                    counting 'handout' buffers before freeing. BufferManager should explicitly
76 //                    check that there are no Buffers alive before freeing the handed out buffers.
77 //                    This will also ensure that the lifetime of BufferManager >= lifetime of
78 //                    Buffer.
79 class Buffer {
80   public:
81     Buffer() = default;
82     virtual BufferType getBufferType() = 0;
83     [[nodiscard]] virtual void* getMem() = 0;
84     [[nodiscard]] virtual size_t getLength() const = 0;
85     virtual void setBytesUsed(uint32_t bytesUsed) = 0;
86     virtual ~Buffer() = default;
87 
setTimestamp(uint64_t ts)88     void setTimestamp(uint64_t ts) { mTimestamp = ts; }
89 
getTimestamp()90     [[nodiscard]] uint64_t getTimestamp() const { return mTimestamp; }
91     [[nodiscard]] virtual uint32_t getIndex() const = 0;
92 
93     friend class BufferManager;
94 
95   private:
96     uint64_t mTimestamp = 0;
97 };
98 
99 class V4L2Buffer : public Buffer {
100   public:
V4L2Buffer(void * mem,const struct v4l2_buffer * buffer)101     V4L2Buffer(void* mem, const struct v4l2_buffer* buffer) : mMem(mem), mBuffer(*buffer) {}
V4L2Buffer()102     V4L2Buffer() { memset(&mBuffer, 0, sizeof(mBuffer)); }
103     ~V4L2Buffer() override = default;
104 
getBufferType()105     BufferType getBufferType() override { return BufferType::V4L2; }
106 
107     // Memory will be freed by BufferManager. Do not free.
getMem()108     [[nodiscard]] void* getMem() override { return mMem; }
109 
getLength()110     [[nodiscard]] size_t getLength() const override { return mBuffer.length; }
111 
setBytesUsed(uint32_t bytesUsed)112     void setBytesUsed(uint32_t bytesUsed) override { mBuffer.bytesused = bytesUsed; }
113 
getV4L2Buffer()114     struct v4l2_buffer* getV4L2Buffer() {
115         return &mBuffer;
116     }
117 
getIndex()118     [[nodiscard]] uint32_t getIndex() const override { return mBuffer.index; }
119 
120   private:
121     void* mMem = nullptr;
122     struct v4l2_buffer mBuffer {};
123 };
124 
125 class BufferProducer {
126   public:
127     // Returns a free buffer if it is available. This method does not wait for a free
128     // buffer. Buffer is owned by BufferProducer. Caller should not manage the lifetime of the
129     // object and should ensure that all buffer references are dropped when BufferProducer goes out
130     // of scope.
131     virtual Buffer* getFreeBufferIfAvailable() = 0;
132 
133     // Queues a filled buffer to the BufferManager.
134     virtual Status queueFilledBuffer(Buffer* buffer) = 0;
135 
136     // Cancels a queued Buffer
137     virtual Status cancelBuffer(Buffer* buffer) = 0;
138     virtual ~BufferProducer() = default;
139 };
140 
141 class BufferConsumer {
142   public:
143     // Gets a filled buffer from BufferManager (waits if one is not available) and returns the
144     // consumer side buffer for the BufferManager to give away to the producer to use.
145     // Buffer is owned by BufferConsumer. Caller should not manage the lifetime of the object.
146     virtual Buffer* getFilledBufferAndSwap() = 0;
147     virtual ~BufferConsumer() = default;
148 };
149 
150 class BufferCreatorAndDestroyer {
151   public:
152     virtual ~BufferCreatorAndDestroyer() = default;
153     virtual Status allocateAndMapBuffers(std::shared_ptr<Buffer>* consumerBuffer,
154                                          std::vector<std::shared_ptr<Buffer>>* producerBuffer) = 0;
155     virtual void destroyBuffers(std::shared_ptr<Buffer>& consumerBuffer,
156                                 std::vector<std::shared_ptr<Buffer>>& producerBuffers) = 0;
157 };
158 
159 class BufferManager : public BufferConsumer, public BufferProducer {
160     // There are 2 types of buffers : the consumer side buffer and the producer side buffers.
161     // The consumer side needs only 1.
162     // The producer side is typically some component which fills in frames such as a FrameProvider
163     // class instance.
164     // The consumer side is typically some component that fetches filled buffers and sends them over
165     // some transport method to the host.
166 
167   public:
168     // TODO(b/267794640): Look into better memory management
169     // BufferCreatorAndDestroyer is owned by the caller, it must be active throughout the lifetime
170     // of BufferManager
171     explicit BufferManager(BufferCreatorAndDestroyer* crD);
172     ~BufferManager() override;
isInited()173     [[nodiscard]] bool isInited() const { return mInited; }
174     Buffer* getFreeBufferIfAvailable() override;
175     Status queueFilledBuffer(Buffer* buffer) override;
176     Status cancelBuffer(Buffer* buffer) override;
177     Buffer* getFilledBufferAndSwap() override;
178 
179   private:
180     enum BufferState {
181         IN_USE = 0,
182         FILLED = 1,
183         FREE = 2,
184     };
185 
186     struct BufferItem {
BufferItemBufferItem187         BufferItem() : buffer(nullptr), state(BufferState::FREE) {}
BufferItemBufferItem188         BufferItem(std::shared_ptr<Buffer>& buf, BufferState st) : buffer(buf), state(st) {}
189         std::shared_ptr<Buffer> buffer;
190         BufferState state = BufferState::FREE;
191     };
192 
193     // Checks if a filled buffer has been made available by the producer and gets the vector index,
194     // of the latest filled buffer. Cancels buffers older than the one referenced by index.
195     bool filledProducerBufferAvailableLocked(uint32_t* index);
196     bool changeProducerBufferStateLocked(Buffer* buffer, BufferState newState);
197 
198     bool mInited = false;
199     BufferCreatorAndDestroyer* mCrD = nullptr;
200 
201     std::mutex mBufferLock;  // guards all operations relating to Buffer and BufferItems
202     std::condition_variable mProducerBufferFilled;  // guarded by mBufferLock
203     BufferItem mConsumerBufferItem;                 // guarded by mBufferLock
204     // Using a simple vector here as we don't expect to have more than 3-4 buffers in circulation
205     // We have multiple producer buffers so that skews between other producers being used by the
206     // producer side - eg: buffer from camera doesn't get blocked from getting encoded while
207     // consumer is still consuming the consumer side buffer (this could happen if we had only 1
208     // producer buffer and 1 consumer buffer and there's a skew between camera frame production and
209     // consumer (UVC gadget driver etc) frame consumption.
210     std::vector<BufferItem> mProducerBufferItems;  // guarded by mBufferLock
211 };
212 
213 }  // namespace webcam
214 }  // namespace android
215