1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci
16fa7767c5Sopenharmony_ci#include "avbuffer_queue_consumer_impl.h"
17fa7767c5Sopenharmony_ci#include "avbuffer_queue_impl.h"
18fa7767c5Sopenharmony_ci#include "avbuffer_queue_producer_impl.h"
19fa7767c5Sopenharmony_ci#include "common/log.h"
20fa7767c5Sopenharmony_ci#include "meta/media_types.h"
21fa7767c5Sopenharmony_ci
22fa7767c5Sopenharmony_cinamespace {
23fa7767c5Sopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "AVBufferQueue" };
24fa7767c5Sopenharmony_ci}
25fa7767c5Sopenharmony_ci
26fa7767c5Sopenharmony_cinamespace OHOS {
27fa7767c5Sopenharmony_cinamespace Media {
28fa7767c5Sopenharmony_ci
29fa7767c5Sopenharmony_cistd::shared_ptr<AVBufferQueue> AVBufferQueue::Create(
30fa7767c5Sopenharmony_ci    uint32_t size, MemoryType type, const std::string& name, bool disableAlloc)
31fa7767c5Sopenharmony_ci{
32fa7767c5Sopenharmony_ci    MEDIA_LOG_D("AVBufferQueue::Create size = %u, type = %u, name = %s",
33fa7767c5Sopenharmony_ci                size, static_cast<uint32_t>(type), name.c_str());
34fa7767c5Sopenharmony_ci    return std::make_shared<AVBufferQueueImpl>(size, type, name, disableAlloc);
35fa7767c5Sopenharmony_ci}
36fa7767c5Sopenharmony_ci
37fa7767c5Sopenharmony_cistd::shared_ptr<AVBufferQueueProducer> AVBufferQueueImpl::GetLocalProducer()
38fa7767c5Sopenharmony_ci{
39fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(producerCreatorMutex_);
40fa7767c5Sopenharmony_ci    std::shared_ptr<AVBufferQueueProducerImpl> producer = nullptr;
41fa7767c5Sopenharmony_ci    if (localProducer_.expired()) {
42fa7767c5Sopenharmony_ci        auto shared_this = shared_from_this();
43fa7767c5Sopenharmony_ci        FALSE_RETURN_V(shared_this != nullptr, nullptr);
44fa7767c5Sopenharmony_ci        producer = std::make_shared<AVBufferQueueProducerImpl>(shared_this);
45fa7767c5Sopenharmony_ci        localProducer_ = producer;
46fa7767c5Sopenharmony_ci    }
47fa7767c5Sopenharmony_ci
48fa7767c5Sopenharmony_ci    return localProducer_.lock();
49fa7767c5Sopenharmony_ci}
50fa7767c5Sopenharmony_ci
51fa7767c5Sopenharmony_cistd::shared_ptr<AVBufferQueueConsumer> AVBufferQueueImpl::GetLocalConsumer()
52fa7767c5Sopenharmony_ci{
53fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(consumerCreatorMutex_);
54fa7767c5Sopenharmony_ci    std::shared_ptr<AVBufferQueueConsumerImpl> consumer = nullptr;
55fa7767c5Sopenharmony_ci    if (localConsumer_.expired()) {
56fa7767c5Sopenharmony_ci        auto shared_this = shared_from_this();
57fa7767c5Sopenharmony_ci        FALSE_RETURN_V(shared_this != nullptr, nullptr);
58fa7767c5Sopenharmony_ci        consumer = std::make_shared<AVBufferQueueConsumerImpl>(shared_this);
59fa7767c5Sopenharmony_ci        localConsumer_ = consumer;
60fa7767c5Sopenharmony_ci    }
61fa7767c5Sopenharmony_ci    return localConsumer_.lock();
62fa7767c5Sopenharmony_ci}
63fa7767c5Sopenharmony_ci
64fa7767c5Sopenharmony_cisptr<AVBufferQueueProducer> AVBufferQueueImpl::GetProducer()
65fa7767c5Sopenharmony_ci{
66fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(producerCreatorMutex_);
67fa7767c5Sopenharmony_ci    sptr<AVBufferQueueProducerImpl> producer = nullptr;
68fa7767c5Sopenharmony_ci    if (producer_ == nullptr || producer_->GetSptrRefCount() <= 0) {
69fa7767c5Sopenharmony_ci        auto shared_this = shared_from_this();
70fa7767c5Sopenharmony_ci        FALSE_RETURN_V(shared_this != nullptr, nullptr);
71fa7767c5Sopenharmony_ci        producer = new AVBufferQueueProducerImpl(shared_this);
72fa7767c5Sopenharmony_ci        producer_ = producer;
73fa7767c5Sopenharmony_ci    }
74fa7767c5Sopenharmony_ci
75fa7767c5Sopenharmony_ci    return producer_.promote();
76fa7767c5Sopenharmony_ci}
77fa7767c5Sopenharmony_ci
78fa7767c5Sopenharmony_cisptr<AVBufferQueueConsumer> AVBufferQueueImpl::GetConsumer()
79fa7767c5Sopenharmony_ci{
80fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(consumerCreatorMutex_);
81fa7767c5Sopenharmony_ci    sptr<AVBufferQueueConsumerImpl> consumer = nullptr;
82fa7767c5Sopenharmony_ci    if (consumer_ == nullptr || consumer_->GetSptrRefCount() <= 0) {
83fa7767c5Sopenharmony_ci        auto shared_this = shared_from_this();
84fa7767c5Sopenharmony_ci        FALSE_RETURN_V(shared_this != nullptr, nullptr);
85fa7767c5Sopenharmony_ci        consumer = new AVBufferQueueConsumerImpl(shared_this);
86fa7767c5Sopenharmony_ci        consumer_ = consumer;
87fa7767c5Sopenharmony_ci    }
88fa7767c5Sopenharmony_ci
89fa7767c5Sopenharmony_ci    return consumer_.promote();
90fa7767c5Sopenharmony_ci}
91fa7767c5Sopenharmony_ci
92fa7767c5Sopenharmony_ciAVBufferQueueImpl::AVBufferQueueImpl(const std::string &name)
93fa7767c5Sopenharmony_ci    : AVBufferQueue(), name_(name), size_(0), memoryType_(MemoryType::UNKNOWN_MEMORY), disableAlloc_(false) {}
94fa7767c5Sopenharmony_ci
95fa7767c5Sopenharmony_ciAVBufferQueueImpl::AVBufferQueueImpl(uint32_t size, MemoryType type, const std::string &name, bool disableAlloc)
96fa7767c5Sopenharmony_ci    : AVBufferQueue(), name_(name), size_(size), memoryType_(type), disableAlloc_(disableAlloc)
97fa7767c5Sopenharmony_ci{
98fa7767c5Sopenharmony_ci    if (size_ > AVBUFFER_QUEUE_MAX_QUEUE_SIZE) {
99fa7767c5Sopenharmony_ci        size_ = AVBUFFER_QUEUE_MAX_QUEUE_SIZE;
100fa7767c5Sopenharmony_ci    }
101fa7767c5Sopenharmony_ci}
102fa7767c5Sopenharmony_ci
103fa7767c5Sopenharmony_ciuint32_t AVBufferQueueImpl::GetQueueSize()
104fa7767c5Sopenharmony_ci{
105fa7767c5Sopenharmony_ci    return size_;
106fa7767c5Sopenharmony_ci}
107fa7767c5Sopenharmony_ci
108fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::SetQueueSize(uint32_t size)
109fa7767c5Sopenharmony_ci{
110fa7767c5Sopenharmony_ci    FALSE_RETURN_V(size >= 0 && size <= AVBUFFER_QUEUE_MAX_QUEUE_SIZE && size != size_,
111fa7767c5Sopenharmony_ci                   Status::ERROR_INVALID_BUFFER_SIZE);
112fa7767c5Sopenharmony_ci
113fa7767c5Sopenharmony_ci    if (size > size_) {
114fa7767c5Sopenharmony_ci        size_ = size;
115fa7767c5Sopenharmony_ci        if (!disableAlloc_) {
116fa7767c5Sopenharmony_ci            requestCondition.notify_all();
117fa7767c5Sopenharmony_ci        }
118fa7767c5Sopenharmony_ci    } else {
119fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
120fa7767c5Sopenharmony_ci        DeleteBuffers(size_ - size);
121fa7767c5Sopenharmony_ci        size_ = size;
122fa7767c5Sopenharmony_ci    }
123fa7767c5Sopenharmony_ci
124fa7767c5Sopenharmony_ci    return Status::OK;
125fa7767c5Sopenharmony_ci}
126fa7767c5Sopenharmony_ci
127fa7767c5Sopenharmony_cibool AVBufferQueueImpl::IsBufferInQueue(const std::shared_ptr<AVBuffer>& buffer)
128fa7767c5Sopenharmony_ci{
129fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, false);
130fa7767c5Sopenharmony_ci    auto uniqueId = buffer->GetUniqueId();
131fa7767c5Sopenharmony_ci    return cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end();
132fa7767c5Sopenharmony_ci}
133fa7767c5Sopenharmony_ci
134fa7767c5Sopenharmony_ciuint32_t AVBufferQueueImpl::GetCachedBufferCount() const
135fa7767c5Sopenharmony_ci{
136fa7767c5Sopenharmony_ci    // 确保cachedBufferMap_.size()不会超过MAX_UINT32
137fa7767c5Sopenharmony_ci    return static_cast<uint32_t>(cachedBufferMap_.size());
138fa7767c5Sopenharmony_ci}
139fa7767c5Sopenharmony_ci
140fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::PopFromFreeBufferList(std::shared_ptr<AVBuffer>& buffer, const AVBufferConfig& config)
141fa7767c5Sopenharmony_ci{
142fa7767c5Sopenharmony_ci    for (auto it = freeBufferList_.begin(); it != freeBufferList_.end(); it++) {
143fa7767c5Sopenharmony_ci        if (config <= cachedBufferMap_[*it].config) {
144fa7767c5Sopenharmony_ci            buffer = cachedBufferMap_[*it].buffer;
145fa7767c5Sopenharmony_ci            freeBufferList_.erase(it);
146fa7767c5Sopenharmony_ci            return Status::OK;
147fa7767c5Sopenharmony_ci        }
148fa7767c5Sopenharmony_ci    }
149fa7767c5Sopenharmony_ci
150fa7767c5Sopenharmony_ci    if (freeBufferList_.empty()) {
151fa7767c5Sopenharmony_ci        buffer = nullptr;
152fa7767c5Sopenharmony_ci        // 没有可以重用的freeBuffer
153fa7767c5Sopenharmony_ci        return Status::ERROR_NO_FREE_BUFFER;
154fa7767c5Sopenharmony_ci    }
155fa7767c5Sopenharmony_ci
156fa7767c5Sopenharmony_ci    buffer = cachedBufferMap_[freeBufferList_.front()].buffer;
157fa7767c5Sopenharmony_ci    freeBufferList_.pop_front();
158fa7767c5Sopenharmony_ci
159fa7767c5Sopenharmony_ci    return Status::OK;
160fa7767c5Sopenharmony_ci}
161fa7767c5Sopenharmony_ci
162fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::PopFromDirtyBufferList(std::shared_ptr<AVBuffer>& buffer)
163fa7767c5Sopenharmony_ci{
164fa7767c5Sopenharmony_ci    FALSE_RETURN_V(!dirtyBufferList_.empty(), Status::ERROR_NO_DIRTY_BUFFER);
165fa7767c5Sopenharmony_ci
166fa7767c5Sopenharmony_ci    buffer = cachedBufferMap_[dirtyBufferList_.front()].buffer;
167fa7767c5Sopenharmony_ci    dirtyBufferList_.pop_front();
168fa7767c5Sopenharmony_ci    return Status::OK;
169fa7767c5Sopenharmony_ci}
170fa7767c5Sopenharmony_ci
171fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::AllocBuffer(std::shared_ptr<AVBuffer>& buffer, const AVBufferConfig& config)
172fa7767c5Sopenharmony_ci{
173fa7767c5Sopenharmony_ci    auto bufferImpl = AVBuffer::CreateAVBuffer(config);
174fa7767c5Sopenharmony_ci    FALSE_RETURN_V(bufferImpl != nullptr, Status::ERROR_CREATE_BUFFER);
175fa7767c5Sopenharmony_ci
176fa7767c5Sopenharmony_ci    auto uniqueId = bufferImpl->GetUniqueId();
177fa7767c5Sopenharmony_ci    AVBufferElement ele = {
178fa7767c5Sopenharmony_ci        .config = bufferImpl->GetConfig(),
179fa7767c5Sopenharmony_ci        .state = AVBUFFER_STATE_RELEASED,
180fa7767c5Sopenharmony_ci        .isDeleting = false,
181fa7767c5Sopenharmony_ci        .buffer = bufferImpl,
182fa7767c5Sopenharmony_ci    };
183fa7767c5Sopenharmony_ci    cachedBufferMap_[uniqueId] = ele;
184fa7767c5Sopenharmony_ci    buffer = bufferImpl;
185fa7767c5Sopenharmony_ci
186fa7767c5Sopenharmony_ci    return Status::OK;
187fa7767c5Sopenharmony_ci}
188fa7767c5Sopenharmony_ci
189fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::RequestReuseBuffer(std::shared_ptr<AVBuffer>& buffer, const AVBufferConfig& config)
190fa7767c5Sopenharmony_ci{
191fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
192fa7767c5Sopenharmony_ci
193fa7767c5Sopenharmony_ci    auto uniqueId = buffer->GetUniqueId();
194fa7767c5Sopenharmony_ci    FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(), Status::ERROR_CREATE_BUFFER);
195fa7767c5Sopenharmony_ci
196fa7767c5Sopenharmony_ci    if (config <= cachedBufferMap_[uniqueId].config) {
197fa7767c5Sopenharmony_ci        // 不需要重新分配,直接更新buffer大小
198fa7767c5Sopenharmony_ci        cachedBufferMap_[uniqueId].config.size = config.size;
199fa7767c5Sopenharmony_ci    } else {
200fa7767c5Sopenharmony_ci        // 重新分配
201fa7767c5Sopenharmony_ci        DeleteCachedBufferById(uniqueId);
202fa7767c5Sopenharmony_ci        NOK_RETURN(AllocBuffer(buffer, config));
203fa7767c5Sopenharmony_ci    }
204fa7767c5Sopenharmony_ci
205fa7767c5Sopenharmony_ci    // 注意这里的uniqueId可能因为重新分配buffer而更新,所以需要再次获取
206fa7767c5Sopenharmony_ci    cachedBufferMap_[buffer->GetUniqueId()].state = AVBUFFER_STATE_REQUESTED;
207fa7767c5Sopenharmony_ci    return Status::OK;
208fa7767c5Sopenharmony_ci}
209fa7767c5Sopenharmony_ci
210fa7767c5Sopenharmony_civoid AVBufferQueueImpl::DeleteBuffers(uint32_t count)
211fa7767c5Sopenharmony_ci{
212fa7767c5Sopenharmony_ci    FALSE_RETURN(count > 0);
213fa7767c5Sopenharmony_ci
214fa7767c5Sopenharmony_ci    while (!freeBufferList_.empty()) {
215fa7767c5Sopenharmony_ci        DeleteCachedBufferById(freeBufferList_.front());
216fa7767c5Sopenharmony_ci        freeBufferList_.pop_front();
217fa7767c5Sopenharmony_ci        count--;
218fa7767c5Sopenharmony_ci        if (count <= 0) {
219fa7767c5Sopenharmony_ci            return;
220fa7767c5Sopenharmony_ci        }
221fa7767c5Sopenharmony_ci    }
222fa7767c5Sopenharmony_ci
223fa7767c5Sopenharmony_ci    while (!dirtyBufferList_.empty()) {
224fa7767c5Sopenharmony_ci        DeleteCachedBufferById(dirtyBufferList_.front());
225fa7767c5Sopenharmony_ci        dirtyBufferList_.pop_front();
226fa7767c5Sopenharmony_ci        count--;
227fa7767c5Sopenharmony_ci        if (count <= 0) {
228fa7767c5Sopenharmony_ci            return;
229fa7767c5Sopenharmony_ci        }
230fa7767c5Sopenharmony_ci    }
231fa7767c5Sopenharmony_ci
232fa7767c5Sopenharmony_ci    for (auto&& ele : cachedBufferMap_) {
233fa7767c5Sopenharmony_ci        ele.second.isDeleting = true;
234fa7767c5Sopenharmony_ci        // we don't have to do anything
235fa7767c5Sopenharmony_ci        count--;
236fa7767c5Sopenharmony_ci        if (count <= 0) {
237fa7767c5Sopenharmony_ci            break;
238fa7767c5Sopenharmony_ci        }
239fa7767c5Sopenharmony_ci    }
240fa7767c5Sopenharmony_ci}
241fa7767c5Sopenharmony_ci
242fa7767c5Sopenharmony_civoid AVBufferQueueImpl::DeleteCachedBufferById(uint64_t uniqueId)
243fa7767c5Sopenharmony_ci{
244fa7767c5Sopenharmony_ci    auto it = cachedBufferMap_.find(uniqueId);
245fa7767c5Sopenharmony_ci    if (it != cachedBufferMap_.end()) {
246fa7767c5Sopenharmony_ci        cachedBufferMap_.erase(it);
247fa7767c5Sopenharmony_ci    }
248fa7767c5Sopenharmony_ci}
249fa7767c5Sopenharmony_ci
250fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::CheckConfig(const AVBufferConfig& config)
251fa7767c5Sopenharmony_ci{
252fa7767c5Sopenharmony_ci    if (config.memoryType == MemoryType::UNKNOWN_MEMORY) {
253fa7767c5Sopenharmony_ci        MEDIA_LOG_D("config.memoryType != MemoryType::UNKNOWN_MEMORY");
254fa7767c5Sopenharmony_ci        return Status::ERROR_UNEXPECTED_MEMORY_TYPE;
255fa7767c5Sopenharmony_ci    }
256fa7767c5Sopenharmony_ci    // memoryType_初始化之后将无法改变。
257fa7767c5Sopenharmony_ci    if (memoryType_ != MemoryType::UNKNOWN_MEMORY && config.memoryType != memoryType_) {
258fa7767c5Sopenharmony_ci        MEDIA_LOG_D("memoryType_ != MemoryType::UNKNOWN_MEMORY && config.memoryType != memoryType_");
259fa7767c5Sopenharmony_ci        return Status::ERROR_UNEXPECTED_MEMORY_TYPE;
260fa7767c5Sopenharmony_ci    }
261fa7767c5Sopenharmony_ci    memoryType_ = config.memoryType;
262fa7767c5Sopenharmony_ci    return Status::OK;
263fa7767c5Sopenharmony_ci}
264fa7767c5Sopenharmony_ci
265fa7767c5Sopenharmony_cibool AVBufferQueueImpl::wait_for(std::unique_lock<std::mutex>& lock, int32_t timeoutMs)
266fa7767c5Sopenharmony_ci{
267fa7767c5Sopenharmony_ci    MEDIA_LOG_D("wait for free buffer, timeout = %d", timeoutMs);
268fa7767c5Sopenharmony_ci    if (timeoutMs > 0) {
269fa7767c5Sopenharmony_ci        return requestCondition.wait_for(
270fa7767c5Sopenharmony_ci            lock, std::chrono::milliseconds(timeoutMs), [this]() {
271fa7767c5Sopenharmony_ci                return !freeBufferList_.empty() || (GetCachedBufferCount() < GetQueueSize());
272fa7767c5Sopenharmony_ci            });
273fa7767c5Sopenharmony_ci    } else if (timeoutMs < 0) {
274fa7767c5Sopenharmony_ci        requestCondition.wait(lock);
275fa7767c5Sopenharmony_ci    }
276fa7767c5Sopenharmony_ci    return true;
277fa7767c5Sopenharmony_ci}
278fa7767c5Sopenharmony_ci
279fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::RequestBuffer(
280fa7767c5Sopenharmony_ci    std::shared_ptr<AVBuffer>& buffer, const AVBufferConfig& config, int32_t timeoutMs)
281fa7767c5Sopenharmony_ci{
282fa7767c5Sopenharmony_ci    auto configCopy = config;
283fa7767c5Sopenharmony_ci    if (config.memoryType == MemoryType::UNKNOWN_MEMORY) {
284fa7767c5Sopenharmony_ci        MEDIA_LOG_D("AVBufferQueueImpl::RequestBuffer config.memoryType unknown, "
285fa7767c5Sopenharmony_ci                    "memoryType_ = %u", static_cast<uint32_t>(memoryType_));
286fa7767c5Sopenharmony_ci        configCopy.memoryType = memoryType_;
287fa7767c5Sopenharmony_ci    }
288fa7767c5Sopenharmony_ci
289fa7767c5Sopenharmony_ci    // check param
290fa7767c5Sopenharmony_ci    std::unique_lock<std::mutex> lock(queueMutex_);
291fa7767c5Sopenharmony_ci    auto res = CheckConfig(configCopy);
292fa7767c5Sopenharmony_ci    FALSE_RETURN_V_MSG(res == Status::OK,
293fa7767c5Sopenharmony_ci        res, "CheckConfig not OK, code %{public}d", static_cast<int32_t>(res));
294fa7767c5Sopenharmony_ci    // dequeue from free list
295fa7767c5Sopenharmony_ci    auto ret = PopFromFreeBufferList(buffer, configCopy);
296fa7767c5Sopenharmony_ci    if (ret == Status::OK) {
297fa7767c5Sopenharmony_ci        return RequestReuseBuffer(buffer, configCopy);
298fa7767c5Sopenharmony_ci    }
299fa7767c5Sopenharmony_ci
300fa7767c5Sopenharmony_ci    // check queue size
301fa7767c5Sopenharmony_ci    if (GetCachedBufferCount() >= GetQueueSize()) {
302fa7767c5Sopenharmony_ci        if (!wait_for(lock, timeoutMs)) {
303fa7767c5Sopenharmony_ci            MEDIA_LOG_D("FALSE_RETURN_V wait_for(lock, timeoutMs)");
304fa7767c5Sopenharmony_ci            return Status::ERROR_WAIT_TIMEOUT;
305fa7767c5Sopenharmony_ci        }
306fa7767c5Sopenharmony_ci
307fa7767c5Sopenharmony_ci        // 被条件唤醒后,再次尝试从freeBufferList中取buffer
308fa7767c5Sopenharmony_ci        ret = PopFromFreeBufferList(buffer, configCopy);
309fa7767c5Sopenharmony_ci        if (ret == Status::OK) {
310fa7767c5Sopenharmony_ci            return RequestReuseBuffer(buffer, configCopy);
311fa7767c5Sopenharmony_ci        }
312fa7767c5Sopenharmony_ci        if (GetCachedBufferCount() >= GetQueueSize()) return Status::ERROR_NO_FREE_BUFFER;
313fa7767c5Sopenharmony_ci    }
314fa7767c5Sopenharmony_ci
315fa7767c5Sopenharmony_ci    NOK_RETURN(AllocBuffer(buffer, configCopy));
316fa7767c5Sopenharmony_ci    cachedBufferMap_[buffer->GetUniqueId()].state = AVBUFFER_STATE_REQUESTED;
317fa7767c5Sopenharmony_ci
318fa7767c5Sopenharmony_ci    return Status::OK;
319fa7767c5Sopenharmony_ci}
320fa7767c5Sopenharmony_ci
321fa7767c5Sopenharmony_civoid AVBufferQueueImpl::InsertFreeBufferInOrder(uint64_t uniqueId)
322fa7767c5Sopenharmony_ci{
323fa7767c5Sopenharmony_ci    for (auto it = freeBufferList_.begin(); it != freeBufferList_.end(); it++) {
324fa7767c5Sopenharmony_ci        if ((*it != uniqueId) &&
325fa7767c5Sopenharmony_ci                (cachedBufferMap_[*it].config.capacity >= cachedBufferMap_[uniqueId].config.capacity)) {
326fa7767c5Sopenharmony_ci            freeBufferList_.insert(it, uniqueId);
327fa7767c5Sopenharmony_ci            return;
328fa7767c5Sopenharmony_ci        }
329fa7767c5Sopenharmony_ci    }
330fa7767c5Sopenharmony_ci    freeBufferList_.emplace_back(uniqueId);
331fa7767c5Sopenharmony_ci}
332fa7767c5Sopenharmony_ci
333fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::CancelBuffer(uint64_t uniqueId)
334fa7767c5Sopenharmony_ci{
335fa7767c5Sopenharmony_ci    FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(), Status::ERROR_INVALID_BUFFER_ID);
336fa7767c5Sopenharmony_ci
337fa7767c5Sopenharmony_ci    FALSE_RETURN_V(cachedBufferMap_[uniqueId].state == AVBUFFER_STATE_REQUESTED ||
338fa7767c5Sopenharmony_ci                   cachedBufferMap_[uniqueId].state == AVBUFFER_STATE_PUSHED,
339fa7767c5Sopenharmony_ci                   Status::ERROR_INVALID_BUFFER_STATE);
340fa7767c5Sopenharmony_ci
341fa7767c5Sopenharmony_ci    InsertFreeBufferInOrder(uniqueId);
342fa7767c5Sopenharmony_ci
343fa7767c5Sopenharmony_ci    cachedBufferMap_[uniqueId].state = AVBUFFER_STATE_RELEASED;
344fa7767c5Sopenharmony_ci
345fa7767c5Sopenharmony_ci    requestCondition.notify_all();
346fa7767c5Sopenharmony_ci
347fa7767c5Sopenharmony_ci    MEDIA_LOG_D("cancel buffer id = %llu", uniqueId);
348fa7767c5Sopenharmony_ci
349fa7767c5Sopenharmony_ci    return Status::OK;
350fa7767c5Sopenharmony_ci}
351fa7767c5Sopenharmony_ci
352fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::PushBuffer(uint64_t uniqueId, bool available)
353fa7767c5Sopenharmony_ci{
354fa7767c5Sopenharmony_ci    std::shared_ptr<AVBuffer> buffer = nullptr;
355fa7767c5Sopenharmony_ci    {
356fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
357fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(),
358fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_ID);
359fa7767c5Sopenharmony_ci
360fa7767c5Sopenharmony_ci        auto& ele = cachedBufferMap_[uniqueId];
361fa7767c5Sopenharmony_ci        if (ele.isDeleting) {
362fa7767c5Sopenharmony_ci            DeleteCachedBufferById(uniqueId);
363fa7767c5Sopenharmony_ci            MEDIA_LOG_D("delete push buffer uniqueId(%llu)", uniqueId);
364fa7767c5Sopenharmony_ci            return Status::OK;
365fa7767c5Sopenharmony_ci        }
366fa7767c5Sopenharmony_ci
367fa7767c5Sopenharmony_ci        if (available) {
368fa7767c5Sopenharmony_ci            FALSE_RETURN_V(ele.buffer->GetConfig().size >= 0, Status::ERROR_INVALID_BUFFER_SIZE);
369fa7767c5Sopenharmony_ci        }
370fa7767c5Sopenharmony_ci
371fa7767c5Sopenharmony_ci        FALSE_RETURN_V(ele.state == AVBUFFER_STATE_REQUESTED || ele.state == AVBUFFER_STATE_ATTACHED,
372fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_STATE);
373fa7767c5Sopenharmony_ci
374fa7767c5Sopenharmony_ci        ele.state = AVBUFFER_STATE_PUSHED;
375fa7767c5Sopenharmony_ci        buffer = cachedBufferMap_[uniqueId].buffer;
376fa7767c5Sopenharmony_ci    }
377fa7767c5Sopenharmony_ci
378fa7767c5Sopenharmony_ci    if (available) {
379fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(brokerListenerMutex_);
380fa7767c5Sopenharmony_ci        if (!brokerListeners_.empty() && brokerListeners_.back() != nullptr) {
381fa7767c5Sopenharmony_ci            brokerListeners_.back()->OnBufferFilled(buffer);
382fa7767c5Sopenharmony_ci            return Status::OK;
383fa7767c5Sopenharmony_ci        }
384fa7767c5Sopenharmony_ci    }
385fa7767c5Sopenharmony_ci
386fa7767c5Sopenharmony_ci    return ReturnBuffer(uniqueId, available);
387fa7767c5Sopenharmony_ci}
388fa7767c5Sopenharmony_ci
389fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::PushBuffer(const std::shared_ptr<AVBuffer>& buffer, bool available)
390fa7767c5Sopenharmony_ci{
391fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
392fa7767c5Sopenharmony_ci
393fa7767c5Sopenharmony_ci    return PushBuffer(buffer->GetUniqueId(), available);
394fa7767c5Sopenharmony_ci}
395fa7767c5Sopenharmony_ci
396fa7767c5Sopenharmony_ciStatus __attribute__((no_sanitize("cfi"))) AVBufferQueueImpl::ReturnBuffer(uint64_t uniqueId, bool available)
397fa7767c5Sopenharmony_ci{
398fa7767c5Sopenharmony_ci    {
399fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
400fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(),
401fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_ID);
402fa7767c5Sopenharmony_ci
403fa7767c5Sopenharmony_ci        if (cachedBufferMap_[uniqueId].isDeleting) {
404fa7767c5Sopenharmony_ci            DeleteCachedBufferById(uniqueId);
405fa7767c5Sopenharmony_ci            MEDIA_LOG_D("delete return buffer uniqueId(%llu)", uniqueId);
406fa7767c5Sopenharmony_ci            return Status::OK;
407fa7767c5Sopenharmony_ci        }
408fa7767c5Sopenharmony_ci
409fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_[uniqueId].state == AVBUFFER_STATE_PUSHED,
410fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_STATE);
411fa7767c5Sopenharmony_ci
412fa7767c5Sopenharmony_ci        if (!available) {
413fa7767c5Sopenharmony_ci            NOK_RETURN(CancelBuffer(uniqueId));
414fa7767c5Sopenharmony_ci        } else {
415fa7767c5Sopenharmony_ci            auto& config = cachedBufferMap_[uniqueId].buffer->GetConfig();
416fa7767c5Sopenharmony_ci            bool isEosBuffer = cachedBufferMap_[uniqueId].buffer->flag_ & (uint32_t)(Plugins::AVBufferFlag::EOS);
417fa7767c5Sopenharmony_ci            if (!isEosBuffer) {
418fa7767c5Sopenharmony_ci                FALSE_RETURN_V(config.size > 0, Status::ERROR_INVALID_BUFFER_SIZE);
419fa7767c5Sopenharmony_ci            }
420fa7767c5Sopenharmony_ci            cachedBufferMap_[uniqueId].config = config;
421fa7767c5Sopenharmony_ci            cachedBufferMap_[uniqueId].state = AVBUFFER_STATE_RETURNED;
422fa7767c5Sopenharmony_ci            dirtyBufferList_.push_back(uniqueId);
423fa7767c5Sopenharmony_ci        }
424fa7767c5Sopenharmony_ci    }
425fa7767c5Sopenharmony_ci
426fa7767c5Sopenharmony_ci    if (!available) {
427fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
428fa7767c5Sopenharmony_ci        if (producerListener_ != nullptr) {
429fa7767c5Sopenharmony_ci            producerListener_->OnBufferAvailable();
430fa7767c5Sopenharmony_ci        }
431fa7767c5Sopenharmony_ci        return Status::OK;
432fa7767c5Sopenharmony_ci    }
433fa7767c5Sopenharmony_ci
434fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(consumerListenerMutex_);
435fa7767c5Sopenharmony_ci    FALSE_RETURN_V(consumerListener_ != nullptr, Status::ERROR_NO_CONSUMER_LISTENER);
436fa7767c5Sopenharmony_ci    consumerListener_->OnBufferAvailable();
437fa7767c5Sopenharmony_ci
438fa7767c5Sopenharmony_ci    return Status::OK;
439fa7767c5Sopenharmony_ci}
440fa7767c5Sopenharmony_ci
441fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::ReturnBuffer(const std::shared_ptr<AVBuffer>& buffer, bool available)
442fa7767c5Sopenharmony_ci{
443fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
444fa7767c5Sopenharmony_ci
445fa7767c5Sopenharmony_ci    return ReturnBuffer(buffer->GetUniqueId(), available);
446fa7767c5Sopenharmony_ci}
447fa7767c5Sopenharmony_ci
448fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::SetQueueSizeAndAttachBuffer(uint32_t size,
449fa7767c5Sopenharmony_ci    std::shared_ptr<AVBuffer>& buffer, bool isFilled)
450fa7767c5Sopenharmony_ci{
451fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
452fa7767c5Sopenharmony_ci    auto config = buffer->GetConfig();
453fa7767c5Sopenharmony_ci    auto uniqueId = buffer->GetUniqueId();
454fa7767c5Sopenharmony_ci    {
455fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
456fa7767c5Sopenharmony_ci        if (size >= 0 && size <= AVBUFFER_QUEUE_MAX_QUEUE_SIZE && size != size_) {
457fa7767c5Sopenharmony_ci            SetQueueSizeBeforeAttachBufferLocked(size);
458fa7767c5Sopenharmony_ci        }
459fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) == cachedBufferMap_.end(),
460fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_ID);
461fa7767c5Sopenharmony_ci        NOK_RETURN(CheckConfig(config));
462fa7767c5Sopenharmony_ci        Status result = AttachAvailableBufferLocked(buffer);
463fa7767c5Sopenharmony_ci        FALSE_RETURN_V(result == Status::OK, result);
464fa7767c5Sopenharmony_ci    }
465fa7767c5Sopenharmony_ci    if (isFilled) {
466fa7767c5Sopenharmony_ci        return PushBufferOnFilled(uniqueId, isFilled);
467fa7767c5Sopenharmony_ci    }
468fa7767c5Sopenharmony_ci    return ReleaseBuffer(uniqueId);
469fa7767c5Sopenharmony_ci}
470fa7767c5Sopenharmony_ci
471fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::AttachAvailableBufferLocked(std::shared_ptr<AVBuffer>& buffer)
472fa7767c5Sopenharmony_ci{
473fa7767c5Sopenharmony_ci    auto config = buffer->GetConfig();
474fa7767c5Sopenharmony_ci    auto uniqueId = buffer->GetUniqueId();
475fa7767c5Sopenharmony_ci    AVBufferElement ele = {
476fa7767c5Sopenharmony_ci        .config = config,
477fa7767c5Sopenharmony_ci        .state = AVBUFFER_STATE_ATTACHED,
478fa7767c5Sopenharmony_ci        .isDeleting = false,
479fa7767c5Sopenharmony_ci        .buffer = buffer
480fa7767c5Sopenharmony_ci    };
481fa7767c5Sopenharmony_ci
482fa7767c5Sopenharmony_ci    auto cachedCount = GetCachedBufferCount();
483fa7767c5Sopenharmony_ci    auto queueSize = GetQueueSize();
484fa7767c5Sopenharmony_ci    if (cachedCount >= queueSize) {
485fa7767c5Sopenharmony_ci        auto validCount = static_cast<uint32_t>(dirtyBufferList_.size() + freeBufferList_.size());
486fa7767c5Sopenharmony_ci        auto toBeDeleteCount = cachedCount - queueSize;
487fa7767c5Sopenharmony_ci        // 这里表示有可以删除的buffer,或者
488fa7767c5Sopenharmony_ci        if (validCount > toBeDeleteCount) {
489fa7767c5Sopenharmony_ci            // 在什么场景下需要在此处删除buffer?
490fa7767c5Sopenharmony_ci            DeleteBuffers(toBeDeleteCount + 1); // 多删除一个,用于attach当前buffer
491fa7767c5Sopenharmony_ci            cachedBufferMap_[uniqueId] = ele;
492fa7767c5Sopenharmony_ci            MEDIA_LOG_D("uniqueId(%llu) attached with delete", uniqueId);
493fa7767c5Sopenharmony_ci        } else {
494fa7767c5Sopenharmony_ci            MEDIA_LOG_E("attach failed, out of range");
495fa7767c5Sopenharmony_ci            return Status::ERROR_OUT_OF_RANGE;
496fa7767c5Sopenharmony_ci        }
497fa7767c5Sopenharmony_ci    } else {
498fa7767c5Sopenharmony_ci        cachedBufferMap_[uniqueId] = ele;
499fa7767c5Sopenharmony_ci        MEDIA_LOG_D("uniqueId(%llu) attached without delete", uniqueId);
500fa7767c5Sopenharmony_ci    }
501fa7767c5Sopenharmony_ci    return Status::OK;
502fa7767c5Sopenharmony_ci}
503fa7767c5Sopenharmony_ci
504fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::PushBufferOnFilled(uint64_t uniqueId, bool isFilled)
505fa7767c5Sopenharmony_ci{
506fa7767c5Sopenharmony_ci    auto ret = PushBuffer(uniqueId, isFilled);
507fa7767c5Sopenharmony_ci    if (ret != Status::OK) {
508fa7767c5Sopenharmony_ci        // PushBuffer失败,强制Detach
509fa7767c5Sopenharmony_ci        DetachBuffer(uniqueId, true);
510fa7767c5Sopenharmony_ci    }
511fa7767c5Sopenharmony_ci    return ret;
512fa7767c5Sopenharmony_ci}
513fa7767c5Sopenharmony_ci
514fa7767c5Sopenharmony_civoid AVBufferQueueImpl::SetQueueSizeBeforeAttachBufferLocked(uint32_t size)
515fa7767c5Sopenharmony_ci{
516fa7767c5Sopenharmony_ci    if (size > size_) {
517fa7767c5Sopenharmony_ci        size_ = size;
518fa7767c5Sopenharmony_ci        if (!disableAlloc_) {
519fa7767c5Sopenharmony_ci            requestCondition.notify_all();
520fa7767c5Sopenharmony_ci        }
521fa7767c5Sopenharmony_ci    } else {
522fa7767c5Sopenharmony_ci        DeleteBuffers(size_ - size);
523fa7767c5Sopenharmony_ci        size_ = size;
524fa7767c5Sopenharmony_ci    }
525fa7767c5Sopenharmony_ci}
526fa7767c5Sopenharmony_ci
527fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::AttachBuffer(std::shared_ptr<AVBuffer>& buffer, bool isFilled)
528fa7767c5Sopenharmony_ci{
529fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
530fa7767c5Sopenharmony_ci
531fa7767c5Sopenharmony_ci    auto config = buffer->GetConfig();
532fa7767c5Sopenharmony_ci    auto uniqueId = buffer->GetUniqueId();
533fa7767c5Sopenharmony_ci    {
534fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
535fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) == cachedBufferMap_.end(),
536fa7767c5Sopenharmony_ci                       Status::ERROR_INVALID_BUFFER_ID);
537fa7767c5Sopenharmony_ci
538fa7767c5Sopenharmony_ci        NOK_RETURN(CheckConfig(config));
539fa7767c5Sopenharmony_ci
540fa7767c5Sopenharmony_ci        Status result = AttachAvailableBufferLocked(buffer);
541fa7767c5Sopenharmony_ci        FALSE_RETURN_V(result == Status::OK, result);
542fa7767c5Sopenharmony_ci    }
543fa7767c5Sopenharmony_ci
544fa7767c5Sopenharmony_ci    if (isFilled) {
545fa7767c5Sopenharmony_ci        return PushBufferOnFilled(uniqueId, isFilled);
546fa7767c5Sopenharmony_ci    }
547fa7767c5Sopenharmony_ci
548fa7767c5Sopenharmony_ci    return ReleaseBuffer(uniqueId);
549fa7767c5Sopenharmony_ci}
550fa7767c5Sopenharmony_ci
551fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::DetachBuffer(uint64_t uniqueId, bool force)
552fa7767c5Sopenharmony_ci{
553fa7767c5Sopenharmony_ci    FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(), Status::ERROR_INVALID_BUFFER_ID);
554fa7767c5Sopenharmony_ci
555fa7767c5Sopenharmony_ci    const auto& ele = cachedBufferMap_[uniqueId];
556fa7767c5Sopenharmony_ci
557fa7767c5Sopenharmony_ci    if (!force) {
558fa7767c5Sopenharmony_ci        // 只有生产者或消费者在获取到buffer后才能detach
559fa7767c5Sopenharmony_ci        if (ele.state == AVBUFFER_STATE_REQUESTED) {
560fa7767c5Sopenharmony_ci            MEDIA_LOG_D("detach buffer(%llu) on state requested", uniqueId);
561fa7767c5Sopenharmony_ci        } else if (ele.state == AVBUFFER_STATE_ACQUIRED) {
562fa7767c5Sopenharmony_ci            MEDIA_LOG_D("detach buffer(%llu) on state acquired", uniqueId);
563fa7767c5Sopenharmony_ci        } else {
564fa7767c5Sopenharmony_ci            MEDIA_LOG_W("detach buffer(%llu) on state %d forbidden", uniqueId, ele.state);
565fa7767c5Sopenharmony_ci            return Status::ERROR_INVALID_BUFFER_STATE;
566fa7767c5Sopenharmony_ci        }
567fa7767c5Sopenharmony_ci    }
568fa7767c5Sopenharmony_ci
569fa7767c5Sopenharmony_ci    cachedBufferMap_.erase(uniqueId);
570fa7767c5Sopenharmony_ci
571fa7767c5Sopenharmony_ci    return Status::OK;
572fa7767c5Sopenharmony_ci}
573fa7767c5Sopenharmony_ci
574fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::DetachBuffer(uint64_t uniqueId)
575fa7767c5Sopenharmony_ci{
576fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(queueMutex_);
577fa7767c5Sopenharmony_ci    return DetachBuffer(uniqueId, false);
578fa7767c5Sopenharmony_ci}
579fa7767c5Sopenharmony_ci
580fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::DetachBuffer(const std::shared_ptr<AVBuffer>& buffer)
581fa7767c5Sopenharmony_ci{
582fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
583fa7767c5Sopenharmony_ci
584fa7767c5Sopenharmony_ci    return DetachBuffer(buffer->GetUniqueId());
585fa7767c5Sopenharmony_ci}
586fa7767c5Sopenharmony_ci
587fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::AcquireBuffer(std::shared_ptr<AVBuffer>& buffer)
588fa7767c5Sopenharmony_ci{
589fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(queueMutex_);
590fa7767c5Sopenharmony_ci    auto ret = PopFromDirtyBufferList(buffer);
591fa7767c5Sopenharmony_ci    if (ret != Status::OK) {
592fa7767c5Sopenharmony_ci        MEDIA_LOG_D("acquire buffer failed");
593fa7767c5Sopenharmony_ci        return ret;
594fa7767c5Sopenharmony_ci    }
595fa7767c5Sopenharmony_ci
596fa7767c5Sopenharmony_ci    cachedBufferMap_[buffer->GetUniqueId()].state = AVBUFFER_STATE_ACQUIRED;
597fa7767c5Sopenharmony_ci
598fa7767c5Sopenharmony_ci    return Status::OK;
599fa7767c5Sopenharmony_ci}
600fa7767c5Sopenharmony_ci
601fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::ReleaseBuffer(uint64_t uniqueId)
602fa7767c5Sopenharmony_ci{
603fa7767c5Sopenharmony_ci    {
604fa7767c5Sopenharmony_ci        std::lock_guard<std::mutex> lockGuard(queueMutex_);
605fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_.find(uniqueId) != cachedBufferMap_.end(), Status::ERROR_INVALID_BUFFER_ID);
606fa7767c5Sopenharmony_ci
607fa7767c5Sopenharmony_ci        FALSE_RETURN_V(cachedBufferMap_[uniqueId].state == AVBUFFER_STATE_ACQUIRED ||
608fa7767c5Sopenharmony_ci            cachedBufferMap_[uniqueId].state == AVBUFFER_STATE_ATTACHED, Status::ERROR_INVALID_BUFFER_STATE);
609fa7767c5Sopenharmony_ci
610fa7767c5Sopenharmony_ci        cachedBufferMap_[uniqueId].state = AVBUFFER_STATE_RELEASED;
611fa7767c5Sopenharmony_ci        if (cachedBufferMap_[uniqueId].isDeleting) {
612fa7767c5Sopenharmony_ci            DeleteCachedBufferById(uniqueId);
613fa7767c5Sopenharmony_ci            return Status::OK;
614fa7767c5Sopenharmony_ci        }
615fa7767c5Sopenharmony_ci
616fa7767c5Sopenharmony_ci        InsertFreeBufferInOrder(uniqueId);
617fa7767c5Sopenharmony_ci
618fa7767c5Sopenharmony_ci        requestCondition.notify_all();
619fa7767c5Sopenharmony_ci    }
620fa7767c5Sopenharmony_ci
621fa7767c5Sopenharmony_ci    // 注意:此时通知生产者有buffer可用,但实际有可能已经被request wait的生产者获取
622fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
623fa7767c5Sopenharmony_ci    if (producerListener_ != nullptr) {
624fa7767c5Sopenharmony_ci        producerListener_->OnBufferAvailable();
625fa7767c5Sopenharmony_ci    }
626fa7767c5Sopenharmony_ci
627fa7767c5Sopenharmony_ci    return Status::OK;
628fa7767c5Sopenharmony_ci}
629fa7767c5Sopenharmony_ci
630fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::ReleaseBuffer(const std::shared_ptr<AVBuffer>& buffer)
631fa7767c5Sopenharmony_ci{
632fa7767c5Sopenharmony_ci    FALSE_RETURN_V(buffer != nullptr, Status::ERROR_NULL_POINT_BUFFER);
633fa7767c5Sopenharmony_ci
634fa7767c5Sopenharmony_ci    return ReleaseBuffer(buffer->GetUniqueId());
635fa7767c5Sopenharmony_ci}
636fa7767c5Sopenharmony_ci
637fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::Clear()
638fa7767c5Sopenharmony_ci{
639fa7767c5Sopenharmony_ci    MEDIA_LOG_D("AVBufferQueueImpl Clear");
640fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(queueMutex_);
641fa7767c5Sopenharmony_ci    dirtyBufferList_.clear();
642fa7767c5Sopenharmony_ci    for (auto it = cachedBufferMap_.begin(); it != cachedBufferMap_.end(); it++) {
643fa7767c5Sopenharmony_ci        if (it->second.state == AVBUFFER_STATE_PUSHED || it->second.state == AVBUFFER_STATE_RETURNED) {
644fa7767c5Sopenharmony_ci            it->second.state = AVBUFFER_STATE_RELEASED;
645fa7767c5Sopenharmony_ci            InsertFreeBufferInOrder(it->first);
646fa7767c5Sopenharmony_ci        }
647fa7767c5Sopenharmony_ci    }
648fa7767c5Sopenharmony_ci    requestCondition.notify_all();
649fa7767c5Sopenharmony_ci    return Status::OK;
650fa7767c5Sopenharmony_ci}
651fa7767c5Sopenharmony_ci
652fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::SetBrokerListener(sptr<IBrokerListener>& listener)
653fa7767c5Sopenharmony_ci{
654fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(brokerListenerMutex_);
655fa7767c5Sopenharmony_ci    brokerListeners_.push_back(listener);
656fa7767c5Sopenharmony_ci    return Status::OK;
657fa7767c5Sopenharmony_ci}
658fa7767c5Sopenharmony_ci
659fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::RemoveBrokerListener(sptr<IBrokerListener>& listener)
660fa7767c5Sopenharmony_ci{
661fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(brokerListenerMutex_);
662fa7767c5Sopenharmony_ci    if (!brokerListeners_.empty() && listener == brokerListeners_.back()) {
663fa7767c5Sopenharmony_ci        brokerListeners_.pop_back();
664fa7767c5Sopenharmony_ci        MEDIA_LOG_I("RemoveBrokerListener success, size: %{public}d", brokerListeners_.size());
665fa7767c5Sopenharmony_ci    } else {
666fa7767c5Sopenharmony_ci        MEDIA_LOG_E("removed item is not the back one.");
667fa7767c5Sopenharmony_ci    }
668fa7767c5Sopenharmony_ci    return Status::OK;
669fa7767c5Sopenharmony_ci}
670fa7767c5Sopenharmony_ci
671fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::SetProducerListener(sptr<IProducerListener>& listener)
672fa7767c5Sopenharmony_ci{
673fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(producerListenerMutex_);
674fa7767c5Sopenharmony_ci    producerListener_ = listener;
675fa7767c5Sopenharmony_ci
676fa7767c5Sopenharmony_ci    return Status::OK;
677fa7767c5Sopenharmony_ci}
678fa7767c5Sopenharmony_ci
679fa7767c5Sopenharmony_ciStatus AVBufferQueueImpl::SetConsumerListener(sptr<IConsumerListener>& listener)
680fa7767c5Sopenharmony_ci{
681fa7767c5Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(consumerListenerMutex_);
682fa7767c5Sopenharmony_ci    consumerListener_ = listener;
683fa7767c5Sopenharmony_ci
684fa7767c5Sopenharmony_ci    return Status::OK;
685fa7767c5Sopenharmony_ci}
686fa7767c5Sopenharmony_ci
687fa7767c5Sopenharmony_ci} // namespace Media
688fa7767c5Sopenharmony_ci} // namespace OHOS
689