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 #ifndef LOG_TAG
16 #define LOG_TAG "HpaeOffloadRendererManager"
17 #endif
18
19 #include "hpae_offload_renderer_manager.h"
20 #include "audio_stream_info.h"
21 #include "audio_errors.h"
22 #include "hpae_node_common.h"
23 #include "audio_engine_log.h"
24
25 namespace OHOS {
26 namespace AudioStandard {
27 namespace HPAE {
28 namespace {
29 constexpr uint32_t HISTORY_INTERVAL_S = 7; // 7s buffer for rewind
30 }
31
HpaeOffloadRendererManager(HpaeSinkInfo & sinkInfo)32 HpaeOffloadRendererManager::HpaeOffloadRendererManager(HpaeSinkInfo &sinkInfo)
33 : hpaeNoLockQueue_(CURRENT_REQUEST_COUNT), sinkInfo_(sinkInfo)
34 {}
35
~HpaeOffloadRendererManager()36 HpaeOffloadRendererManager::~HpaeOffloadRendererManager()
37 {
38 AUDIO_INFO_LOG("destructor offload renderer");
39 if (isInit_.load()) {
40 DeInit();
41 }
42 }
43
44 // private method
CreateInputSession(const HpaeStreamInfo & streamInfo)45 int32_t HpaeOffloadRendererManager::CreateInputSession(const HpaeStreamInfo &streamInfo)
46 {
47 HpaeNodeInfo nodeInfo;
48 nodeInfo.channels = streamInfo.channels;
49 nodeInfo.format = streamInfo.format;
50 nodeInfo.frameLen = streamInfo.frameLen;
51 nodeInfo.streamType = streamInfo.streamType;
52 nodeInfo.sessionId = streamInfo.sessionId;
53 nodeInfo.samplingRate = static_cast<AudioSamplingRate>(streamInfo.samplingRate);
54 nodeInfo.sceneType = TransStreamTypeToSceneType(streamInfo.streamType);
55 nodeInfo.effectInfo = streamInfo.effectInfo;
56 nodeInfo.historyFrameCount = nodeInfo.frameLen ?
57 HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen : 0;
58 nodeInfo.statusCallback = weak_from_this();
59 nodeInfo.deviceClass = sinkInfo_.deviceClass;
60 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
61 sinkInputNode_ = std::make_shared<HpaeSinkInputNode>(nodeInfo);
62 sinkInputNode_->SetAppUid(streamInfo.uid);
63 return SUCCESS;
64 }
65
AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node)66 int32_t HpaeOffloadRendererManager::AddNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node)
67 {
68 auto request = [this, node]() { AddSingleNodeToSink(node); };
69 SendRequest(request);
70 return SUCCESS;
71 }
72
AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> & node,bool isConnect)73 void HpaeOffloadRendererManager::AddSingleNodeToSink(const std::shared_ptr<HpaeSinkInputNode> &node, bool isConnect)
74 {
75 HpaeNodeInfo nodeInfo = node->GetNodeInfo();
76 nodeInfo.deviceClass = sinkInfo_.deviceClass;
77 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
78 // 7s history buffer to rewind
79 nodeInfo.historyFrameCount = HISTORY_INTERVAL_S * nodeInfo.samplingRate / nodeInfo.frameLen;
80 nodeInfo.statusCallback = weak_from_this();
81 node->SetNodeInfo(nodeInfo);
82 uint32_t sessionId = nodeInfo.sessionId;
83 AUDIO_INFO_LOG("[FinishMove] session:%{public}u to sink:offload", sessionId);
84 sinkInputNode_ = node;
85 sessionInfo_.state = node->GetState();
86
87 if (!isConnect || sinkInputNode_->GetState() != HPAE_SESSION_RUNNING) {
88 AUDIO_INFO_LOG("[FinishMove] session:%{public}u not need connect session", sessionId);
89 return;
90 }
91
92 if (node->GetState() == HPAE_SESSION_RUNNING) {
93 AUDIO_INFO_LOG("[FinishMove] session:%{public}u connect to sink:offload", sessionId);
94 ConnectInputSession();
95 if (sinkOutputNode_->GetSinkState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
96 sinkOutputNode_->RenderSinkStart();
97 }
98 }
99 }
100
AddAllNodesToSink(const std::vector<std::shared_ptr<HpaeSinkInputNode>> & sinkInputs,bool isConnect)101 int32_t HpaeOffloadRendererManager::AddAllNodesToSink(
102 const std::vector<std::shared_ptr<HpaeSinkInputNode>> &sinkInputs, bool isConnect)
103 {
104 auto request = [this, sinkInputs, isConnect]() {
105 for (const auto &it : sinkInputs) {
106 AddSingleNodeToSink(it, isConnect);
107 }
108 };
109 SendRequest(request);
110 return SUCCESS;
111 }
112
CreateStream(const HpaeStreamInfo & streamInfo)113 int32_t HpaeOffloadRendererManager::CreateStream(const HpaeStreamInfo &streamInfo)
114 {
115 if (!IsInit()) {
116 return ERR_INVALID_OPERATION;
117 }
118 auto request = [this, streamInfo]() {
119 CreateInputSession(streamInfo);
120 sessionInfo_.state = HPAE_SESSION_PREPARED;
121 sinkInputNode_->SetState(HPAE_SESSION_PREPARED);
122 };
123 SendRequest(request);
124 return SUCCESS;
125 }
126
DeleteInputSession()127 void HpaeOffloadRendererManager::DeleteInputSession()
128 {
129 DisConnectInputSession();
130 if (sinkInputNode_->GetState() == HPAE_SESSION_RUNNING) {
131 sinkOutputNode_->StopStream();
132 }
133 sinkInputNode_ = nullptr;
134 }
135
DestroyStream(uint32_t sessionId)136 int32_t HpaeOffloadRendererManager::DestroyStream(uint32_t sessionId)
137 {
138 if (!IsInit()) {
139 return ERR_INVALID_OPERATION;
140 }
141 auto request = [this, sessionId]() {
142 CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(),
143 "DestroyStream not find sessionId %{public}u",
144 sessionId);
145 AUDIO_INFO_LOG("DestroyStream sessionId %{public}u", sessionId);
146 DeleteInputSession();
147 };
148 SendRequest(request);
149 return SUCCESS;
150 }
151
ConnectInputSession()152 int32_t HpaeOffloadRendererManager::ConnectInputSession()
153 {
154 if (sinkInputNode_->GetState() != HPAE_SESSION_RUNNING) {
155 return SUCCESS;
156 }
157
158 HpaeNodeInfo outputNodeInfo = sinkOutputNode_->GetNodeInfo();
159 outputNodeInfo.sessionId = sinkInputNode_->GetSessionId();
160 outputNodeInfo.streamType = sinkInputNode_->GetStreamType();
161 sinkOutputNode_->SetNodeInfo(outputNodeInfo);
162 sinkOutputNode_->SetSpeed(sinkInputNode_->GetSpeed());
163
164 // single stream manager
165 HpaeNodeInfo nodeInfo = sinkOutputNode_->GetNodeInfo();
166 converterForOutput_ = std::make_shared<HpaeAudioFormatConverterNode>(nodeInfo, outputNodeInfo);
167 sinkOutputNode_->Connect(converterForOutput_);
168 // if there's no loudness algo, audio format will be converted to output device format at the first converternode
169 loudnessGainNode_ = std::make_shared<HpaeLoudnessGainNode>(nodeInfo);
170 converterForOutput_->Connect(loudnessGainNode_);
171 converterForLoudness_ = std::make_shared<HpaeAudioFormatConverterNode>(sinkInputNode_->GetNodeInfo(), nodeInfo);
172 loudnessGainNode_->Connect(converterForLoudness_);
173 loudnessGainNode_->SetLoudnessGain(sinkInputNode_->GetLoudnessGain());
174 converterForLoudness_->Connect(sinkInputNode_);
175 converterForLoudness_->RegisterCallback(this);
176
177 return SUCCESS;
178 }
179
Start(uint32_t sessionId)180 int32_t HpaeOffloadRendererManager::Start(uint32_t sessionId)
181 {
182 auto request = [this, sessionId]() {
183 CHECK_AND_RETURN_LOG(sinkInputNode_ &&
184 sessionId == sinkInputNode_->GetSessionId(), "Start not find sessionId %{public}u", sessionId);
185 AUDIO_INFO_LOG("Start sessionId %{public}u", sessionId);
186 sinkInputNode_->SetState(HPAE_SESSION_RUNNING);
187 ConnectInputSession();
188 if (sinkOutputNode_->GetSinkState() != STREAM_MANAGER_RUNNING && !isSuspend_) {
189 sinkOutputNode_->RenderSinkStart();
190 }
191 sessionInfo_.state = HPAE_SESSION_RUNNING;
192 };
193 SendRequest(request);
194 return SUCCESS;
195 }
196
DisConnectInputSession()197 int32_t HpaeOffloadRendererManager::DisConnectInputSession()
198 {
199 CHECK_AND_RETURN_RET_LOG(converterForLoudness_, SUCCESS, "No need to disconnect");
200 converterForLoudness_->DisConnect(sinkInputNode_);
201 loudnessGainNode_->DisConnect(converterForLoudness_);
202 converterForOutput_->DisConnect(loudnessGainNode_);
203 sinkOutputNode_->DisConnect(converterForOutput_);
204 converterForLoudness_ = nullptr;
205 loudnessGainNode_ = nullptr;
206 converterForOutput_ = nullptr;
207 return SUCCESS;
208 }
209
Pause(uint32_t sessionId)210 int32_t HpaeOffloadRendererManager::Pause(uint32_t sessionId)
211 {
212 auto request = [this, sessionId]() {
213 CHECK_AND_RETURN_LOG(sinkInputNode_ &&
214 sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId);
215 AUDIO_INFO_LOG("Pause sessionId %{public}u", sessionId);
216 DisConnectInputSession();
217 auto state = sinkInputNode_->GetState();
218 sinkInputNode_->SetState(HPAE_SESSION_PAUSED);
219 if (state == HPAE_SESSION_RUNNING) {
220 sinkOutputNode_->StopStream();
221 }
222 sessionInfo_.state = HPAE_SESSION_PAUSED;
223 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_PAUSED);
224 };
225 SendRequest(request);
226 return SUCCESS;
227 }
228
Flush(uint32_t sessionId)229 int32_t HpaeOffloadRendererManager::Flush(uint32_t sessionId)
230 {
231 auto request = [this, sessionId]() {
232 CHECK_AND_RETURN_LOG(sinkInputNode_ &&
233 sessionId == sinkInputNode_->GetSessionId(), "Pause not find sessionId %{public}u", sessionId);
234 AUDIO_INFO_LOG("Flush sessionId %{public}u", sessionId);
235 // flush history buffer
236 sinkInputNode_->Flush();
237 // flush sinkoutput cache
238 sinkOutputNode_->FlushStream();
239 };
240 SendRequest(request);
241 return SUCCESS;
242 }
243
Drain(uint32_t sessionId)244 int32_t HpaeOffloadRendererManager::Drain(uint32_t sessionId)
245 {
246 auto request = [this, sessionId]() {
247 CHECK_AND_RETURN_LOG(sinkInputNode_ &&
248 sessionId == sinkInputNode_->GetSessionId(), "Drain not find sessionId %{public}u", sessionId);
249 AUDIO_INFO_LOG("Drain sessionId %{public}u", sessionId);
250 sinkInputNode_->Drain();
251 if (sessionInfo_.state != HPAE_SESSION_RUNNING) {
252 TriggerCallback(
253 UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_DRAINED);
254 }
255 };
256 SendRequest(request);
257 return SUCCESS;
258 }
259
Stop(uint32_t sessionId)260 int32_t HpaeOffloadRendererManager::Stop(uint32_t sessionId)
261 {
262 auto request = [this, sessionId]() {
263 CHECK_AND_RETURN_LOG(sinkInputNode_ &&
264 sessionId == sinkInputNode_->GetSessionId(), "Stop not find sessionId %{public}u", sessionId);
265 AUDIO_INFO_LOG("Stop sessionId %{public}u", sessionId);
266 DisConnectInputSession();
267 auto state = sinkInputNode_->GetState();
268 sinkInputNode_->SetState(HPAE_SESSION_STOPPED);
269 sessionInfo_.state = HPAE_SESSION_STOPPED;
270 if (state == HPAE_SESSION_RUNNING) {
271 sinkOutputNode_->StopStream();
272 }
273 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, OPERATION_STOPPED);
274 };
275 SendRequest(request);
276 return SUCCESS;
277 }
278
Release(uint32_t sessionId)279 int32_t HpaeOffloadRendererManager::Release(uint32_t sessionId)
280 {
281 return DestroyStream(sessionId);
282 }
283
MoveAllStreamToNewSink(const std::string & sinkName,const std::vector<uint32_t> & moveIds,MoveSessionType moveType)284 void HpaeOffloadRendererManager::MoveAllStreamToNewSink(const std::string &sinkName,
285 const std::vector<uint32_t>& moveIds, MoveSessionType moveType)
286 {
287 std::string name = sinkName;
288 std::vector<std::shared_ptr<HpaeSinkInputNode>> sinkInputs;
289 if (sinkInputNode_) {
290 uint32_t sessionId = sinkInputNode_->GetSessionId();
291 if (moveType == MOVE_ALL || std::find(moveIds.begin(), moveIds.end(), sessionId) != moveIds.end()) {
292 sinkInputs.emplace_back(sinkInputNode_);
293 DeleteInputSession();
294 AUDIO_INFO_LOG("[StartMove] session: %{public}u,sink [offload] --> [%{public}s]",
295 sessionId, sinkName.c_str());
296 }
297 }
298 if (sinkInputs.size() == 0) {
299 AUDIO_WARNING_LOG("sink count is 0,no need move session");
300 }
301 TriggerCallback(MOVE_ALL_SINK_INPUT, sinkInputs, name, moveType);
302 }
303
MoveAllStream(const std::string & sinkName,const std::vector<uint32_t> & sessionIds,MoveSessionType moveType)304 int32_t HpaeOffloadRendererManager::MoveAllStream(const std::string &sinkName, const std::vector<uint32_t>& sessionIds,
305 MoveSessionType moveType)
306 {
307 if (!IsInit()) {
308 AUDIO_INFO_LOG("sink is not init ,use sync mode move to:%{public}s.", sinkName.c_str());
309 MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
310 } else {
311 AUDIO_INFO_LOG("sink is init ,use async mode move to:%{public}s.", sinkName.c_str());
312 auto request = [this, sinkName, sessionIds, moveType]() {
313 MoveAllStreamToNewSink(sinkName, sessionIds, moveType);
314 };
315 SendRequest(request);
316 }
317 return SUCCESS;
318 }
319
MoveStream(uint32_t sessionId,const std::string & sinkName)320 int32_t HpaeOffloadRendererManager::MoveStream(uint32_t sessionId, const std::string &sinkName)
321 {
322 auto request = [this, sessionId, sinkName]() {
323 if (sinkInputNode_ == nullptr || sessionId != sinkInputNode_->GetSessionId()) {
324 AUDIO_ERR_LOG("[StartMove] session:%{public}d failed,sink [offload] --> [%{public}s]",
325 sessionId, sinkName.c_str());
326 TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
327 return;
328 }
329
330 if (sinkName.empty()) {
331 AUDIO_ERR_LOG("[StartMove] session:%{public}u failed,sinkName is empty", sessionId);
332 TriggerCallback(MOVE_SESSION_FAILED, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, MOVE_SINGLE, sinkName);
333 return;
334 }
335
336 std::shared_ptr<HpaeSinkInputNode> inputNode = sinkInputNode_;
337 AUDIO_INFO_LOG("move session:%{public}d,sink [offload] --> [%{public}s]", sessionId, sinkName.c_str());
338 DeleteInputSession();
339 std::string name = sinkName;
340 TriggerCallback(MOVE_SINK_INPUT, inputNode, name);
341 };
342 SendRequest(request);
343 return SUCCESS;
344 }
345
SuspendStreamManager(bool isSuspend)346 int32_t HpaeOffloadRendererManager::SuspendStreamManager(bool isSuspend)
347 {
348 auto request = [this, isSuspend]() {
349 if (isSuspend_ == isSuspend) {
350 return;
351 }
352 isSuspend_ = isSuspend;
353 if (isSuspend_) {
354 sinkOutputNode_->RenderSinkStop();
355 } else if (sinkOutputNode_->GetSinkState() != STREAM_MANAGER_RUNNING && sinkInputNode_ &&
356 sinkInputNode_->GetState() == HPAE_SESSION_RUNNING) {
357 sinkOutputNode_->RenderSinkStart();
358 }
359 };
360 SendRequest(request);
361 return SUCCESS;
362 }
363
SetMute(bool isMute)364 int32_t HpaeOffloadRendererManager::SetMute(bool isMute)
365 {
366 auto request = [this, isMute]() {
367 isMute_ = isMute; // todo: set to sinkoutputnode
368 };
369 SendRequest(request);
370 return SUCCESS;
371 }
372
HandleMsg()373 void HpaeOffloadRendererManager::HandleMsg()
374 {
375 hpaeNoLockQueue_.HandleRequests();
376 }
377
ReloadRenderManager(const HpaeSinkInfo & sinkInfo,bool isReload)378 int32_t HpaeOffloadRendererManager::ReloadRenderManager(const HpaeSinkInfo &sinkInfo, bool isReload)
379 {
380 if (IsInit()) {
381 AUDIO_INFO_LOG("deinit offload renderer first.");
382 DeInit();
383 }
384 hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
385 auto request = [this, sinkInfo, isReload]() {
386 if (sinkOutputNode_ != nullptr && sinkOutputNode_->GetSinkState() == STREAM_MANAGER_RUNNING) {
387 DisConnectInputSession();
388 }
389 sinkInfo_ = sinkInfo;
390 InitSinkInner(isReload);
391
392 if (sinkOutputNode_ != nullptr && sinkOutputNode_->GetSinkState() == STREAM_MANAGER_RUNNING) {
393 ConnectInputSession();
394 }
395 };
396 SendRequest(request, true);
397 hpaeSignalProcessThread_->ActivateThread(shared_from_this());
398 return SUCCESS;
399 }
400
Init(bool isReload)401 int32_t HpaeOffloadRendererManager::Init(bool isReload)
402 {
403 hpaeSignalProcessThread_ = std::make_unique<HpaeSignalProcessThread>();
404 auto request = [this, isReload] {
405 InitSinkInner(isReload);
406 };
407 SendRequest(request, true);
408 hpaeSignalProcessThread_->ActivateThread(shared_from_this());
409 return SUCCESS;
410 }
411
InitSinkInner(bool isReload)412 void HpaeOffloadRendererManager::InitSinkInner(bool isReload)
413 {
414 AUDIO_INFO_LOG("HpaeOffloadRendererManager::init");
415 HpaeNodeInfo nodeInfo;
416 nodeInfo.channels = sinkInfo_.channels;
417 nodeInfo.format = sinkInfo_.format;
418 nodeInfo.frameLen = sinkInfo_.frameLen;
419 nodeInfo.nodeId = 0;
420 nodeInfo.samplingRate = sinkInfo_.samplingRate;
421 nodeInfo.sceneType = HPAE_SCENE_EFFECT_OUT;
422 nodeInfo.deviceNetId = sinkInfo_.deviceNetId;
423 nodeInfo.deviceClass = sinkInfo_.deviceClass;
424 nodeInfo.statusCallback = weak_from_this();
425 sinkOutputNode_ = std::make_unique<HpaeOffloadSinkOutputNode>(nodeInfo);
426 sinkOutputNode_->SetTimeoutStopThd(sinkInfo_.suspendTime);
427 // if failed, RenderSinkInit will failed either, so no need to deal ret
428 AUDIO_INFO_LOG("HpaeOffloadRendererManager::GetRenderSinkInstance");
429 sinkOutputNode_->GetRenderSinkInstance(sinkInfo_.deviceClass, sinkInfo_.deviceNetId);
430 IAudioSinkAttr attr;
431 attr.adapterName = sinkInfo_.adapterName.c_str();
432 attr.sampleRate = sinkInfo_.samplingRate;
433 attr.channel = sinkInfo_.channels;
434 attr.format = sinkInfo_.format;
435 attr.channelLayout = sinkInfo_.channelLayout;
436 attr.deviceType = sinkInfo_.deviceType;
437 attr.volume = sinkInfo_.volume;
438 attr.openMicSpeaker = sinkInfo_.openMicSpeaker;
439 attr.deviceNetworkId = sinkInfo_.deviceNetId.c_str();
440 attr.filePath = sinkInfo_.filePath.c_str();
441 int32_t ret = sinkOutputNode_->RenderSinkInit(attr);
442 isInit_.store(true);
443 TriggerCallback(isReload ? RELOAD_AUDIO_SINK_RESULT : INIT_DEVICE_RESULT, sinkInfo_.deviceName, ret);
444 AUDIO_INFO_LOG("HpaeOffloadRendererManager::inited");
445 }
446
DeactivateThread()447 bool HpaeOffloadRendererManager::DeactivateThread()
448 {
449 if (hpaeSignalProcessThread_ != nullptr) {
450 hpaeSignalProcessThread_->DeactivateThread();
451 hpaeSignalProcessThread_ = nullptr;
452 }
453 hpaeNoLockQueue_.HandleRequests();
454 return true;
455 }
456
DeInit(bool isMoveDefault)457 int32_t HpaeOffloadRendererManager::DeInit(bool isMoveDefault)
458 {
459 if (hpaeSignalProcessThread_ != nullptr) {
460 hpaeSignalProcessThread_->DeactivateThread();
461 hpaeSignalProcessThread_ = nullptr;
462 }
463 hpaeNoLockQueue_.HandleRequests();
464 if (isMoveDefault) {
465 std::string sinkName = "";
466 std::vector<uint32_t> ids;
467 AUDIO_INFO_LOG("move all sink to default sink");
468 MoveAllStreamToNewSink(sinkName, ids, MOVE_ALL);
469 }
470 if (sinkOutputNode_ != nullptr) {
471 sinkOutputNode_->RenderSinkStop();
472 sinkOutputNode_->RenderSinkDeInit();
473 sinkOutputNode_->ResetAll();
474 sinkOutputNode_ = nullptr;
475 }
476
477 isInit_.store(false);
478 return SUCCESS;
479 }
480
IsInit()481 bool HpaeOffloadRendererManager::IsInit()
482 {
483 return isInit_.load();
484 }
485
IsRunning(void)486 bool HpaeOffloadRendererManager::IsRunning(void)
487 {
488 if (sinkOutputNode_ != nullptr && hpaeSignalProcessThread_ != nullptr) {
489 return sinkOutputNode_->GetSinkState() == STREAM_MANAGER_RUNNING && hpaeSignalProcessThread_->IsRunning();
490 }
491 return false;
492 }
493
IsMsgProcessing()494 bool HpaeOffloadRendererManager::IsMsgProcessing()
495 {
496 return !hpaeNoLockQueue_.IsFinishProcess();
497 }
498
SetClientVolume(uint32_t sessionId,float volume)499 int32_t HpaeOffloadRendererManager::SetClientVolume(uint32_t sessionId, float volume)
500 {
501 return SUCCESS;
502 }
503
SetRate(uint32_t sessionId,int32_t rate)504 int32_t HpaeOffloadRendererManager::SetRate(uint32_t sessionId, int32_t rate)
505 {
506 return SUCCESS;
507 }
508
SetAudioEffectMode(uint32_t sessionId,int32_t effectMode)509 int32_t HpaeOffloadRendererManager::SetAudioEffectMode(uint32_t sessionId, int32_t effectMode)
510 {
511 return SUCCESS;
512 }
513
GetAudioEffectMode(uint32_t sessionId,int32_t & effectMode)514 int32_t HpaeOffloadRendererManager::GetAudioEffectMode(uint32_t sessionId, int32_t &effectMode)
515 {
516 return SUCCESS;
517 }
518
SetPrivacyType(uint32_t sessionId,int32_t privacyType)519 int32_t HpaeOffloadRendererManager::SetPrivacyType(uint32_t sessionId, int32_t privacyType)
520 {
521 return SUCCESS;
522 }
523
GetPrivacyType(uint32_t sessionId,int32_t & privacyType)524 int32_t HpaeOffloadRendererManager::GetPrivacyType(uint32_t sessionId, int32_t &privacyType)
525 {
526 return SUCCESS;
527 }
528
RegisterWriteCallback(uint32_t sessionId,const std::weak_ptr<IStreamCallback> & callback)529 int32_t HpaeOffloadRendererManager::RegisterWriteCallback(
530 uint32_t sessionId, const std::weak_ptr<IStreamCallback> &callback)
531 {
532 auto request = [this, sessionId, callback]() {
533 CHECK_AND_RETURN_LOG(sinkInputNode_ != nullptr, "SinkInputNode is nullptr");
534 CHECK_AND_RETURN_LOG(sessionId == sinkInputNode_->GetSessionId(),
535 "RegisterWriteCallback not find sessionId %{public}u",
536 sessionId);
537 sinkInputNode_->RegisterWriteCallback(callback);
538 };
539 SendRequest(request);
540 return SUCCESS;
541 }
542
RegisterReadCallback(uint32_t sessionId,const std::weak_ptr<ICapturerStreamCallback> & callback)543 int32_t HpaeOffloadRendererManager::RegisterReadCallback(
544 uint32_t sessionId, const std::weak_ptr<ICapturerStreamCallback> &callback)
545 {
546 return ERR_NOT_SUPPORTED;
547 }
548
Process()549 void HpaeOffloadRendererManager::Process()
550 {
551 if (sinkOutputNode_ != nullptr && IsRunning()) {
552 UpdateAppsUid();
553 sinkOutputNode_->DoProcess();
554 }
555 }
556
UpdateAppsUid()557 void HpaeOffloadRendererManager::UpdateAppsUid()
558 {
559 appsUid_.clear();
560 if (sinkInputNode_ != nullptr && sinkInputNode_->GetState() == HPAE_SESSION_RUNNING) {
561 appsUid_.emplace_back(sinkInputNode_->GetAppUid());
562 }
563 sinkOutputNode_->UpdateAppsUid(appsUid_);
564 }
565
SetOffloadPolicy(uint32_t sessionId,int32_t state)566 int32_t HpaeOffloadRendererManager::SetOffloadPolicy(uint32_t sessionId, int32_t state)
567 {
568 auto request = [this, sessionId, state]() {
569 CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(),
570 "SetOffloadPolicy not find sessionId %{public}u",
571 sessionId);
572 sinkInputNode_->SetOffloadEnabled(state != OFFLOAD_DEFAULT);
573 // OFFLOAD_DEFAULT do not need set buffersize
574 if (state != OFFLOAD_DEFAULT && sinkOutputNode_) {
575 sinkOutputNode_->SetPolicyState(state);
576 }
577 };
578 SendRequest(request);
579 return SUCCESS;
580 }
581
GetWritableSize(uint32_t sessionId)582 size_t HpaeOffloadRendererManager::GetWritableSize(uint32_t sessionId)
583 {
584 return SUCCESS;
585 }
586
UpdateSpatializationState(uint32_t sessionId,bool spatializationEnabled,bool headTrackingEnabled)587 int32_t HpaeOffloadRendererManager::UpdateSpatializationState(
588 uint32_t sessionId, bool spatializationEnabled, bool headTrackingEnabled)
589 {
590 return SUCCESS;
591 }
592
UpdateMaxLength(uint32_t sessionId,uint32_t maxLength)593 int32_t HpaeOffloadRendererManager::UpdateMaxLength(uint32_t sessionId, uint32_t maxLength)
594 {
595 return SUCCESS;
596 }
597
SetOffloadRenderCallbackType(uint32_t sessionId,int32_t type)598 int32_t HpaeOffloadRendererManager::SetOffloadRenderCallbackType(uint32_t sessionId, int32_t type)
599 {
600 auto request = [this, sessionId, type]() {
601 CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(),
602 "SetOffloadRenderCallbackType not find sessionId %{public}u",
603 sessionId);
604 if (sinkOutputNode_) {
605 sinkOutputNode_->SetOffloadRenderCallbackType(type);
606 }
607 };
608 SendRequest(request);
609 return SUCCESS;
610 }
611
SetSpeed(uint32_t sessionId,float speed)612 void HpaeOffloadRendererManager::SetSpeed(uint32_t sessionId, float speed)
613 {
614 auto request = [this, sessionId, speed]() {
615 CHECK_AND_RETURN_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(),
616 "SetSpeed not find sessionId %{public}u", sessionId);
617 sinkInputNode_->SetSpeed(speed);
618 CHECK_AND_RETURN_LOG(sinkOutputNode_, "sinkOutputNode is nullptr");
619 sinkOutputNode_->SetSpeed(speed);
620 };
621 SendRequest(request);
622 }
623
GetAllSinkInputsInfo()624 std::vector<SinkInput> HpaeOffloadRendererManager::GetAllSinkInputsInfo()
625 {
626 std::vector<SinkInput> sinkInputs;
627 return sinkInputs;
628 }
629
GetSinkInputInfo(uint32_t sessionId,HpaeSinkInputInfo & sinkInputInfo)630 int32_t HpaeOffloadRendererManager::GetSinkInputInfo(uint32_t sessionId, HpaeSinkInputInfo &sinkInputInfo)
631 {
632 CHECK_AND_RETURN_RET_LOG(sinkInputNode_ && sessionId == sinkInputNode_->GetSessionId(),
633 ERR_INVALID_OPERATION,
634 "RegisterWriteCallback not find sessionId %{public}u",
635 sessionId);
636 sinkInputInfo.nodeInfo = sinkInputNode_->GetNodeInfo();
637 sinkInputInfo.rendererSessionInfo = sessionInfo_;
638 return SUCCESS;
639 }
640
RefreshProcessClusterByDevice()641 int32_t HpaeOffloadRendererManager::RefreshProcessClusterByDevice()
642 {
643 return SUCCESS;
644 }
645
GetSinkInfo()646 HpaeSinkInfo HpaeOffloadRendererManager::GetSinkInfo()
647 {
648 return sinkInfo_;
649 }
650
SendRequest(Request && request,bool isInit)651 void HpaeOffloadRendererManager::SendRequest(Request &&request, bool isInit)
652 {
653 CHECK_AND_RETURN_LOG(isInit || IsInit(), "HpaeOffloadRendererManager not init");
654 hpaeNoLockQueue_.PushRequest(std::move(request));
655 CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ offloadrenderer is nullptr");
656 hpaeSignalProcessThread_->Notify();
657 }
658
OnNodeStatusUpdate(uint32_t sessionId,IOperation operation)659 void HpaeOffloadRendererManager::OnNodeStatusUpdate(uint32_t sessionId, IOperation operation)
660 {
661 TriggerCallback(UPDATE_STATUS, HPAE_STREAM_CLASS_TYPE_PLAY, sessionId, sessionInfo_.state, operation);
662 }
663
OnRequestLatency(uint32_t sessionId,uint64_t & latency)664 void HpaeOffloadRendererManager::OnRequestLatency(uint32_t sessionId, uint64_t &latency)
665 {
666 latency = sinkOutputNode_->GetLatency();
667 }
668
OnRewindAndFlush(uint64_t rewindTime,uint64_t hdiFramePosition)669 void HpaeOffloadRendererManager::OnRewindAndFlush(uint64_t rewindTime, uint64_t hdiFramePosition)
670 {
671 CHECK_AND_RETURN_LOG(sinkInputNode_ != nullptr,
672 "HpaeOffloadRendererManager::OnRewindAndFlush sinkInputNode_ is null");
673 sinkInputNode_->RewindHistoryBuffer(rewindTime, hdiFramePosition);
674 }
675
OnNotifyQueue()676 void HpaeOffloadRendererManager::OnNotifyQueue()
677 {
678 CHECK_AND_RETURN_LOG(hpaeSignalProcessThread_, "hpaeSignalProcessThread_ offloadrenderer is nullptr");
679 hpaeSignalProcessThread_->Notify();
680 }
681
GetThreadName()682 std::string HpaeOffloadRendererManager::GetThreadName()
683 {
684 return sinkInfo_.deviceName;
685 }
686
DumpSinkInfo()687 int32_t HpaeOffloadRendererManager::DumpSinkInfo()
688 {
689 CHECK_AND_RETURN_RET_LOG(IsInit(), ERR_ILLEGAL_STATE, "HpaeOffloadRendererManager not init");
690 auto request = [this]() {
691 AUDIO_INFO_LOG("DumpSinkInfo deviceName %{public}s", sinkInfo_.deviceName.c_str());
692 UploadDumpSinkInfo(sinkInfo_.deviceName);
693 };
694 SendRequest(request);
695 return SUCCESS;
696 }
697
GetDeviceHDFDumpInfo()698 std::string HpaeOffloadRendererManager::GetDeviceHDFDumpInfo()
699 {
700 std::string config;
701 TransDeviceInfoToString(sinkInfo_, config);
702 return config;
703 }
704
SetLoudnessGain(uint32_t sessionId,float loudnessGain)705 int32_t HpaeOffloadRendererManager::SetLoudnessGain(uint32_t sessionId, float loudnessGain)
706 {
707 auto request = [this, sessionId, loudnessGain]() {
708 CHECK_AND_RETURN_LOG(sinkInputNode_, "sessionId %{public}d, sinkInputNode is nullptr", sessionId);
709 CHECK_AND_RETURN_LOG(sinkInputNode_->GetSessionId() == sessionId,
710 "sessionId %{public}d is not current sessionid %{public}d for offload",
711 sessionId, sinkInputNode_->GetSessionId());
712 sinkInputNode_->SetLoudnessGain(loudnessGain);
713 CHECK_AND_RETURN_LOG(loudnessGainNode_, "session id %{public}d is not connected", sessionId);
714 loudnessGainNode_->SetLoudnessGain(loudnessGain);
715 };
716 SendRequest(request);
717 return SUCCESS;
718 }
719
GetNodeInputFormatInfo(uint32_t sessionId,AudioBasicFormat & basicFormat)720 int32_t HpaeOffloadRendererManager::GetNodeInputFormatInfo(uint32_t sessionId, AudioBasicFormat &basicFormat)
721 {
722 CHECK_AND_RETURN_RET_LOG(loudnessGainNode_, ERROR, "sessionId %{public}d, gainNode does not exist", sessionId);
723 CHECK_AND_RETURN_RET_LOG(loudnessGainNode_->GetSessionId() == sessionId, ERROR, "loudness node id %{public}d,"
724 "set sessionId %{public}d does not match!", loudnessGainNode_->GetSessionId(), sessionId);
725 basicFormat.audioChannelInfo.channelLayout = (AudioChannelLayout)sinkInfo_.channelLayout;
726 basicFormat.audioChannelInfo.numChannels = (uint32_t)sinkInfo_.channels;
727 basicFormat.rate = sinkInfo_.samplingRate;
728 if (loudnessGainNode_->IsLoudnessAlgoOn()) {
729 // has loudness gain algorithm, should convert to 48k, channels and chanellayout stay same as input
730 basicFormat.rate = SAMPLE_RATE_48000;
731 }
732 return SUCCESS;
733 }
734 } // namespace HPAE
735 } // namespace AudioStandard
736 } // namespace OHOS