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 #ifndef LOG_TAG
17 #define LOG_TAG "HpaeRendererManager"
18 #endif
19
20 #include "hpae_renderer_manager.h"
21 #include "audio_stream_info.h"
22 #include "audio_errors.h"
23 #include "hpae_node_common.h"
24 #include "audio_effect_chain_manager.h"
25 #include "audio_utils.h"
26 #include "audio_volume.h"
27 #include "audio_engine_log.h"
28 #include "hpae_output_cluster.h"
29 #include "hpae_remote_output_cluster.h"
30
31 constexpr int32_t DEFAULT_EFFECT_RATE = 48000;
32 constexpr int32_t DEFAULT_EFFECT_FRAME_LEN = 960;
33
34 namespace OHOS {
35 namespace AudioStandard {
36 namespace HPAE {
37
HpaeRendererManager(HpaeSinkInfo & sinkInfo)38 HpaeRendererManager::HpaeRendererManager(HpaeSinkInfo &sinkInfo)
39 : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo)
40 {}
41
~HpaeRendererManager()42 HpaeRendererManager::~HpaeRendererManager()
43 {
44 AUDIO_INFO_LOG("destructor renderer");
45 if (isInit_.load()) {
46 DeInit();
47 }
48 }
49
IsMchDevice()50 bool HpaeRendererManager::IsMchDevice()
51 {
52 return sinkInfo_.deviceName == "MCH_Speaker" || sinkInfo_.deviceName == "DP_MCH_speaker";
53 }
54
CreateInputSession(const HpaeStreamInfo & streamInfo)55 int32_t HpaeRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo)
56 {
57 Trace trace("[" + std::to_string(streamInfo.sessionId) + "]HpaeRendererManager::CreateInputSession");
58 HpaeNodeInfo nodeInfo;
59 nodeInfo.channels = streamInfo.channels;
60 nodeInfo.format = streamInfo.format;
61 nodeInfo.frameLen = streamInfo.frameLen;
62 nodeInfo.channelLayout = (AudioChannelLayout)streamInfo.channelLayout;
63 nodeInfo.streamType = streamInfo.streamType;
64 nodeInfo.sessionId = streamInfo.sessionId;
65 nodeInfo.samplingRate = static_cast<AudioSamplingRate>(streamInfo.samplingRate);
66 nodeInfo.sceneType = TransToProperSceneType(streamInfo.effectInfo.streamUsage, streamInfo.effectInfo.effectScene);
67 nodeInfo.effectInfo = streamInfo.effectInfo;
68 TransNodeInfoForCollaboration(nodeInfo, isCollaborationEnabled_);
69 nodeInfo.fadeType = streamInfo.fadeType;
70 nodeInfo.statusCallback = weak_from_this();
71 nodeInfo.deviceClass = sinkInfo_.deviceClass;
72 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
73 sinkInputNodeMap_[streamInfo.sessionId] = std::make_shared<HpaeSinkInputNode>(nodeInfo);
74 sinkInputNodeMap_[streamInfo.sessionId]->SetAppUid(streamInfo.uid);
75 AUDIO_INFO_LOG("streamType %{public}u, sessionId = %{public}u, current sceneType is %{public}d",
76 nodeInfo.streamType,
77 nodeInfo.sessionId,
78 nodeInfo.sceneType);
79 CreateProcessCluster(nodeInfo);
80 if (!sessionNodeMap_[nodeInfo.sessionId].bypass) {
81 CHECK_AND_RETURN_RET_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType), ERROR,
82 "could not find processorType %{public}d", nodeInfo.sceneType);
83 sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
84 int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
85 if (ret != SUCCESS) {
86 AUDIO_WARNING_LOG("update audio effect when creating failed, ret = %{public}d", ret);
87 }
88 }
89 return SUCCESS;
90 }
91
AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node)92 int32_t HpaeRendererManager::AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node)
93 {
94 auto request = [this, node]() { AddSingleNodeToSink(node); };
95 SendRequest(request);
96 return SUCCESS;
97 }
98
AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node,bool isConnect)99 void HpaeRendererManager::AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node, bool isConnect)
100 {
101 Trace trace("HpaeRendererManager::AddSingleNodeToSink");
102 HpaeNodeInfo nodeInfo = node->GetNodeInfo();
103 nodeInfo.deviceClass = sinkInfo_.deviceClass;
104 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
105 // no need history buffer in not offload sink
106 nodeInfo.historyFrameCount = 0;
107 nodeInfo.statusCallback = weak_from_this();
108 nodeInfo.sceneType = TransToProperSceneType(nodeInfo.effectInfo.streamUsage, nodeInfo.effectInfo.effectScene);
109 // for collaboration
110 TransNodeInfoForCollaboration(nodeInfo, isCollaborationEnabled_);
111 node->SetNodeInfo(nodeInfo);
112 uint32_t sessionId = nodeInfo.sessionId;
113
114 sinkInputNodeMap_[sessionId] = node;
115 SetSessionState(sessionId, node->GetState());
116 sessionNodeMap_[sessionId].sceneType = nodeInfo.sceneType;
117
118 AUDIO_INFO_LOG("[FinishMove] session :%{public}u to sink:%{public}s, sceneType is %{public}d",
119 sessionId, sinkInfo_.deviceClass.c_str(), nodeInfo.sceneType);
120 CreateEffectAndConnect(nodeInfo, isConnect);
121 }
122
CreateEffectAndConnect(HpaeNodeInfo & nodeInfo,bool isConnect)123 void HpaeRendererManager::CreateEffectAndConnect(HpaeNodeInfo &nodeInfo, bool isConnect)
124 {
125 uint32_t sessionId = nodeInfo.sessionId;
126 HpaeNodeInfo processNodeInfo = nodeInfo;
127 processNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE;
128 processNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN;
129 processNodeInfo.channels = STEREO;
130 processNodeInfo.channelLayout = CH_LAYOUT_STEREO;
131 CreateProcessCluster(processNodeInfo);
132 if (!sessionNodeMap_[sessionId].bypass) {
133 CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
134 "could not find processorType %{public}d", nodeInfo.sceneType);
135 sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
136 int32_t ret = sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
137 if (ret != SUCCESS) {
138 AUDIO_WARNING_LOG("session:%{public}u update audio effect when creating failed ret %{public}d",
139 sessionId, ret);
140 }
141 }
142
143 CHECK_AND_RETURN_LOG(isConnect == true, "not need connect session:%{public}d", sessionId);
144 if (sessionNodeMap_[sessionId].state == HPAE_SESSION_RUNNING) {
145 AUDIO_INFO_LOG("session:%{public}u connect to sink:%{public}s",
146 sessionId, sinkInfo_.deviceClass.c_str());
147 ConnectInputSession(sessionId);
148 }
149 }
150
CreateDefaultProcessCluster(HpaeNodeInfo & nodeInfo)151 void HpaeRendererManager::CreateDefaultProcessCluster(HpaeNodeInfo &nodeInfo)
152 {
153 AUDIO_INFO_LOG("use default processCluster");
154 if (sceneClusterMap_.find(HPAE_SCENE_DEFAULT) == sceneClusterMap_.end()) {
155 AUDIO_INFO_LOG("default processCluster is null, create default processCluster");
156 HpaeNodeInfo temp = nodeInfo;
157 temp.sceneType = HPAE_SCENE_DEFAULT;
158 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(temp, sinkInfo_);
159 sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster;
160 sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster;
161 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
162 } else {
163 sceneClusterMap_[nodeInfo.sceneType] = sceneClusterMap_[HPAE_SCENE_DEFAULT];
164 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
165 }
166 return;
167 }
168
CreateProcessClusterInner(HpaeNodeInfo & nodeInfo,int32_t processClusterDecision)169 void HpaeRendererManager::CreateProcessClusterInner(HpaeNodeInfo &nodeInfo, int32_t processClusterDecision)
170 {
171 HpaeNodeInfo temp = nodeInfo;
172 std::shared_ptr<HpaeProcessCluster> hpaeProcessCluster = nullptr;
173 switch (processClusterDecision) {
174 case NO_NEED_TO_CREATE_PROCESSCLUSTER:
175 AUDIO_INFO_LOG("no need to create processCluster");
176 CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
177 AUDIO_INFO_LOG("processCluster is null, create a new processCluster");
178 sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
179 break;
180 case CREATE_NEW_PROCESSCLUSTER:
181 CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
182 AUDIO_INFO_LOG("create new processCluster");
183 sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
184 break;
185 case CREATE_DEFAULT_PROCESSCLUSTER:
186 temp.sceneType = HPAE_SCENE_DEFAULT;
187 if (!SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT)) {
188 AUDIO_INFO_LOG("begin control, create default processCluster");
189 hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(temp, sinkInfo_);
190 sceneClusterMap_[HPAE_SCENE_DEFAULT] = hpaeProcessCluster;
191 sceneClusterMap_[nodeInfo.sceneType] = hpaeProcessCluster;
192 } else {
193 sceneClusterMap_[nodeInfo.sceneType] = sceneClusterMap_[HPAE_SCENE_DEFAULT];
194 }
195 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]++;
196 break;
197 case USE_DEFAULT_PROCESSCLUSTER:
198 CreateDefaultProcessCluster(nodeInfo);
199 break;
200 case USE_NONE_PROCESSCLUSTER:
201 AUDIO_INFO_LOG("use none processCluster");
202 break;
203 case CREATE_EXTRA_PROCESSCLUSTER:
204 AUDIO_INFO_LOG("out of control");
205 CHECK_AND_RETURN(!SafeGetMap(sceneClusterMap_, nodeInfo.sceneType));
206 AUDIO_INFO_LOG("out of control, create a new processCluster");
207 sceneClusterMap_[nodeInfo.sceneType] = std::make_shared<HpaeProcessCluster>(nodeInfo, sinkInfo_);
208 break;
209 default:
210 break;
211 }
212 sessionNodeMap_[nodeInfo.sessionId].bypass = (processClusterDecision == USE_NONE_PROCESSCLUSTER) ? true : false;
213 return;
214 }
215
CreateProcessCluster(HpaeNodeInfo & nodeInfo)216 void HpaeRendererManager::CreateProcessCluster(HpaeNodeInfo &nodeInfo)
217 {
218 Trace trace("HpaeRendererManager::CreateProcessCluster");
219 std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType);
220 int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType);
221 CreateProcessClusterInner(nodeInfo, processClusterDecision);
222 }
223
AddAllNodesToSink(const std::vector<std::shared_ptr<HpaeSinkInputNode>> & sinkInputs,bool isConnect)224 int32_t HpaeRendererManager::AddAllNodesToSink(
225 const std::vector<std::shared_ptr<HpaeSinkInputNode>> &sinkInputs, bool isConnect)
226 {
227 auto request = [this, sinkInputs, isConnect]() {
228 for (const auto &it : sinkInputs) {
229 AddSingleNodeToSink(it, isConnect);
230 }
231 };
232 SendRequest(request);
233 return SUCCESS;
234 }
235
TransToProperSceneType(StreamUsage streamUsage,AudioEffectScene effectScene)236 HpaeProcessorType HpaeRendererManager::TransToProperSceneType(StreamUsage streamUsage, AudioEffectScene effectScene)
237 {
238 if (sinkInfo_.lib == "libmodule-split-stream-sink.z.so") {
239 return TransStreamUsageToSplitSceneType(streamUsage, sinkInfo_.splitMode);
240 } else if (sinkInfo_.deviceClass == "remote" || IsMchDevice()) {
241 return HPAE_SCENE_EFFECT_NONE;
242 } else {
243 return TransEffectSceneToSceneType(effectScene);
244 }
245 }
246
GetProcessorType(uint32_t sessionId)247 HpaeProcessorType HpaeRendererManager::GetProcessorType(uint32_t sessionId)
248 {
249 HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
250 if ((sessionNodeMap_[sessionId].bypass || nodeInfo.effectInfo.effectMode == EFFECT_NONE) &&
251 (!isSplitProcessorType(nodeInfo.sceneType))) {
252 return HPAE_SCENE_EFFECT_NONE;
253 }
254 return nodeInfo.sceneType;
255 }
256
RefreshProcessClusterByDeviceInner(const std::shared_ptr<HpaeSinkInputNode> & node)257 void HpaeRendererManager::RefreshProcessClusterByDeviceInner(const std::shared_ptr<HpaeSinkInputNode> &node)
258 {
259 CHECK_AND_RETURN_LOG(node != nullptr, "sinkInputNode is nullptr");
260 HpaeNodeInfo nodeInfo = node->GetNodeInfo();
261 std::string sceneType = TransProcessorTypeToSceneType(nodeInfo.sceneType);
262 int32_t processClusterDecision = AudioEffectChainManager::GetInstance()->CheckProcessClusterInstances(sceneType);
263 bool isConnected = (node->isConnected_) ? true : false;
264 if (processClusterDecision != USE_NONE_PROCESSCLUSTER && sessionNodeMap_[nodeInfo.sessionId].bypass) {
265 DeleteConnectInputProcessor(sinkInputNodeMap_[nodeInfo.sessionId]);
266 DeleteProcessCluster(GetProcessorType(nodeInfo.sessionId));
267 CreateProcessClusterInner(nodeInfo, processClusterDecision);
268 CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
269 "could not find processorType %{public}d", nodeInfo.sceneType);
270 sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]++;
271 sceneClusterMap_[nodeInfo.sceneType]->AudioRendererCreate(nodeInfo);
272 if (isConnected) {
273 ConnectInputSession(nodeInfo.sessionId);
274 }
275 } else if (processClusterDecision == USE_NONE_PROCESSCLUSTER && !sessionNodeMap_[nodeInfo.sessionId].bypass) {
276 DeleteConnectInputProcessor(sinkInputNodeMap_[nodeInfo.sessionId]);
277 DeleteProcessCluster(GetProcessorType(nodeInfo.sessionId));
278 sessionNodeMap_[nodeInfo.sessionId].bypass = true;
279 if (isConnected) {
280 ConnectInputSession(nodeInfo.sessionId);
281 }
282 }
283 }
284
RefreshProcessClusterByDevice()285 int32_t HpaeRendererManager::RefreshProcessClusterByDevice()
286 {
287 auto request = [this]() {
288 for (const auto &it : sinkInputNodeMap_) {
289 RefreshProcessClusterByDeviceInner(it.second);
290 }
291 };
292 SendRequest(request);
293 return SUCCESS;
294 }
295
CreateStream(const HpaeStreamInfo & streamInfo)296 int32_t HpaeRendererManager::CreateStream(const HpaeStreamInfo &streamInfo)
297 {
298 if (!IsInit()) {
299 return ERR_INVALID_OPERATION;
300 }
301 auto request = [this, streamInfo]() {
302 Trace trace("HpaeRendererManager::CreateStream id[" +
303 std::to_string(streamInfo.sessionId) + "]");
304 AUDIO_INFO_LOG("CreateStream sessionId %{public}u deviceName %{public}s",
305 streamInfo.sessionId,
306 sinkInfo_.deviceName.c_str());
307 CreateInputSession(streamInfo);
308 SetSessionState(streamInfo.sessionId, HPAE_SESSION_PREPARED);
309 sessionNodeMap_[streamInfo.sessionId].isMoveAble = streamInfo.isMoveAble;
310 sinkInputNodeMap_[streamInfo.sessionId]->SetState(HPAE_SESSION_PREPARED);
311 };
312 SendRequest(request);
313 return SUCCESS;
314 }
315
DestroyStream(uint32_t sessionId)316 int32_t HpaeRendererManager::DestroyStream(uint32_t sessionId)
317 {
318 if (!IsInit()) {
319 return ERR_INVALID_OPERATION;
320 }
321 auto request = [this, sessionId]() {
322 Trace trace("HpaeRendererManager::DestroyStream id[" +
323 std::to_string(sessionId) + "]");
324 AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId);
325 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
326 "Release not find sessionId %{public}u", sessionId);
327 SetSessionState(sessionId, HPAE_SESSION_RELEASED);
328 sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RELEASED);
329 DeleteInputSession(sessionId);
330 };
331 SendRequest(request);
332 return SUCCESS;
333 }
334
DeleteConnectInputProcessor(const std::shared_ptr<HpaeSinkInputNode> & sinkInputNode)335 int32_t HpaeRendererManager::DeleteConnectInputProcessor(
336 const std::shared_ptr<HpaeSinkInputNode> &sinkInputNode)
337 {
338 uint32_t sessionId = sinkInputNode->GetSessionId();
339 HpaeNodeInfo nodeInfo = sinkInputNode->GetNodeInfo();
340 HpaeProcessorType sceneType = GetProcessorType(sessionId);
341 if (SafeGetMap(sceneClusterMap_, sceneType)) {
342 DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
343 }
344 return SUCCESS;
345 }
346
DeleteInputSession(uint32_t sessionId)347 int32_t HpaeRendererManager::DeleteInputSession(uint32_t sessionId)
348 {
349 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSession");
350 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
351 AUDIO_INFO_LOG("could not find session:%{public}d", sessionId);
352 return SUCCESS;
353 }
354 DeleteConnectInputProcessor(sinkInputNodeMap_[sessionId]);
355 sinkInputNodeMap_.erase(sessionId);
356 sessionNodeMap_.erase(sessionId);
357 return SUCCESS;
358 }
359
360
DeleteInputSessionForMove(uint32_t sessionId)361 int32_t HpaeRendererManager::DeleteInputSessionForMove(uint32_t sessionId)
362 {
363 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::DeleteInputSessionForMove");
364 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
365 AUDIO_INFO_LOG("could not find session:%{public}d", sessionId);
366 return SUCCESS;
367 }
368 HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
369 HpaeProcessorType sceneType = GetProcessorType(sessionId);
370 if (SafeGetMap(sceneClusterMap_, sceneType)) {
371 DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
372 if (sceneClusterMap_[sceneType]->GetPreOutNum() == 0) {
373 sceneClusterMap_[sceneType]->DisConnectMixerNode();
374 outputCluster_->DisConnect(sceneClusterMap_[sceneType]);
375 // for collaboration
376 if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
377 hpaeCoBufferNode_->DisConnect(sceneClusterMap_[sceneType]);
378 TriggerCallback(DISCONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
379 }
380 sceneClusterMap_[sceneType]->SetConnectedFlag(false);
381 }
382 }
383 DeleteProcessCluster(sceneType);
384 sinkInputNodeMap_.erase(sessionId);
385 sessionNodeMap_.erase(sessionId);
386 return SUCCESS;
387 }
388
DisConnectProcessCluster(const HpaeNodeInfo & nodeInfo,HpaeProcessorType sceneType,uint32_t sessionId)389 void HpaeRendererManager::DisConnectProcessCluster(
390 const HpaeNodeInfo &nodeInfo, HpaeProcessorType sceneType, uint32_t sessionId)
391 {
392 Trace trace("[" + std::to_string(sessionId) +
393 "]HpaeRendererManager::DisConnectProcessCluster sceneType:" + std::to_string(sceneType));
394 if (!sessionNodeMap_[sessionId].bypass) {
395 CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, nodeInfo.sceneType),
396 "could not find processorType %{public}d", nodeInfo.sceneType);
397 sceneClusterMap_[nodeInfo.sceneType]->AudioRendererRelease(sinkInputNodeMap_[sessionId]->GetNodeInfo());
398 }
399 sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]);
400 sinkInputNodeMap_[sessionId]->isConnected_ = false;
401 if (!sessionNodeMap_[sessionId].bypass) {
402 sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType]--;
403 if (sceneClusterMap_[nodeInfo.sceneType] == sceneClusterMap_[HPAE_SCENE_DEFAULT]) {
404 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]--;
405 }
406 AUDIO_INFO_LOG("sceneType %{public}d is deleted, current count: %{public}d, default count: %{public}d",
407 nodeInfo.sceneType, sceneTypeToProcessClusterCountMap_[nodeInfo.sceneType],
408 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT]);
409 }
410 }
411
DeleteProcessCluster(HpaeProcessorType sceneType)412 int32_t HpaeRendererManager::DeleteProcessCluster(HpaeProcessorType sceneType)
413 {
414 if (sceneTypeToProcessClusterCountMap_[sceneType] == 0) {
415 sceneClusterMap_.erase(sceneType);
416 sceneTypeToProcessClusterCountMap_.erase(sceneType);
417 }
418 if (sceneTypeToProcessClusterCountMap_[HPAE_SCENE_DEFAULT] == 0) {
419 sceneClusterMap_.erase(HPAE_SCENE_DEFAULT);
420 sceneTypeToProcessClusterCountMap_.erase(HPAE_SCENE_DEFAULT);
421 }
422 return SUCCESS;
423 }
424
isSplitProcessorType(HpaeProcessorType sceneType)425 bool HpaeRendererManager::isSplitProcessorType(HpaeProcessorType sceneType)
426 {
427 if (sceneType == HPAE_SCENE_SPLIT_MEDIA || sceneType == HPAE_SCENE_SPLIT_NAVIGATION ||
428 sceneType == HPAE_SCENE_SPLIT_COMMUNICATION) {
429 return true;
430 }
431 return false;
432 }
433
ConnectInputSession(uint32_t sessionId)434 int32_t HpaeRendererManager::ConnectInputSession(uint32_t sessionId)
435 {
436 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectInputSession");
437 AUDIO_INFO_LOG("connect input session:%{public}d", sessionId);
438 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
439 AUDIO_INFO_LOG("could not input node by sessionid:%{public}d", sessionId);
440 return ERR_INVALID_PARAM;
441 }
442 if (sinkInputNodeMap_[sessionId]->GetState() != HPAE_SESSION_RUNNING) {
443 return SUCCESS;
444 }
445 HpaeProcessorType sceneType = GetProcessorType(sessionId);
446 if (SafeGetMap(sceneClusterMap_, sceneType)) {
447 ConnectProcessCluster(sessionId, sceneType);
448 }
449 if (outputCluster_->GetState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
450 outputCluster_->Start();
451 }
452 return SUCCESS;
453 }
454
ConnectProcessCluster(uint32_t sessionId,HpaeProcessorType sceneType)455 void HpaeRendererManager::ConnectProcessCluster(uint32_t sessionId, HpaeProcessorType sceneType)
456 {
457 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::ConnectProcessCluster sceneType:"
458 + std::to_string(sceneType));
459 HpaeProcessorType tmpSceneType = (sceneClusterMap_[sceneType] == SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT))
460 ? HPAE_SCENE_DEFAULT : sceneType;
461 if (toBeStoppedSceneTypeToSessionMap_.count(tmpSceneType) > 0) {
462 uint32_t sessionIdToStop = toBeStoppedSceneTypeToSessionMap_[tmpSceneType];
463 if (sessionIdToStop == sessionId) {
464 toBeStoppedSceneTypeToSessionMap_.erase(tmpSceneType);
465 } else {
466 if (SafeGetMap(sinkInputNodeMap_, sessionIdToStop)) {
467 sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionIdToStop]->GetNodeInfo());
468 }
469 toBeStoppedSceneTypeToSessionMap_.erase(tmpSceneType);
470 int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo());
471 if (ret != SUCCESS) {
472 AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret);
473 }
474 }
475 } else {
476 int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStart(sinkInputNodeMap_[sessionId]->GetNodeInfo());
477 if (ret != SUCCESS) {
478 AUDIO_WARNING_LOG("update audio effect when starting failed, ret = %{public}d", ret);
479 }
480 }
481 if (!outputCluster_->IsProcessClusterConnected(sceneType) && !sceneClusterMap_[sceneType]->GetConnectedFlag()) {
482 outputCluster_->Connect(sceneClusterMap_[sceneType]);
483 sceneClusterMap_[sceneType]->SetConnectedFlag(true);
484 }
485 sceneClusterMap_[sceneType]->Connect(sinkInputNodeMap_[sessionId]);
486 sinkInputNodeMap_[sessionId]->isConnected_ = true;
487 if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
488 uint32_t latency = outputCluster_->GetLatency();
489 hpaeCoBufferNode_->SetLatency(latency);
490 hpaeCoBufferNode_->Connect(sceneClusterMap_[sceneType]);
491 TriggerCallback(CONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
492 }
493 std::shared_ptr<HpaeSinkInputNode> sinkInputNode = SafeGetMap(sinkInputNodeMap_, sessionId);
494 CHECK_AND_RETURN_LOG(sinkInputNode != nullptr, "sinkInputNode is nullptr");
495 sceneClusterMap_[sceneType]->SetLoudnessGain(sessionId, sinkInputNode->GetLoudnessGain());
496 }
497
MoveAllStreamToNewSink(const std::string & sinkName,const std::vector<uint32_t> & moveIds,MoveSessionType moveType)498 void HpaeRendererManager::MoveAllStreamToNewSink(const std::string &sinkName,
499 const std::vector<uint32_t>& moveIds, MoveSessionType moveType)
500 {
501 Trace trace("HpaeRendererManager::MoveAllStreamToNewSink[" + sinkName + "]");
502 std::string name = sinkName;
503 std::vector<std::shared_ptr<HpaeSinkInputNode>> sinkInputs;
504 std::vector<uint32_t> sessionIds;
505 std::string idStr;
506 for (const auto &it : sinkInputNodeMap_) {
507 if (moveType == MOVE_ALL || std::find(moveIds.begin(), moveIds.end(), it.first) != moveIds.end()) {
508 sinkInputs.emplace_back(it.second);
509 sessionIds.emplace_back(it.first);
510 idStr.append("[").append(std::to_string(it.first)).append("],");
511 }
512 }
513 for (const auto &it : sessionIds) {
514 DeleteInputSessionForMove(it);
515 }
516 AUDIO_INFO_LOG("[StartMove] session:%{public}s to sink name:%{public}s, move type:%{public}d",
517 idStr.c_str(), name.c_str(), moveType);
518 TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name, moveType);
519 }
520
MoveAllStream(const std::string & sinkName,const std::vector<uint32_t> & sessionIds,MoveSessionType moveType)521 int32_t HpaeRendererManager::MoveAllStream(const std::string &sinkName, const std::vector<uint32_t>& sessionIds,
522 MoveSessionType moveType)
523 {
524 if (!IsInit()) {
525 AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str());
526 MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
527 } else {
528 AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str());
529 auto request = [this, sinkName, sessionIds, moveType]() {
530 MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
531 };
532 SendRequest(request);
533 }
534 return SUCCESS;
535 }
536
MoveStreamSync(uint32_t sessionId,const std::string & sinkName)537 void HpaeRendererManager::MoveStreamSync(uint32_t sessionId, const std::string &sinkName)
538 {
539 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
540 AUDIO_ERR_LOG("[StartMove] session:%{public}u failed,can not find session,move %{public}s --> %{public}s",
541 sessionId, sinkInfo_.deviceName.c_str(), sinkName.c_str());
542 TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
543 return;
544 }
545
546 if (sinkName.empty()) {
547 AUDIO_ERR_LOG("[StartMove] session:%{public}u failed,sinkName is empty", sessionId);
548 TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
549 return;
550 }
551
552 AUDIO_INFO_LOG("[StartMove] session: %{public}u,sink [%{public}s] --> [%{public}s]",
553 sessionId, sinkInfo_.deviceName.c_str(), sinkName.c_str());
554 std::shared_ptr<HpaeSinkInputNode> inputNode = sinkInputNodeMap_[sessionId];
555 HpaeSessionState inputState = inputNode->GetState();
556 if (inputState == HPAE_SESSION_STOPPING || inputState == HPAE_SESSION_PAUSING) {
557 HpaeSessionState state = inputState == HPAE_SESSION_PAUSING ? HPAE_SESSION_PAUSED : HPAE_SESSION_STOPPED;
558 IOperation operation = inputState == HPAE_SESSION_PAUSING ? OPERATION_PAUSED : OPERATION_STOPPED;
559 SetSessionState(sessionId, state);
560 inputNode->SetState(state);
561 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
562 // todo: do fade out
563 }
564 DeleteInputSessionForMove(sessionId);
565 std::string name = sinkName;
566 TriggerCallback(MOVE_SINK_INPUT, inputNode, name);
567 }
568
MoveStream(uint32_t sessionId,const std::string & sinkName)569 int32_t HpaeRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName)
570 {
571 if (!IsInit()) {
572 MoveStreamSync(sessionId, sinkName);
573 } else {
574 auto request = [this, sessionId, sinkName]() { MoveStreamSync(sessionId, sinkName); };
575 SendRequest(request);
576 }
577 return SUCCESS;
578 }
579
Start(uint32_t sessionId)580 int32_t HpaeRendererManager::Start(uint32_t sessionId)
581 {
582 auto request = [this, sessionId]() {
583 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Start");
584 AUDIO_INFO_LOG("Start sessionId %{public}u, deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
585 if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
586 sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RUNNING);
587 }
588 HandlePriPaPower(sessionId);
589 ConnectInputSession(sessionId);
590 SetSessionState(sessionId, HPAE_SESSION_RUNNING);
591 SetSessionFade(sessionId, OPERATION_STARTED);
592 };
593 SendRequest(request);
594 return SUCCESS;
595 }
596
StartWithSyncId(uint32_t sessionId,int32_t syncId)597 int32_t HpaeRendererManager::StartWithSyncId(uint32_t sessionId, int32_t syncId)
598 {
599 auto request = [this, sessionId, syncId]() {
600 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::StartWithSyncId");
601 AUDIO_INFO_LOG("StartWithSyncId sessionId %{public}u, deviceName %{public}s",
602 sessionId, sinkInfo_.deviceName.c_str());
603 if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
604 sinkInputNodeMap_[sessionId]->SetState(HPAE_SESSION_RUNNING);
605 }
606 HandlePriPaPower(sessionId);
607 ConnectInputSession(sessionId);
608 SetSessionState(sessionId, HPAE_SESSION_RUNNING);
609 SetSessionFade(sessionId, OPERATION_STARTED);
610 if (syncId >= 0) {
611 HandleSyncId(sessionId, syncId);
612 }
613 };
614 SendRequest(request);
615 return SUCCESS;
616 }
617
DisConnectInputSession(uint32_t sessionId)618 int32_t HpaeRendererManager::DisConnectInputSession(uint32_t sessionId)
619 {
620 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
621 AUDIO_INFO_LOG("DisConnectInputSession sessionId %{public}u", sessionId);
622 return SUCCESS;
623 }
624 HpaeProcessorType sceneType = GetProcessorType(sessionId);
625 if (SafeGetMap(sceneClusterMap_, sceneType)) {
626 DisConnectInputCluster(sessionId, sceneType);
627 }
628 return SUCCESS;
629 }
630
OnDisConnectProcessCluster(HpaeProcessorType sceneType)631 void HpaeRendererManager::OnDisConnectProcessCluster(HpaeProcessorType sceneType)
632 {
633 auto request = [this, sceneType]() {
634 AUDIO_INFO_LOG("mixerNode trigger callback, sceneType %{public}d", sceneType);
635 if (SafeGetMap(sceneClusterMap_, sceneType) && sceneClusterMap_[sceneType]->GetPreOutNum() == 0) {
636 sceneClusterMap_[sceneType]->DisConnectMixerNode();
637 // for collaboration
638 if (sceneType == HPAE_SCENE_COLLABORATIVE && hpaeCoBufferNode_ != nullptr) {
639 hpaeCoBufferNode_->DisConnect(sceneClusterMap_[sceneType]);
640 TriggerCallback(DISCONNECT_CO_BUFFER_NODE, hpaeCoBufferNode_);
641 }
642 outputCluster_->DisConnect(sceneClusterMap_[sceneType]);
643 sceneClusterMap_[sceneType]->SetConnectedFlag(false);
644 if (toBeStoppedSceneTypeToSessionMap_.count(sceneType) &&
645 SafeGetMap(sinkInputNodeMap_, toBeStoppedSceneTypeToSessionMap_[sceneType])) {
646 sceneClusterMap_[sceneType]->
647 AudioRendererStop(sinkInputNodeMap_[toBeStoppedSceneTypeToSessionMap_[sceneType]]->GetNodeInfo());
648 }
649 toBeStoppedSceneTypeToSessionMap_.erase(sceneType);
650 }
651 DeleteProcessCluster(sceneType);
652 };
653 SendRequest(request);
654 }
655
DisConnectInputCluster(uint32_t sessionId,HpaeProcessorType sceneType)656 void HpaeRendererManager::DisConnectInputCluster(uint32_t sessionId, HpaeProcessorType sceneType)
657 {
658 sceneClusterMap_[sceneType]->DisConnect(sinkInputNodeMap_[sessionId]);
659 sinkInputNodeMap_[sessionId]->isConnected_ = false;
660 if (sceneClusterMap_[sceneType]->GetPreOutNum() > 0) {
661 int32_t ret = sceneClusterMap_[sceneType]->AudioRendererStop(sinkInputNodeMap_[sessionId]->GetNodeInfo());
662 if (ret != SUCCESS) {
663 AUDIO_WARNING_LOG("update audio effect when stopping failed, ret = %{public}d", ret);
664 }
665 } else {
666 HpaeProcessorType tmpSceneType = (sceneClusterMap_[sceneType] ==
667 SafeGetMap(sceneClusterMap_, HPAE_SCENE_DEFAULT)) ? HPAE_SCENE_DEFAULT : sceneType;
668 CHECK_AND_RETURN_LOG(toBeStoppedSceneTypeToSessionMap_.count(sceneType) == 0,
669 "sessionId %{public}d to stop already existed", sessionId);
670 toBeStoppedSceneTypeToSessionMap_[tmpSceneType] = sessionId;
671 AUDIO_INFO_LOG("sessionId %{public}u will be stop", sessionId);
672 }
673 }
674
SetSessionState(uint32_t sessionId,HpaeSessionState renderState)675 void HpaeRendererManager::SetSessionState(uint32_t sessionId, HpaeSessionState renderState)
676 {
677 sessionNodeMap_[sessionId].state = renderState;
678 }
679
Pause(uint32_t sessionId)680 int32_t HpaeRendererManager::Pause(uint32_t sessionId)
681 {
682 auto request = [this, sessionId]() {
683 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Pause");
684 AUDIO_INFO_LOG("Pause sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
685 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
686 "Pause not find sessionId %{public}u", sessionId);
687 if (!SetSessionFade(sessionId, OPERATION_PAUSED)) {
688 DisConnectInputSession(sessionId);
689 }
690 };
691 SendRequest(request);
692 return SUCCESS;
693 }
694
Flush(uint32_t sessionId)695 int32_t HpaeRendererManager::Flush(uint32_t sessionId)
696 {
697 auto request = [this, sessionId]() {
698 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Flush");
699 AUDIO_INFO_LOG("Flush sessionId %{public}u deviceName %{public}s", sessionId, sinkInfo_.deviceName.c_str());
700 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
701 "Flush not find sessionId %{public}u", sessionId);
702 // flush history buffer
703 sinkInputNodeMap_[sessionId]->Flush();
704 HpaeProcessorType sceneType = GetProcessorType(sessionId);
705 CHECK_AND_RETURN_LOG(SafeGetMap(sceneClusterMap_, sceneType),
706 "Flush not find sceneType: %{public}d in sceneClusterMap", static_cast<int32_t>(sceneType));
707 sceneClusterMap_[sceneType]->InitEffectBuffer(sessionId);
708 };
709 SendRequest(request);
710 return SUCCESS;
711 }
712
Drain(uint32_t sessionId)713 int32_t HpaeRendererManager::Drain(uint32_t sessionId)
714 {
715 auto request = [this, sessionId]() {
716 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Drain");
717 AUDIO_INFO_LOG("Drain sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str());
718 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
719 "Drain not find sessionId %{public}u", sessionId);
720 sinkInputNodeMap_[sessionId]->Drain();
721 if (sessionNodeMap_[sessionId].state != HPAE_SESSION_RUNNING) {
722 AUDIO_INFO_LOG("TriggerCallback Drain sessionId %{public}u", sessionId);
723 TriggerCallback(UPDATE_STATUS,
724 HPAE_STREAM_CLASS_TYPE_PLAY,
725 sessionId,
726 sessionNodeMap_[sessionId].state,
727 OPERATION_DRAINED);
728 }
729 };
730 SendRequest(request);
731 return SUCCESS;
732 }
733
Stop(uint32_t sessionId)734 int32_t HpaeRendererManager::Stop(uint32_t sessionId)
735 {
736 auto request = [this, sessionId]() {
737 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Stop");
738 AUDIO_INFO_LOG("Stop sessionId %{public}u deviceName %{public}s ", sessionId, sinkInfo_.deviceName.c_str());
739 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
740 "Stop not find sessionId %{public}u", sessionId);
741 if (!SetSessionFade(sessionId, OPERATION_STOPPED)) {
742 DisConnectInputSession(sessionId);
743 }
744 };
745 SendRequest(request);
746 return SUCCESS;
747 }
748
Release(uint32_t sessionId)749 int32_t HpaeRendererManager::Release(uint32_t sessionId)
750 {
751 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::Release");
752 CHECK_AND_RETURN_RET_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), ERROR,
753 "Release not find sessionId %{public}u", sessionId);
754 return DestroyStream(sessionId);
755 }
756
CheckIsStreamRunning()757 bool HpaeRendererManager::CheckIsStreamRunning()
758 {
759 bool isRunning = false;
760 for (const auto& it : sessionNodeMap_) {
761 if (it.second.state == HPAE_SESSION_RUNNING) {
762 isRunning = true;
763 break;
764 }
765 }
766 return isRunning;
767 }
768
SuspendStreamManager(bool isSuspend)769 int32_t HpaeRendererManager::SuspendStreamManager(bool isSuspend)
770 {
771 Trace trace("HpaeRendererManager::SuspendStreamManager: " + std::to_string(isSuspend));
772 auto request = [this, isSuspend]() {
773 if (isSuspend_ == isSuspend) {
774 return;
775 }
776 AUDIO_INFO_LOG("suspend audio device: %{public}s, isSuspend: %{public}d",
777 sinkInfo_.deviceName.c_str(), isSuspend);
778 isSuspend_ = isSuspend;
779 if (isSuspend_) {
780 if (outputCluster_ != nullptr) {
781 outputCluster_->Stop();
782 }
783 } else if (outputCluster_ != nullptr && outputCluster_->GetState() != STREAM_MANAGER_RUNNING &&
784 CheckIsStreamRunning()) {
785 outputCluster_->Start();
786 }
787 };
788 SendRequest(request);
789 return SUCCESS;
790 }
791
SetMute(bool isMute)792 int32_t HpaeRendererManager::SetMute(bool isMute)
793 {
794 // to do check pulseaudio
795 auto request = [this, isMute]() {
796 if (isMute_ != isMute) {
797 isMute_ = isMute; // todo: fadein and fadeout and mute feature
798 }
799 };
800 SendRequest(request);
801 return SUCCESS;
802 }
803
HandleMsg()804 void HpaeRendererManager::HandleMsg()
805 {
806 hpaeNoLockQueue_.HandleRequests();
807 }
808
ReloadRenderManager(const HpaeSinkInfo & sinkInfo,bool isReload)809 int32_t HpaeRendererManager::ReloadRenderManager(const HpaeSinkInfo &sinkInfo, bool isReload)
810 {
811 if (IsInit()) {
812 AUDIO_INFO_LOG("deinit:%{public}s renderer first.", sinkInfo.deviceName.c_str());
813 DeInit();
814 }
815 hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
816 auto request = [this, sinkInfo, isReload]() {
817 AUDIO_INFO_LOG("ReloadRenderManager deviceName %{public}s", sinkInfo.deviceName.c_str());
818
819 for (const auto &it : sinkInputNodeMap_) {
820 DeleteConnectInputProcessor(it.second);
821 }
822 AUDIO_INFO_LOG("delete device:%{public}s all input processor end", sinkInfo.deviceName.c_str());
823 sinkInfo_ = sinkInfo;
824 InitManager(isReload);
825 AUDIO_INFO_LOG("init device:%{public}s manager end", sinkInfo.deviceName.c_str());
826 for (const auto &it : sinkInputNodeMap_) {
827 HpaeNodeInfo nodeInfo = it.second->GetNodeInfo();
828 CreateEffectAndConnect(nodeInfo);
829 }
830 AUDIO_INFO_LOG("connect device:%{public}s all processor end", sinkInfo.deviceName.c_str());
831 };
832 SendRequest(request, true);
833 hpaeSignalProcessThread_->ActivateThread(shared_from_this());
834 return SUCCESS;
835 }
836
InitManager(bool isReload)837 void HpaeRendererManager::InitManager(bool isReload)
838 {
839 AUDIO_INFO_LOG("init devicename:%{public}s", sinkInfo_.deviceName.c_str());
840 HpaeNodeInfo nodeInfo;
841 nodeInfo.channels = sinkInfo_.channels;
842 nodeInfo.format = sinkInfo_.format;
843 nodeInfo.frameLen = sinkInfo_.frameLen;
844 nodeInfo.nodeId = 0;
845 nodeInfo.samplingRate = sinkInfo_.samplingRate;
846 nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT;
847 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
848 nodeInfo.deviceClass = sinkInfo_.deviceClass;
849 nodeInfo.statusCallback = weak_from_this();
850 if (sinkInfo_.lib == "libmodule-split-stream-sink.z.so") {
851 outputCluster_ = std::make_unique<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo_);
852 } else {
853 outputCluster_ = std::make_unique<HpaeOutputCluster>(nodeInfo);
854 }
855 outputCluster_->SetTimeoutStopThd(sinkInfo_.suspendTime);
856 int32_t ret = outputCluster_->GetInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId);
857 IAudioSinkAttr attr;
858 attr.adapterName = sinkInfo_.adapterName.c_str();
859 attr.sampleRate = sinkInfo_.samplingRate;
860 attr.channel = sinkInfo_.channels;
861 attr.format = sinkInfo_.format;
862 attr.channelLayout = sinkInfo_.channelLayout;
863 attr.deviceType = sinkInfo_.deviceType;
864 attr.volume = sinkInfo_.volume;
865 attr.openMicSpeaker = sinkInfo_.openMicSpeaker;
866 attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str();
867 attr.filePath = sinkInfo_.filePath.c_str();
868 attr.aux = sinkInfo_.splitMode.c_str();
869 if (!sceneClusterMap_.count(HPAE_SCENE_EFFECT_NONE)) {
870 HpaeNodeInfo defaultNodeInfo;
871 defaultNodeInfo.frameLen = (uint32_t)DEFAULT_EFFECT_FRAME_LEN;
872 defaultNodeInfo.samplingRate = (AudioSamplingRate)DEFAULT_EFFECT_RATE;
873 defaultNodeInfo.format = AudioSampleFormat::INVALID_WIDTH;
874 defaultNodeInfo.channels = STEREO;
875 defaultNodeInfo.channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO;
876 defaultNodeInfo.streamType = STREAM_DEFAULT;
877 defaultNodeInfo.sceneType = HPAE_SCENE_EFFECT_NONE;
878 defaultNodeInfo.deviceNetId = sinkInfo_.deviceNetId;
879 defaultNodeInfo.deviceClass = sinkInfo_.deviceClass;
880 defaultNodeInfo.statusCallback = weak_from_this();
881 sceneClusterMap_[HPAE_SCENE_EFFECT_NONE] = std::make_shared<HpaeProcessCluster>(defaultNodeInfo, sinkInfo_);
882 sceneTypeToProcessClusterCountMap_[HPAE_SCENE_EFFECT_NONE] = 1;
883 }
884
885 ret = outputCluster_->Init(attr);
886 isInit_.store(ret == SUCCESS);
887 TriggerCallback(isReload ? RELOAD_AUDIO_SINK_RESULT :INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret);
888 }
889
CreateOutputClusterNodeInfo(HpaeNodeInfo & nodeInfo)890 void HpaeRendererManager::CreateOutputClusterNodeInfo(HpaeNodeInfo &nodeInfo)
891 {
892 nodeInfo.channels = sinkInfo_.channels;
893 nodeInfo.format = sinkInfo_.format;
894 nodeInfo.frameLen = sinkInfo_.frameLen;
895 nodeInfo.nodeId = 0;
896 nodeInfo.samplingRate = sinkInfo_.samplingRate;
897 nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT;
898 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
899 nodeInfo.deviceClass = sinkInfo_.deviceClass;
900 nodeInfo.statusCallback = weak_from_this();
901 return;
902 }
903
Init(bool isReload)904 int32_t HpaeRendererManager::Init(bool isReload)
905 {
906 hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
907 auto request = [this, isReload] {
908 Trace trace("HpaeRendererManager::Init");
909 InitManager(isReload);
910 };
911 SendRequest(request, true);
912 hpaeSignalProcessThread_->ActivateThread(shared_from_this());
913 return SUCCESS;
914 }
915
DeactivateThread()916 bool HpaeRendererManager::DeactivateThread()
917 {
918 if (hpaeSignalProcessThread_ != nullptr) {
919 hpaeSignalProcessThread_->DeactivateThread();
920 hpaeSignalProcessThread_ = nullptr;
921 }
922 hpaeNoLockQueue_.HandleRequests();
923 return true;
924 }
925
DeInit(bool isMoveDefault)926 int32_t HpaeRendererManager::DeInit(bool isMoveDefault)
927 {
928 Trace trace("HpaeRendererManager::DeInit");
929 if (hpaeSignalProcessThread_ != nullptr) {
930 hpaeSignalProcessThread_->DeactivateThread();
931 hpaeSignalProcessThread_ = nullptr;
932 }
933 hpaeNoLockQueue_.HandleRequests();
934 if (isMoveDefault) {
935 std::string sinkName = "";
936 std::vector<uint32_t> ids;
937 AUDIO_INFO_LOG("move all sink to default sink");
938 MoveAllStreamToNewSink(sinkName, ids, MOVE_ALL);
939 }
940 if (outputCluster_ != nullptr) {
941 outputCluster_->Stop();
942 outputCluster_->DeInit();
943 }
944 for (const auto &item : sceneClusterMap_) {
945 if (item.second) {
946 item.second->SetConnectedFlag(false);
947 }
948 }
949 if (outputCluster_ != nullptr) {
950 outputCluster_->ResetAll();
951 outputCluster_ = nullptr;
952 }
953 isInit_.store(false);
954 return SUCCESS;
955 }
956
StartRenderSink()957 int32_t HpaeRendererManager::StartRenderSink()
958 {
959 return SUCCESS;
960 }
961
SetClientVolume(uint32_t sessionId,float volume)962 int32_t HpaeRendererManager::SetClientVolume(uint32_t sessionId, float volume)
963 {
964 return SUCCESS;
965 }
966
SetLoudnessGain(uint32_t sessionId,float loudnessGain)967 int32_t HpaeRendererManager::SetLoudnessGain(uint32_t sessionId, float loudnessGain)
968 {
969 auto request = [this, sessionId, loudnessGain] {
970 AUDIO_INFO_LOG("set loudnessGain %{public}f to sessionId %{public}d", loudnessGain, sessionId);
971 std::shared_ptr<HpaeSinkInputNode> sinkInputNode = SafeGetMap(sinkInputNodeMap_, sessionId);
972 CHECK_AND_RETURN_LOG(sinkInputNode != nullptr,
973 "session with Id %{public}d not in sinkInputNodeMap_", sessionId);
974 sinkInputNode->SetLoudnessGain(loudnessGain);
975
976 HpaeProcessorType processorType = GetProcessorType(sessionId);
977 std::shared_ptr<HpaeProcessCluster> processCluster = SafeGetMap(sceneClusterMap_, processorType);
978 CHECK_AND_RETURN_LOG(processCluster != nullptr,
979 "session with Id %{public}d not in sceneClusterMap_", sessionId);
980 processCluster->SetLoudnessGain(sessionId, loudnessGain);
981 };
982 SendRequest(request);
983 return SUCCESS;
984 }
985
SetRate(uint32_t sessionId,int32_t rate)986 int32_t HpaeRendererManager::SetRate(uint32_t sessionId, int32_t rate)
987 {
988 return SUCCESS;
989 }
990
SetAudioEffectMode(uint32_t sessionId,int32_t effectMode)991 int32_t HpaeRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode)
992 {
993 if (effectMode < EFFECT_NONE || effectMode > EFFECT_DEFAULT) {
994 return ERR_INVALID_OPERATION;
995 }
996 auto request = [this, sessionId, effectMode]() {
997 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
998 AUDIO_WARNING_LOG("miss corresponding sinkInputNode for sessionId %{public}d", sessionId);
999 return ;
1000 }
1001 HpaeNodeInfo &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1002 if (nodeInfo.effectInfo.effectMode != static_cast<AudioEffectMode>(effectMode)) {
1003 nodeInfo.effectInfo.effectMode = static_cast<AudioEffectMode>(effectMode);
1004 size_t sinkInputNodeConnectNum = sinkInputNodeMap_[sessionId]->GetOutputPort()->GetInputNum();
1005 if (sinkInputNodeConnectNum != 0) {
1006 AUDIO_INFO_LOG("UpdateProcessClusterConnection because effectMode to be %{public}d", effectMode);
1007 UpdateProcessClusterConnection(sessionId, effectMode);
1008 } else {
1009 AUDIO_INFO_LOG("no need to ProcessClusterConnection, sinkInputNodeConnectNum is %{public}zu",
1010 sinkInputNodeConnectNum);
1011 }
1012 }
1013 };
1014 SendRequest(request);
1015 return SUCCESS;
1016 }
1017
GetAudioEffectMode(uint32_t sessionId,int32_t & effectMode)1018 int32_t HpaeRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode)
1019 {
1020 return SUCCESS;
1021 }
1022
SetPrivacyType(uint32_t sessionId,int32_t privacyType)1023 int32_t HpaeRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType)
1024 {
1025 return SUCCESS;
1026 }
1027
GetPrivacyType(uint32_t sessionId,int32_t & privacyType)1028 int32_t HpaeRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType)
1029 {
1030 return SUCCESS;
1031 }
1032
RegisterWriteCallback(uint32_t sessionId,const std::weak_ptr<IStreamCallback> & callback)1033 int32_t HpaeRendererManager::RegisterWriteCallback(uint32_t sessionId, const std::weak_ptr<IStreamCallback> &callback)
1034 {
1035 auto request = [this, sessionId, callback]() {
1036 AUDIO_INFO_LOG("RegisterWriteCallback sessionId %{public}u", sessionId);
1037 if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1038 sinkInputNodeMap_[sessionId]->RegisterWriteCallback(callback);
1039 }
1040 };
1041 hpaeNoLockQueue_.PushRequest(request);
1042 return SUCCESS;
1043 }
1044
Process()1045 void HpaeRendererManager::Process()
1046 {
1047 Trace trace("HpaeRendererManager::Process");
1048 if (outputCluster_ != nullptr && IsRunning()) {
1049 UpdateAppsUid();
1050 outputCluster_->DoProcess();
1051 }
1052 }
1053
UpdateAppsUid()1054 void HpaeRendererManager::UpdateAppsUid()
1055 {
1056 appsUid_.clear();
1057 for (const auto &sinkInputNodePair : sinkInputNodeMap_) {
1058 if (sinkInputNodePair.second->GetState() == HPAE_SESSION_RUNNING) {
1059 appsUid_.emplace_back(sinkInputNodePair.second->GetAppUid());
1060 }
1061 }
1062 outputCluster_->UpdateAppsUid(appsUid_);
1063 }
1064
GetWritableSize(uint32_t sessionId)1065 size_t HpaeRendererManager::GetWritableSize(uint32_t sessionId)
1066 {
1067 return SUCCESS;
1068 }
1069
UpdateSpatializationState(uint32_t sessionId,bool spatializationEnabled,bool headTrackingEnabled)1070 int32_t HpaeRendererManager::UpdateSpatializationState(
1071 uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled)
1072 {
1073 return SUCCESS;
1074 }
1075
UpdateMaxLength(uint32_t sessionId,uint32_t maxLength)1076 int32_t HpaeRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength)
1077 {
1078 return SUCCESS;
1079 }
1080
SetSpeed(uint32_t sessionId,float speed)1081 void HpaeRendererManager::SetSpeed(uint32_t sessionId, float speed)
1082 {
1083 auto request = [this, sessionId, speed]() {
1084 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::SetSpeed");
1085 AUDIO_INFO_LOG("SetSpeed sessionId %{public}u, deviceName %{public}s, speed %{public}f", sessionId,
1086 sinkInfo_.deviceName.c_str(), speed);
1087 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), "not find sessionId %{public}u", sessionId);
1088 sinkInputNodeMap_[sessionId]->SetSpeed(speed);
1089 };
1090 SendRequest(request);
1091 }
1092
GetAllSinkInputsInfo()1093 std::vector<SinkInput> HpaeRendererManager::GetAllSinkInputsInfo()
1094 {
1095 return {};
1096 }
1097
GetSinkInputInfo(uint32_t sessionId,HpaeSinkInputInfo & sinkInputInfo)1098 int32_t HpaeRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo)
1099 {
1100 if (!SafeGetMap(sinkInputNodeMap_, sessionId)) {
1101 return ERR_INVALID_OPERATION;
1102 }
1103 sinkInputInfo.nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1104 sinkInputInfo.rendererSessionInfo = sessionNodeMap_[sessionId];
1105 return SUCCESS;
1106 }
1107
GetSinkInfo()1108 HpaeSinkInfo HpaeRendererManager::GetSinkInfo()
1109 {
1110 return sinkInfo_;
1111 }
1112
IsInit()1113 bool HpaeRendererManager::IsInit()
1114 {
1115 return isInit_.load();
1116 }
1117
IsMsgProcessing()1118 bool HpaeRendererManager::IsMsgProcessing()
1119 {
1120 return !hpaeNoLockQueue_.IsFinishProcess();
1121 }
1122
IsRunning(void)1123 bool HpaeRendererManager::IsRunning(void)
1124 {
1125 if (outputCluster_ != nullptr && hpaeSignalProcessThread_ != nullptr) {
1126 return outputCluster_->GetState() == STREAM_MANAGER_RUNNING && hpaeSignalProcessThread_->IsRunning();
1127 } else {
1128 return false;
1129 }
1130 }
1131
SendRequest(Request && request,bool isInit)1132 void HpaeRendererManager::SendRequest(Request &&request, bool isInit)
1133 {
1134 AUDIO_DEBUG_LOG("HpaeRendererManager::isInit is %{public}s", isInit ? "true" : "false");
1135 CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeRendererManager not init");
1136 hpaeNoLockQueue_.PushRequest(std::move(request));
1137 CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ renderer is nullptr");
1138 hpaeSignalProcessThread_->Notify();
1139 }
1140
OnNodeStatusUpdate(uint32_t sessionId,IOperation operation)1141 void HpaeRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation)
1142 {
1143 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionNodeMap_[sessionId].state, operation);
1144 }
1145
OnFadeDone(uint32_t sessionId,IOperation operation)1146 void HpaeRendererManager::OnFadeDone(uint32_t sessionId, IOperation operation)
1147 {
1148 auto request = [this, sessionId, operation]() {
1149 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::OnFadeDone: " + std::to_string(operation));
1150 AUDIO_INFO_LOG("Fade done, call back at RendererManager");
1151 DisConnectInputSession(sessionId);
1152 HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPED : HPAE_SESSION_PAUSED;
1153 SetSessionState(sessionId, state);
1154 if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1155 sinkInputNodeMap_[sessionId]->SetState(state);
1156 }
1157 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
1158 };
1159 SendRequest(request);
1160 }
1161
RegisterReadCallback(uint32_t sessionId,const std::weak_ptr<ICapturerStreamCallback> & callback)1162 int32_t HpaeRendererManager::RegisterReadCallback(uint32_t sessionId,
1163 const std::weak_ptr<ICapturerStreamCallback> &callback)
1164 {
1165 return SUCCESS;
1166 }
1167
OnRequestLatency(uint32_t sessionId,uint64_t & latency)1168 void HpaeRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency)
1169 {
1170 // todo: add processLatency
1171 return;
1172 }
1173
OnNotifyQueue()1174 void HpaeRendererManager::OnNotifyQueue()
1175 {
1176 CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ is nullptr");
1177 hpaeSignalProcessThread_->Notify();
1178 }
1179
UpdateProcessClusterConnection(uint32_t sessionId,int32_t effectMode)1180 void HpaeRendererManager::UpdateProcessClusterConnection(uint32_t sessionId, int32_t effectMode)
1181 {
1182 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::UpdateProcessClusterConnection" +
1183 "effectMode[" + std::to_string(effectMode) + "]");
1184 HpaeProcessorType sceneType = sinkInputNodeMap_[sessionId]->GetSceneType();
1185 if (!SafeGetMap(sceneClusterMap_, sceneType)) {
1186 AUDIO_WARNING_LOG("miss corresponding process cluster for scene type %{public}d", sceneType);
1187 return;
1188 }
1189 if (isSplitProcessorType(sceneType) || sessionNodeMap_[sessionId].bypass) {
1190 AUDIO_INFO_LOG("no need to update the sceneType %{public}d", sceneType);
1191 return;
1192 }
1193
1194 if (effectMode == EFFECT_NONE) {
1195 DisConnectInputCluster(sessionId, sceneType);
1196 ConnectProcessCluster(sessionId, HPAE_SCENE_EFFECT_NONE);
1197 } else {
1198 DisConnectInputCluster(sessionId, HPAE_SCENE_EFFECT_NONE);
1199 ConnectProcessCluster(sessionId, sceneType);
1200 }
1201 }
1202
GetThreadName()1203 std::string HpaeRendererManager::GetThreadName()
1204 {
1205 return sinkInfo_.deviceName;
1206 }
1207
SetSessionFade(uint32_t sessionId,IOperation operation)1208 bool HpaeRendererManager::SetSessionFade(uint32_t sessionId, IOperation operation)
1209 {
1210 CHECK_AND_RETURN_RET_LOG(SafeGetMap(sinkInputNodeMap_, sessionId), false,
1211 "can not get input node of session %{public}u", sessionId);
1212 HpaeProcessorType sceneType = GetProcessorType(sessionId);
1213 AUDIO_INFO_LOG("sessionId is %{public}d, sceneType is %{public}d", sessionId, sceneType);
1214 std::shared_ptr<HpaeGainNode> sessionGainNode = nullptr;
1215 if (SafeGetMap(sceneClusterMap_, sceneType)) {
1216 sessionGainNode = sceneClusterMap_[sceneType]->GetGainNodeById(sessionId);
1217 }
1218 if (sessionGainNode == nullptr) {
1219 AUDIO_WARNING_LOG("session %{public}d do not have gain node!", sessionId);
1220 if (operation != OPERATION_STARTED) {
1221 HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPED : HPAE_SESSION_PAUSED;
1222 SetSessionState(sessionId, state);
1223 sinkInputNodeMap_[sessionId]->SetState(state);
1224 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, state, operation);
1225 }
1226 return false;
1227 }
1228 AUDIO_INFO_LOG("get gain node of session %{public}d operation %{public}d.", sessionId, operation);
1229 if (operation != OPERATION_STARTED) {
1230 HpaeSessionState state = operation == OPERATION_STOPPED ? HPAE_SESSION_STOPPING : HPAE_SESSION_PAUSING;
1231 SetSessionState(sessionId, state);
1232 sinkInputNodeMap_[sessionId]->SetState(state);
1233 }
1234 sessionGainNode->SetFadeState(operation);
1235 return true;
1236 }
1237
DumpSinkInfo()1238 int32_t HpaeRendererManager::DumpSinkInfo()
1239 {
1240 CHECK_AND_RETURN_RET_LOG(IsInit(), ERR_ILLEGAL_STATE, "HpaeRendererManager not init");
1241 auto request = [this]() {
1242 AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str());
1243 UploadDumpSinkInfo(sinkInfo_.deviceName);
1244 };
1245 SendRequest(request);
1246 return SUCCESS;
1247 }
1248
SetOffloadPolicy(uint32_t sessionId,int32_t state)1249 int32_t HpaeRendererManager::SetOffloadPolicy(uint32_t sessionId, int32_t state)
1250 {
1251 auto request = [this, sessionId, state]() {
1252 Trace trace("[" + std::to_string(sessionId) + "]HpaeRendererManager::SetOffloadPolicy");
1253 AUDIO_INFO_LOG("SetOffloadPolicy sessionId %{public}u, deviceName %{public}s, state %{public}d", sessionId,
1254 sinkInfo_.deviceName.c_str(), state);
1255 if (SafeGetMap(sinkInputNodeMap_, sessionId)) {
1256 sinkInputNodeMap_[sessionId]->SetOffloadEnabled(state != OFFLOAD_DEFAULT);
1257 } else {
1258 AUDIO_ERR_LOG("not find sessionId %{public}u", sessionId);
1259 }
1260 };
1261 SendRequest(request);
1262 return SUCCESS;
1263 }
1264
UpdateCollaborativeState(bool isCollaborationEnabled)1265 int32_t HpaeRendererManager::UpdateCollaborativeState(bool isCollaborationEnabled)
1266 {
1267 auto request = [this, isCollaborationEnabled]() {
1268 if (isCollaborationEnabled_ == isCollaborationEnabled) {
1269 AUDIO_INFO_LOG("collaboration state not changed, isCollaborationEnabled_ %{public}d",
1270 isCollaborationEnabled_);
1271 return;
1272 }
1273 AUDIO_INFO_LOG("collaborativeState change from %{public}d to %{public}d",
1274 isCollaborationEnabled_, isCollaborationEnabled);
1275 isCollaborationEnabled_ = isCollaborationEnabled;
1276 if (isCollaborationEnabled_) {
1277 // for collaboration enabled
1278 EnableCollaboration();
1279 } else {
1280 // for collaboration disabled
1281 DisableCollaboration();
1282 }
1283 };
1284 SendRequest(request);
1285 return SUCCESS;
1286 }
1287
HandlePriPaPower(uint32_t sessionId)1288 int32_t HpaeRendererManager::HandlePriPaPower(uint32_t sessionId)
1289 {
1290 if (!SafeGetMap(sinkInputNodeMap_, sessionId) || sinkInfo_.deviceClass != "primary") {
1291 return ERR_INVALID_OPERATION;
1292 }
1293 auto &nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1294 struct VolumeValues volumes;
1295 auto audioVolume = AudioVolume::GetInstance();
1296 float curVolume = audioVolume->GetVolume(sessionId, nodeInfo.streamType, sinkInfo_.deviceClass, &volumes);
1297 auto isZeroVolume = audioVolume->IsSameVolume(0.0f, curVolume);
1298 AUDIO_INFO_LOG("session %{public}u, stream %{public}d, is zero volume %{public}d",
1299 sessionId, nodeInfo.streamType, isZeroVolume);
1300 if (!isZeroVolume) {
1301 return outputCluster_->SetPriPaPower();
1302 }
1303 return SUCCESS;
1304 }
1305
GetDeviceHDFDumpInfo()1306 std::string HpaeRendererManager::GetDeviceHDFDumpInfo()
1307 {
1308 std::string config;
1309 TransDeviceInfoToString(sinkInfo_, config);
1310 return config;
1311 }
1312
ConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> & coBufferNode)1313 int32_t HpaeRendererManager::ConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> &coBufferNode)
1314 {
1315 auto request = [this, coBufferNode]() {
1316 CHECK_AND_RETURN_LOG((outputCluster_ != nullptr) && (coBufferNode != nullptr),
1317 "outputCluster or coBufferNode is nullptr");
1318 if (!coBufferNode->IsOutputClusterConnected()) {
1319 outputCluster_->Connect(coBufferNode);
1320 coBufferNode->SetOutputClusterConnected(true);
1321 }
1322 if (outputCluster_->GetState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
1323 outputCluster_->Start();
1324 }
1325 };
1326 SendRequest(request);
1327 return SUCCESS;
1328 }
1329
DisConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> & coBufferNode)1330 int32_t HpaeRendererManager::DisConnectCoBufferNode(const std::shared_ptr<HpaeCoBufferNode> &coBufferNode)
1331 {
1332 auto request = [this, coBufferNode]() {
1333 CHECK_AND_RETURN_LOG((outputCluster_ != nullptr) && (coBufferNode != nullptr),
1334 "outputCluster or coBufferNode is nullptr");
1335 if (coBufferNode->IsOutputClusterConnected()) {
1336 outputCluster_->DisConnect(coBufferNode);
1337 coBufferNode->SetOutputClusterConnected(false);
1338 }
1339 };
1340 SendRequest(request);
1341 return SUCCESS;
1342 }
1343
ReConnectNodeForCollaboration(uint32_t sessionId)1344 void HpaeRendererManager::ReConnectNodeForCollaboration(uint32_t sessionId)
1345 {
1346 // todo fade out
1347 CHECK_AND_RETURN_LOG(SafeGetMap(sinkInputNodeMap_, sessionId),
1348 "sinkInputNodeMap_ not find sessionId %{public}u", sessionId);
1349 HpaeNodeInfo nodeInfo = sinkInputNodeMap_[sessionId]->GetNodeInfo();
1350 HpaeProcessorType sceneType = GetProcessorType(sessionId);
1351 if (SafeGetMap(sceneClusterMap_, sceneType)) {
1352 DisConnectProcessCluster(nodeInfo, sceneType, sessionId);
1353 }
1354 AUDIO_INFO_LOG("AddSingleNodeToSink sessionId %{public}u", sessionId);
1355 AddSingleNodeToSink(sinkInputNodeMap_[sessionId]);
1356 }
1357
EnableCollaboration()1358 void HpaeRendererManager::EnableCollaboration()
1359 {
1360 if (hpaeCoBufferNode_ == nullptr) {
1361 hpaeCoBufferNode_ = std::make_shared<HpaeCoBufferNode>();
1362 }
1363
1364 std::vector<uint32_t> sinkInputNodeMapKeys;
1365 for (auto& [key, node] : sinkInputNodeMap_) {
1366 HpaeNodeInfo nodeInfo = node->GetNodeInfo();
1367 if (nodeInfo.effectInfo.effectScene == SCENE_MUSIC || nodeInfo.effectInfo.effectScene == SCENE_MOVIE) {
1368 sinkInputNodeMapKeys.push_back(key);
1369 }
1370 }
1371
1372 for (auto& key : sinkInputNodeMapKeys) {
1373 ReConnectNodeForCollaboration(key);
1374 }
1375 }
1376
DisableCollaboration()1377 void HpaeRendererManager::DisableCollaboration()
1378 {
1379 std::vector<uint32_t> sinkInputNodeMapKeys;
1380 for (auto& [key, node] : sinkInputNodeMap_) {
1381 HpaeNodeInfo nodeInfo = node->GetNodeInfo();
1382 if (nodeInfo.effectInfo.effectScene == SCENE_COLLABORATIVE) {
1383 sinkInputNodeMapKeys.push_back(key);
1384 }
1385 }
1386 for (auto& key : sinkInputNodeMapKeys) {
1387 ReConnectNodeForCollaboration(key);
1388 }
1389 }
1390
HandleSyncId(uint32_t sessionId,int32_t syncId)1391 int32_t HpaeRendererManager::HandleSyncId(uint32_t sessionId, int32_t syncId)
1392 {
1393 if (!SafeGetMap(sinkInputNodeMap_, sessionId) || sinkInfo_.deviceClass != "primary") {
1394 return ERR_INVALID_OPERATION;
1395 }
1396 return outputCluster_->SetSyncId(syncId);
1397 }
1398 } // namespace HPAE
1399 } // namespace AudioStandard
1400 } // namespace OHOS