1 /*
2 * Copyright (C) 2025 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_renderer_manager.h"
17
18 namespace {
19 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "AudioRendererManager"};
20 static const int32_t AUDIO_RENDERER_MAX_NUM = 20;
21 }
22
23 namespace OHOS {
24 namespace Media {
~AudioRendererManager()25 AudioRendererManager::~AudioRendererManager()
26 {
27 MEDIA_LOGI("Destruction AudioRendererManager.");
28 };
29
GetInstance()30 AudioRendererManager& AudioRendererManager::GetInstance()
31 {
32 static AudioRendererManager instance;
33 return instance;
34 }
35
GetGlobalId()36 int32_t AudioRendererManager::GetGlobalId()
37 {
38 std::lock_guard<std::mutex> lock(renderMgrMutex_);
39 globalIdNext_ = globalIdNext_ == INT32_MAX ? 1 : globalIdNext_ + 1;
40 return globalIdNext_;
41 }
42
GetAudioRendererInstance(int32_t globalId)43 std::unique_ptr<AudioStandard::AudioRenderer> AudioRendererManager::GetAudioRendererInstance(int32_t globalId)
44 {
45 MediaTrace trace("AudioRendererManager::GetAudioRendererInstance");
46 std::lock_guard<std::mutex> lock(renderMgrMutex_);
47 std::unique_ptr<AudioStandard::AudioRenderer> findInstance;
48 for (auto it = audioRendererVector_.begin(); it != audioRendererVector_.end();) {
49 if (it->first == globalId) {
50 findInstance = std::move(it->second);
51 it = audioRendererVector_.erase(it);
52 break;
53 } else {
54 ++it;
55 }
56 }
57 MEDIA_LOGI("AudioRendererManager::GetAudioRendererInstance audioRendererVector_ size:%{public}zu",
58 audioRendererVector_.size());
59 return findInstance;
60 }
61
SetAudioRendererInstance(int32_t globalId,std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer)62 void AudioRendererManager::SetAudioRendererInstance(int32_t globalId,
63 std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer)
64 {
65 MediaTrace trace("AudioRendererManager::SetAudioRendererInstance");
66 renderMgrMutex_.lock();
67 audioRendererVector_.push_back(std::make_pair(globalId, std::move(audioRenderer)));
68 int32_t removeGlobalId = -1;
69 MEDIA_LOGI("AudioRendererManager::SetAudioRendererInstance audioRendererVector_ size:%{public}zu",
70 audioRendererVector_.size());
71 int32_t excessNum = static_cast<int32_t>(audioRendererVector_.size()) - AUDIO_RENDERER_MAX_NUM;
72 if (excessNum > 0) {
73 SoundPoolXCollie soundPoolXCollie("AudioRenderer::Release time out",
74 [](void *) {
75 MEDIA_LOGI("AudioRenderer::Release time out");
76 });
77 removeGlobalId = audioRendererVector_.front().first;
78 MEDIA_LOGI("AudioRendererManager release audioRenderer removeGlobalId:%{public}d", removeGlobalId);
79 (audioRendererVector_.front().second)->Release();
80 soundPoolXCollie.CancelXCollieTimer();
81 audioRendererVector_.pop_front();
82 }
83 renderMgrMutex_.unlock();
84 if (removeGlobalId > 0) {
85 DeleteManager(removeGlobalId);
86 }
87 }
88
RemoveOldAudioRenderer()89 void AudioRendererManager::RemoveOldAudioRenderer()
90 {
91 MediaTrace trace("AudioRendererManager::RemoveOldAudioRenderer");
92 renderMgrMutex_.lock();
93 int32_t removeGlobalId = -1;
94 if (audioRendererVector_.size() > 0) {
95 SoundPoolXCollie soundPoolXCollie("AudioRenderer::RemoveOld time out",
96 [](void *) {
97 MEDIA_LOGI("AudioRenderer::RemoveOld time out");
98 });
99 removeGlobalId = audioRendererVector_.front().first;
100 MEDIA_LOGI("AudioRendererManager remove old removeGlobalId:%{public}d", removeGlobalId);
101 (audioRendererVector_.front().second)->Release();
102 soundPoolXCollie.CancelXCollieTimer();
103 audioRendererVector_.pop_front();
104 }
105 renderMgrMutex_.unlock();
106 if (removeGlobalId > 0) {
107 DeleteManager(removeGlobalId);
108 }
109 }
110
DelAudioRenderer(int32_t globalId)111 void AudioRendererManager::DelAudioRenderer(int32_t globalId)
112 {
113 std::lock_guard<std::mutex> lock(renderMgrMutex_);
114 for (auto it = audioRendererVector_.begin(); it != audioRendererVector_.end();) {
115 if (it->first == globalId) {
116 SoundPoolXCollie soundPoolXCollie("AudioRenderer::DelAudioRenderer time out",
117 [](void *) {
118 MEDIA_LOGI("AudioRenderer::DelAudioRenderer time out");
119 });
120 (it->second)->Release();
121 soundPoolXCollie.CancelXCollieTimer();
122 it = audioRendererVector_.erase(it);
123 break;
124 } else {
125 ++it;
126 }
127 }
128 MEDIA_LOGI("AudioRendererManager::DelAudioRenderer audioRendererVector_ size:%{public}zu",
129 audioRendererVector_.size());
130 }
131
SetParallelManager(std::weak_ptr<ParallelStreamManager> parallelManager)132 void AudioRendererManager::SetParallelManager(std::weak_ptr<ParallelStreamManager> parallelManager)
133 {
134 std::lock_guard<std::mutex> lock(renderMgrMutex_);
135 parallelManagerList_.push_back(parallelManager);
136 }
137
SetStreamIDManager(std::weak_ptr<StreamIDManager> streamIDManager)138 void AudioRendererManager::SetStreamIDManager(std::weak_ptr<StreamIDManager> streamIDManager)
139 {
140 std::lock_guard<std::mutex> lock(renderMgrMutex_);
141 streamIDManagerList_.push_back(streamIDManager);
142 }
143
DeleteManager(int32_t globalId)144 void AudioRendererManager::DeleteManager(int32_t globalId)
145 {
146 std::list<std::weak_ptr<ParallelStreamManager>> palList;
147 std::list<std::weak_ptr<StreamIDManager>> mgrList;
148 {
149 std::lock_guard<std::mutex> lock(renderMgrMutex_);
150 palList = parallelManagerList_;
151 mgrList = streamIDManagerList_;
152 }
153 for (const auto& weakManager : palList) {
154 if (auto sharedManager = weakManager.lock()) {
155 sharedManager->DelGlobalId(globalId);
156 }
157 }
158 for (const auto& weakManager : mgrList) {
159 if (auto sharedManager = weakManager.lock()) {
160 sharedManager->DelGlobalId(globalId);
161 }
162 }
163 }
164
165 } // namespace Media
166 } // namespace OHOS
167