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