• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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