• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "audio_buffers_manager.h"
17 #include "avcodec_log.h"
18 
19 namespace {
20 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AvCodec-AudioBuffersManager"};
21 constexpr uint8_t LOGD_FREQUENCY = 5;
22 } // namespace
23 
24 namespace OHOS {
25 namespace MediaAVCodec {
26 constexpr short DEFAULT_SLEEP_TIME = 500;
27 constexpr short MAX_WAIT_TIMES = 20;
28 
~AudioBuffersManager()29 AudioBuffersManager::~AudioBuffersManager()
30 {
31     AVCODEC_LOGI("deconstructor called.");
32 }
33 
AudioBuffersManager(const uint32_t bufferSize,const std::string_view & name,const uint16_t count,const uint32_t metaSize)34 AudioBuffersManager::AudioBuffersManager(const uint32_t bufferSize, const std::string_view &name, const uint16_t count,
35                                          const uint32_t metaSize)
36     : isRunning_(true),
37       inBufIndexExist(count, false),
38       bufferCount_(count),
39       bufferSize_(bufferSize),
40       metaSize_(metaSize),
41       name_(name),
42       bufferInfo_(count)
43 {
44     initBuffers();
45 }
46 
getMemory(const uint32_t & index) const47 std::shared_ptr<AudioBufferInfo> AudioBuffersManager::getMemory(const uint32_t &index) const noexcept
48 {
49     if (index >= bufferInfo_.size()) {
50         return nullptr;
51     }
52     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "start get memory,name:%{public}s,index:%{public}u", name_.data(), index);
53     std::lock_guard<std::mutex> lock(stateMutex_);
54     return bufferInfo_[index];
55 }
56 
SetBufferBusy(const uint32_t & index)57 bool AudioBuffersManager::SetBufferBusy(const uint32_t &index)
58 {
59     if (index < bufferInfo_.size()) {
60         std::lock_guard<std::mutex> lock(stateMutex_);
61         bufferInfo_[index]->SetBufferOwned();
62         return true;
63     }
64     return false;
65 }
66 
initBuffers()67 void AudioBuffersManager::initBuffers()
68 {
69     std::lock_guard<std::mutex> lock(stateMutex_);
70     AVCODEC_LOGI("start allocate %{public}s buffers,each buffer size:%{public}d", name_.data(), bufferSize_);
71     for (size_t i = 0; i < bufferCount_; i++) {
72         bufferInfo_[i] = std::make_shared<AudioBufferInfo>(bufferSize_, name_, metaSize_);
73         inBufIndexQue_.emplace(i);
74         inBufIndexExist[i] = true;
75     }
76     AVCODEC_LOGI("end allocate %{public}s buffers", name_.data());
77 }
78 
RequestNewBuffer(uint32_t & index,std::shared_ptr<AudioBufferInfo> & buffer)79 bool AudioBuffersManager::RequestNewBuffer(uint32_t &index, std::shared_ptr<AudioBufferInfo> &buffer)
80 {
81     buffer = createNewBuffer();
82     if (buffer == nullptr) {
83         return false;
84     }
85     index = bufferInfo_.size() - 1;
86     inBufIndexExist.emplace_back(false);
87     return true;
88 }
89 
RequestAvailableIndex(uint32_t & index)90 bool AudioBuffersManager::RequestAvailableIndex(uint32_t &index)
91 {
92     short waitTimes = 0;
93     bool isTimeOut = false;
94     while (inBufIndexQue_.empty() && isRunning_) {
95         if (waitTimes >= MAX_WAIT_TIMES) {
96             AVCODEC_LOGW("Request empty %{public}s buffer time out.", name_.data());
97             isTimeOut = true;
98             break;
99         }
100         AVCODEC_LOGD("Request empty %{public}s buffer", name_.data());
101         std::unique_lock aLock(availableMutex_);
102         availableCondition_.wait_for(aLock, std::chrono::milliseconds(DEFAULT_SLEEP_TIME),
103                                      [this] { return !inBufIndexQue_.empty() || !isRunning_; });
104         waitTimes++;
105     }
106 
107     if (isTimeOut) {
108         return false;
109     }
110 
111     if (!isRunning_) {
112         return false;
113     }
114     {
115         std::lock_guard<std::mutex> lock(stateMutex_);
116         index = inBufIndexQue_.front();
117         inBufIndexQue_.pop();
118     }
119     if (index >= bufferInfo_.size()) {
120         AVCODEC_LOGW("Request %{public}s buffer index is invalidate ,index:%{public}u.", name_.data(), index);
121         return false;
122     }
123     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "Request %{public}s buffer successful,index:%{public}u", name_.data(), index);
124     inBufIndexExist[index] = false;
125     bufferInfo_[index]->SetBufferOwned();
126     return true;
127 }
128 
ReleaseAll()129 void AudioBuffersManager::ReleaseAll()
130 {
131     isRunning_ = false;
132     availableCondition_.notify_all();
133     {
134         std::lock_guard<std::mutex> lock(stateMutex_);
135         while (!inBufIndexQue_.empty()) {
136             inBufIndexQue_.pop();
137         }
138     }
139     for (uint32_t i = 0; i < bufferInfo_.size(); ++i) {
140         bufferInfo_[i]->ResetBuffer();
141         inBufIndexQue_.emplace(i);
142         inBufIndexExist[i] = true;
143     }
144     AVCODEC_LOGI("release all %{public}s buffer.", name_.data());
145 }
146 
SetRunning()147 void AudioBuffersManager::SetRunning()
148 {
149     isRunning_ = true;
150 }
151 
ReleaseBuffer(const uint32_t & index)152 bool AudioBuffersManager::ReleaseBuffer(const uint32_t &index)
153 {
154     if (index < bufferInfo_.size()) {
155         AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "ReleaseBuffer %{public}s buffer,index:%{public}u", name_.data(), index);
156         std::lock_guard<std::mutex> lock(stateMutex_);
157         bufferInfo_[index]->ResetBuffer();
158         if (!inBufIndexExist[index]) {
159             inBufIndexQue_.emplace(index);
160             inBufIndexExist[index] = true;
161         }
162         availableCondition_.notify_all();
163         return true;
164     }
165     return false;
166 }
167 
createNewBuffer()168 std::shared_ptr<AudioBufferInfo> AudioBuffersManager::createNewBuffer()
169 {
170     std::lock_guard<std::mutex> lock(stateMutex_);
171     std::shared_ptr<AudioBufferInfo> buffer = std::make_shared<AudioBufferInfo>(bufferSize_, name_, metaSize_);
172     bufferInfo_.emplace_back(buffer);
173     return buffer;
174 }
175 } // namespace MediaAVCodec
176 } // namespace OHOS