1 /*
2 * Copyright (c) 2024 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 #ifndef LOG_TAG
16 #define LOG_TAG "ProAudioStreamManager"
17 #endif
18
19 #include "pro_audio_stream_manager.h"
20 #include <sstream>
21 #include <atomic>
22 #include "audio_service_log.h"
23 #include "audio_errors.h"
24 #include "direct_playback_engine.h"
25 #include "policy_handler.h"
26 #include "pro_renderer_stream_impl.h"
27 #include "audio_engine_manager.h"
28 #include "none_mix_engine.h"
29 #include "audio_utils.h"
30
31 namespace OHOS {
32 namespace AudioStandard {
33 using namespace std;
34
ProAudioStreamManager(ManagerType type)35 ProAudioStreamManager::ProAudioStreamManager(ManagerType type)
36 : managerType_(type)
37 {
38 if (type == EAC3_PLAYBACK) {
39 playbackEngine_ = std::make_unique<DirectPlayBackEngine>();
40 } else {
41 playbackEngine_ = std::make_unique<NoneMixEngine>();
42 }
43 AUDIO_DEBUG_LOG("ProAudioStreamManager");
44 }
45
~ProAudioStreamManager()46 ProAudioStreamManager::~ProAudioStreamManager()
47 {
48 playbackEngine_ = nullptr;
49 AUDIO_DEBUG_LOG("~ProAudioStreamManager");
50 }
51
CreateRender(AudioProcessConfig processConfig,std::shared_ptr<IRendererStream> & stream)52 int32_t ProAudioStreamManager::CreateRender(AudioProcessConfig processConfig, std::shared_ptr<IRendererStream> &stream)
53 {
54 Trace trace("ProAudioStreamManager::CreateRender");
55 AUDIO_DEBUG_LOG("Create renderer start,manager type:%{public}d", managerType_);
56 uint32_t sessionId = 0;
57 if (processConfig.originalSessionId < MIN_STREAMID || processConfig.originalSessionId > MAX_STREAMID) {
58 sessionId = PolicyHandler::GetInstance().GenerateSessionId(processConfig.appInfo.appUid);
59 } else {
60 sessionId = processConfig.originalSessionId;
61 }
62 std::shared_ptr<IRendererStream> rendererStream = CreateRendererStream(processConfig);
63 CHECK_AND_RETURN_RET_LOG(rendererStream != nullptr, ERR_DEVICE_INIT, "Failed to init rendererStream");
64 int32_t ret = CreatePlayBackEngine(rendererStream);
65 if (ret != SUCCESS) {
66 AUDIO_ERR_LOG("Create play back engine failed. ret:%{public}d", ret);
67 rendererStream = nullptr;
68 return ret;
69 }
70 rendererStream->SetStreamIndex(sessionId);
71 std::lock_guard<std::mutex> lock(streamMapMutex_);
72 rendererStreamMap_[sessionId] = rendererStream;
73 stream = rendererStream;
74 return SUCCESS;
75 }
76
StartRender(uint32_t streamIndex)77 int32_t ProAudioStreamManager::StartRender(uint32_t streamIndex)
78 {
79 Trace trace("ProAudioStreamManager::StartRender");
80 AUDIO_DEBUG_LOG("Start renderer enter");
81 std::shared_ptr<IRendererStream> currentRender;
82 std::lock_guard<std::mutex> lock(streamMapMutex_);
83 auto it = rendererStreamMap_.find(streamIndex);
84 if (it == rendererStreamMap_.end()) {
85 AUDIO_WARNING_LOG("No matching stream");
86 return SUCCESS;
87 }
88 currentRender = rendererStreamMap_[streamIndex];
89 int32_t result = currentRender->Start();
90 CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "Failed to start rendererStream");
91 if (playbackEngine_) {
92 playbackEngine_->Start();
93 }
94 return SUCCESS;
95 }
96
StopRender(uint32_t streamIndex)97 int32_t ProAudioStreamManager::StopRender(uint32_t streamIndex)
98 {
99 Trace trace("ProAudioStreamManager::StopRender");
100 AUDIO_DEBUG_LOG("Stop renderer enter");
101 std::lock_guard<std::mutex> lock(streamMapMutex_);
102 auto it = rendererStreamMap_.find(streamIndex);
103 if (it == rendererStreamMap_.end()) {
104 AUDIO_WARNING_LOG("No matching stream");
105 return SUCCESS;
106 }
107 rendererStreamMap_[streamIndex]->Stop();
108 if (playbackEngine_) {
109 playbackEngine_->Stop();
110 }
111 return SUCCESS;
112 }
113
PauseRender(uint32_t streamIndex)114 int32_t ProAudioStreamManager::PauseRender(uint32_t streamIndex)
115 {
116 Trace trace("ProAudioStreamManager::PauseRender");
117 AUDIO_DEBUG_LOG("Pause renderer enter");
118 std::lock_guard<std::mutex> lock(streamMapMutex_);
119 auto it = rendererStreamMap_.find(streamIndex);
120 if (it == rendererStreamMap_.end()) {
121 AUDIO_WARNING_LOG("No matching stream");
122 return SUCCESS;
123 }
124 rendererStreamMap_[streamIndex]->Pause();
125 if (playbackEngine_) {
126 playbackEngine_->Pause();
127 }
128 return SUCCESS;
129 }
130
ReleaseRender(uint32_t streamIndex)131 int32_t ProAudioStreamManager::ReleaseRender(uint32_t streamIndex)
132 {
133 Trace trace("ProAudioStreamManager::ReleaseRender");
134 AUDIO_DEBUG_LOG("Release renderer start");
135 std::shared_ptr<IRendererStream> currentRender;
136 {
137 std::lock_guard<std::mutex> lock(streamMapMutex_);
138 auto it = rendererStreamMap_.find(streamIndex);
139 if (it == rendererStreamMap_.end()) {
140 AUDIO_WARNING_LOG("No matching stream");
141 return SUCCESS;
142 }
143 currentRender = rendererStreamMap_[streamIndex];
144 rendererStreamMap_[streamIndex] = nullptr;
145 rendererStreamMap_.erase(streamIndex);
146 if (playbackEngine_) {
147 playbackEngine_->Stop();
148 playbackEngine_->RemoveRenderer(currentRender);
149 }
150 }
151 if (currentRender->Release() < 0) {
152 AUDIO_WARNING_LOG("Release stream %{public}d failed", streamIndex);
153 return ERR_OPERATION_FAILED;
154 }
155 AUDIO_INFO_LOG("rendererStreamMap_.size() : %{public}zu", rendererStreamMap_.size());
156 if (rendererStreamMap_.size() == 0) {
157 AUDIO_INFO_LOG("Release the last stream");
158 }
159 return SUCCESS;
160 }
161
TriggerStartIfNecessary()162 int32_t ProAudioStreamManager::TriggerStartIfNecessary()
163 {
164 if (playbackEngine_ && !playbackEngine_->IsPlaybackEngineRunning()) {
165 AUDIO_INFO_LOG("trigger re-start thread");
166 playbackEngine_->Start();
167 }
168 return SUCCESS;
169 }
170
GetStreamCount() const171 int32_t ProAudioStreamManager::GetStreamCount() const noexcept
172 {
173 return rendererStreamMap_.size();
174 }
175
CreatePlayBackEngine(const std::shared_ptr<IRendererStream> & stream)176 int32_t ProAudioStreamManager::CreatePlayBackEngine(const std::shared_ptr<IRendererStream> &stream)
177 {
178 Trace trace("ProAudioStreamManager::CreatePlayBackEngine");
179 int32_t ret = SUCCESS;
180 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
181 AudioProcessConfig config = stream->GetAudioProcessConfig();
182 bool result = PolicyHandler::GetInstance().GetProcessDeviceInfo(config, true, deviceInfo);
183 CHECK_AND_RETURN_RET_LOG(result, ERR_DEVICE_INIT, "GetProcessDeviceInfo failed.");
184 CHECK_AND_RETURN_RET_LOG(playbackEngine_ != nullptr, ERR_NOT_SUPPORTED, "engine not init!");
185 playbackEngine_->Init(deviceInfo, managerType_ == VOIP_PLAYBACK);
186 ret = playbackEngine_->AddRenderer(stream);
187 return ret;
188 }
189
CreateRendererStream(AudioProcessConfig processConfig)190 std::shared_ptr<IRendererStream> ProAudioStreamManager::CreateRendererStream(AudioProcessConfig processConfig)
191 {
192 Trace trace("ProAudioStreamManager::CreateRendererStream");
193 std::lock_guard<std::mutex> lock(paElementsMutex_);
194 bool isDirectStream = managerType_ == DIRECT_PLAYBACK; // direct stream (high resolution) or direct VoIP stream
195 std::shared_ptr<ProRendererStreamImpl> rendererStream =
196 std::make_shared<ProRendererStreamImpl>(processConfig, isDirectStream);
197 if (rendererStream->InitParams() != SUCCESS) {
198 AUDIO_ERR_LOG("Create rendererStream Failed!");
199 return nullptr;
200 }
201 return rendererStream;
202 }
203
CreateCapturer(AudioProcessConfig processConfig,std::shared_ptr<ICapturerStream> & stream)204 int32_t ProAudioStreamManager::CreateCapturer(AudioProcessConfig processConfig,
205 std::shared_ptr<ICapturerStream> &stream)
206 {
207 AUDIO_ERR_LOG("Unsupported operation: CreateCapturer!");
208 return SUCCESS;
209 }
210
ReleaseCapturer(uint32_t streamIndex)211 int32_t ProAudioStreamManager::ReleaseCapturer(uint32_t streamIndex)
212 {
213 AUDIO_ERR_LOG("Unsupported operation: ReleaseCapturer!");
214 return SUCCESS;
215 }
216
AddUnprocessStream(int32_t appUid)217 int32_t ProAudioStreamManager::AddUnprocessStream(int32_t appUid)
218 {
219 AUDIO_ERR_LOG("Unsupported operation: AddUnprocessStream!");
220 return SUCCESS;
221 }
222
GetLatency()223 uint64_t ProAudioStreamManager::GetLatency() noexcept
224 {
225 CHECK_AND_RETURN_RET_LOG(playbackEngine_ != nullptr, 0, "engine not init!");
226 return playbackEngine_->GetLatency();
227 }
228
GetAllSinkInputs(std::vector<SinkInput> & sinkInputs)229 void ProAudioStreamManager::GetAllSinkInputs(std::vector<SinkInput> &sinkInputs)
230 {
231 // not supported
232 }
233
234 } // namespace AudioStandard
235 } // namespace OHOS