1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "avbuffer_queue_consumer_impl.h"
17 #include "avbuffer_queue_producer_impl.h"
18 #include "common/log.h"
19
20
21 namespace OHOS {
22 namespace Media {
23
AVBufferQueueSurfaceWrapper(sptr<Surface> & surface,const std::string & name,uint8_t wrapperType)24 AVBufferQueueSurfaceWrapper::AVBufferQueueSurfaceWrapper(
25 sptr<Surface> &surface, const std::string &name, uint8_t wrapperType)
26 : AVBufferQueueImpl(surface->GetQueueSize(), MemoryType::UNKNOWN_MEMORY, name),
27 surface_(surface), wrapperType_(wrapperType)
28 {
29 for (uint32_t i = 0; i < surface->GetQueueSize(); i++) {
30 auto buffer = AVBuffer::CreateAVBuffer();
31 cachedBufferMap_[buffer->GetUniqueId()] = buffer;
32 freeBufferList_.emplace_back(buffer->GetUniqueId());
33 }
34 }
35
GetProducer()36 sptr<AVBufferQueueProducer> AVBufferQueueSurfaceWrapper::GetProducer()
37 {
38 return AVBufferQueueImpl::GetProducer();
39 }
40
GetConsumer()41 sptr<AVBufferQueueConsumer> AVBufferQueueSurfaceWrapper::GetConsumer()
42 {
43 if (wrapperType_ == PRODUCER_WRAPPER) {
44 return nullptr;
45 }
46 return AVBufferQueueImpl::GetConsumer();
47 }
48
GetSurfaceAsProducer()49 sptr<Surface> AVBufferQueueSurfaceWrapper::GetSurfaceAsProducer()
50 {
51 if (wrapperType_ == PRODUCER_WRAPPER || wrapperType_ == BOTH_WRAPPER) {
52 return nullptr;
53 }
54 return surface_;
55 }
56
GetSurfaceAsConsumer()57 sptr<Surface> AVBufferQueueSurfaceWrapper::GetSurfaceAsConsumer()
58 {
59 if (wrapperType_ == CONSUMER_WRAPPER || wrapperType_ == BOTH_WRAPPER) {
60 return nullptr;
61 }
62 return surface_;
63 }
64
GetQueueSize()65 uint32_t AVBufferQueueSurfaceWrapper::GetQueueSize()
66 {
67 return surface_->GetQueueSize();
68 }
69
SetQueueSize(uint32_t size)70 Status AVBufferQueueSurfaceWrapper::SetQueueSize(uint32_t size)
71 {
72 NZERO_RETURN_V(surface_->SetQueueSize(size), Status::ERROR_SURFACE_INNER);
73
74 std::lock_guard<std::mutex> lockGuard(queueMutex_);
75
76 auto curSize = cachedBufferMap_.size();
77 if (size > curSize) {
78 for (auto i = curSize; i < size; ++i) {
79 auto buffer = AVBuffer::CreateAVBuffer();
80 cachedBufferMap_[buffer->GetUniqueId()] = buffer;
81 freeBufferList_.emplace_back(buffer->GetUniqueId());
82 }
83 }
84
85 return Status::OK;
86 }
87
BindSurface(std::shared_ptr<AVBuffer> & buffer,sptr<SurfaceBuffer> & surfaceBuffer,int32_t fence)88 Status AVBufferQueueSurfaceWrapper::BindSurface(
89 std::shared_ptr<AVBuffer>& buffer, sptr<SurfaceBuffer>& surfaceBuffer, int32_t fence)
90 {
91 std::lock_guard<std::mutex> lockGuard(queueMutex_);
92 if (freeBufferList_.empty()) {
93 MEDIA_LOG_W("cannot find free buffer, alloc new one");
94 buffer = AVBuffer::CreateAVBuffer();
95 cachedBufferMap_[buffer->GetUniqueId()] = buffer;
96 } else {
97 buffer = cachedBufferMap_[freeBufferList_.front()];
98 freeBufferList_.pop_front();
99 }
100 return Status::OK;
101 }
102
UnbindSurface(uint64_t uniqueId,sptr<SurfaceBuffer> & surfaceBuffer,int32_t & fence,BufferFlushConfig & config)103 Status AVBufferQueueSurfaceWrapper::UnbindSurface(uint64_t uniqueId, sptr<SurfaceBuffer>& surfaceBuffer, int32_t& fence,
104 BufferFlushConfig& config)
105 {
106 std::lock_guard<std::mutex> lockGuard(queueMutex_);
107 FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(), Status::ERROR_INVALID_BUFFER_ID);
108 freeBufferList_.emplace_back(uniqueId);
109
110 return Status::OK;
111 }
112
RequestBuffer(std::shared_ptr<AVBuffer> & buffer,const AVBufferConfig & config,int32_t timeoutMs)113 Status AVBufferQueueSurfaceWrapper::RequestBuffer(
114 std::shared_ptr<AVBuffer>& buffer, const AVBufferConfig& config, int32_t timeoutMs)
115 {
116 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
117 int32_t fence;
118 FALSE_RETURN_V(config.surfaceBufferConfig != nullptr, Status::ERROR_INVALID_PARAMETER);
119 BufferRequestConfig surfaceBufferConfig = *(config.surfaceBufferConfig);
120 NZERO_RETURN_V(surface_->RequestBuffer(surfaceBuffer, fence, surfaceBufferConfig),
121 Status::ERROR_SURFACE_INNER);
122
123 return BindSurface(buffer, surfaceBuffer, fence);
124 }
125
CancelBuffer(uint64_t uniqueId)126 Status AVBufferQueueSurfaceWrapper::CancelBuffer(uint64_t uniqueId)
127 {
128 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
129 int32_t fence;
130 BufferFlushConfig config;
131 return UnbindSurface(uniqueId, surfaceBuffer, fence, config);
132 }
133
PushBuffer(uint64_t uniqueId,bool available)134 Status AVBufferQueueSurfaceWrapper::PushBuffer(uint64_t uniqueId, bool available)
135 {
136 if (brokerListener_ != nullptr) {
137 std::lock_guard<std::mutex> lockGuard(brokerListenerMutex_);
138 if (brokerListener_ != nullptr) {
139 brokerListener_->OnBufferFilled(cachedBufferMap_[uniqueId]);
140 return Status::OK;
141 }
142 }
143
144 return ReturnBuffer(uniqueId, available);
145 }
146
PushBuffer(const std::shared_ptr<AVBuffer> & buffer,bool available)147 Status AVBufferQueueSurfaceWrapper::PushBuffer(const std::shared_ptr<AVBuffer>& buffer, bool available)
148 {
149 FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
150
151 return PushBuffer(buffer->GetUniqueId(), available);
152 }
153
ReturnBuffer(uint64_t uniqueId,bool available)154 Status AVBufferQueueSurfaceWrapper::ReturnBuffer(uint64_t uniqueId, bool available)
155 {
156 if (!available) {
157 return CancelBuffer(uniqueId);
158 }
159
160 int32_t fence;
161 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
162 BufferFlushConfig config;
163 NOK_RETURN(UnbindSurface(uniqueId, surfaceBuffer, fence, config));
164
165 NZERO_RETURN_V(surface_->FlushBuffer(surfaceBuffer, fence, config), Status::ERROR_SURFACE_INNER);
166
167 return Status::OK;
168 }
169
ReturnBuffer(const std::shared_ptr<AVBuffer> & buffer,bool available)170 Status AVBufferQueueSurfaceWrapper::ReturnBuffer(const std::shared_ptr<AVBuffer>& buffer, bool available)
171 {
172 FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
173 return ReturnBuffer(buffer->GetUniqueId(), available);
174 }
175
AttachBuffer(std::shared_ptr<AVBuffer> & buffer,bool isFilled)176 Status AVBufferQueueSurfaceWrapper::AttachBuffer(std::shared_ptr<AVBuffer>& buffer, bool isFilled)
177 {
178 FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
179 FALSE_RETURN_V(!isFilled, Status::ERROR_INVALID_PARAMETER);
180 return Status::OK;
181 }
182
DetachBuffer(uint64_t uniqueId)183 Status AVBufferQueueSurfaceWrapper::DetachBuffer(uint64_t uniqueId)
184 {
185 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
186 int32_t fence;
187 BufferFlushConfig config;
188 NOK_RETURN(UnbindSurface(uniqueId, surfaceBuffer, fence, config));
189
190 NZERO_RETURN_V(surface_->DetachBuffer(surfaceBuffer), Status::ERROR_SURFACE_INNER);
191
192 return Status::OK;
193 }
194
DetachBuffer(const std::shared_ptr<AVBuffer> & buffer)195 Status AVBufferQueueSurfaceWrapper::DetachBuffer(const std::shared_ptr<AVBuffer>& buffer)
196 {
197 FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
198
199 NOK_RETURN(DetachBuffer(buffer->GetUniqueId()));
200
201 return Status::OK;
202 }
203
AcquireBuffer(std::shared_ptr<AVBuffer> & buffer)204 Status AVBufferQueueSurfaceWrapper::AcquireBuffer(std::shared_ptr<AVBuffer>& buffer)
205 {
206 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
207 int32_t fence;
208 int64_t timestamp;
209 Rect range;
210 NZERO_RETURN_V(surface_->AcquireBuffer(surfaceBuffer, fence, timestamp, range),
211 Status::ERROR_SURFACE_INNER);
212
213 NOK_RETURN(BindSurface(buffer, surfaceBuffer, fence));
214
215 return Status::OK;
216 }
217
ReleaseBuffer(uint64_t uniqueId)218 Status AVBufferQueueSurfaceWrapper::ReleaseBuffer(uint64_t uniqueId)
219 {
220 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
221 int32_t fence;
222 BufferFlushConfig config;
223 NOK_RETURN(UnbindSurface(uniqueId, surfaceBuffer, fence, config));
224 NZERO_RETURN_V(surface_->ReleaseBuffer(surfaceBuffer, fence), Status::ERROR_SURFACE_INNER);
225 return Status::OK;
226 }
227
ReleaseBuffer(const std::shared_ptr<AVBuffer> & buffer)228 Status AVBufferQueueSurfaceWrapper::ReleaseBuffer(const std::shared_ptr<AVBuffer>& buffer)
229 {
230 FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
231 return ReleaseBuffer(buffer->GetUniqueId());
232 }
233
SetBrokerListener(sptr<IBrokerListener> & listener)234 Status AVBufferQueueSurfaceWrapper::SetBrokerListener(sptr<IBrokerListener>& listener)
235 {
236 std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
237 brokerListener_ = listener;
238 return Status::OK;
239 }
240
SetProducerListener(sptr<IProducerListener> & listener)241 Status AVBufferQueueSurfaceWrapper::SetProducerListener(sptr<IProducerListener>& listener)
242 {
243 std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
244 producerListener_ = listener;
245 return Status::OK;
246 }
247
248 class SurfaceConsumerListener : public IBufferConsumerListener {
249 public:
SurfaceConsumerListener(std::function<void ()> releaseBufferFunc)250 explicit SurfaceConsumerListener(std::function<void()> releaseBufferFunc)
251 : onReleaseBufferFunc_(std::move(releaseBufferFunc)) {}
252
OnBufferAvailable()253 void OnBufferAvailable() override { onReleaseBufferFunc_(); }
254
255 private:
256 std::function<void(void)> onReleaseBufferFunc_;
257 };
258
SetConsumerListener(sptr<IConsumerListener> & listener)259 Status AVBufferQueueSurfaceWrapper::SetConsumerListener(sptr<IConsumerListener>& listener)
260 {
261 auto releaseBufferFunc = [this]()->void {
262 std::lock_guard<std::mutex> lockGuard(consumerListenerMutex_);
263 if (consumerListener_ != nullptr) {
264 consumerListener_->OnBufferAvailable();
265 }
266 };
267
268 std::lock_guard<std::mutex> lockGuard(consumerListenerMutex_);
269 if (listener == nullptr) {
270 surfaceConsumerListener_ = nullptr;
271 surface_->RegisterConsumerListener(nullptr);
272 } else {
273 surfaceConsumerListener_ = new SurfaceConsumerListener(releaseBufferFunc);
274 surface_->RegisterConsumerListener(surfaceConsumerListener_);
275 }
276
277 consumerListener_ = listener;
278
279 return Status::OK;
280 }
281
282 }
283 }