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