1 /*
2 * Copyright (c) 2021-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 "AudioOffloadStream"
17 #endif
18
19 #include "audio_offload_stream.h"
20 #include <ability_manager_client.h>
21 #include "iservice_registry.h"
22 #include "parameter.h"
23 #include "parameters.h"
24 #include "audio_policy_log.h"
25 #include "media_monitor_manager.h"
26 #include "audio_spatialization_service.h"
27
28 #include "audio_policy_utils.h"
29 #include "audio_server_proxy.h"
30 #include "audio_config_manager.h"
31
32 namespace OHOS {
33 namespace AudioStandard {
34
35 const int32_t UID_AUDIO = 1041;
36 const int32_t dAudioClientUid = 3055;
37 static const int32_t WAIT_OFFLOAD_CLOSE_TIME_S = 10; // 10s
38
PrintSinkInput(SinkInput sinkInput)39 inline std::string PrintSinkInput(SinkInput sinkInput)
40 {
41 std::stringstream value;
42 value << "streamId:[" << sinkInput.streamId << "] ";
43 value << "streamType:[" << sinkInput.streamType << "] ";
44 value << "uid:[" << sinkInput.uid << "] ";
45 value << "pid:[" << sinkInput.pid << "] ";
46 value << "statusMark:[" << sinkInput.statusMark << "] ";
47 value << "sinkName:[" << sinkInput.sinkName << "] ";
48 value << "startTime:[" << sinkInput.startTime << "]";
49 return value.str();
50 }
51
HandlePowerStateChanged(PowerMgr::PowerState state)52 void AudioOffloadStream::HandlePowerStateChanged(PowerMgr::PowerState state)
53 {
54 if (currentPowerState_ == state) {
55 return;
56 }
57 currentPowerState_ = state;
58 if (!audioActiveDevice_.CheckActiveOutputDeviceSupportOffload()) {
59 return;
60 }
61 if (offloadSessionID_.has_value()) {
62 AUDIO_DEBUG_LOG("SetOffloadMode! Offload power is state = %{public}d", state);
63 SetOffloadMode();
64 }
65 }
66
SetOffloadAvailableFromXML(AudioModuleInfo & moduleInfo)67 void AudioOffloadStream::SetOffloadAvailableFromXML(AudioModuleInfo &moduleInfo)
68 {
69 if (moduleInfo.name == "Speaker") {
70 for (const auto &portInfo : moduleInfo.ports) {
71 if ((portInfo.adapterName == "primary") && (portInfo.offloadEnable == "1")) {
72 isOffloadAvailable_ = true;
73 }
74 }
75 }
76 }
77
GetOffloadAvailableFromXml() const78 bool AudioOffloadStream::GetOffloadAvailableFromXml() const
79 {
80 return isOffloadAvailable_;
81 }
82
SetOffloadMode()83 void AudioOffloadStream::SetOffloadMode()
84 {
85 if (!GetOffloadAvailableFromXml()) {
86 AUDIO_INFO_LOG("Offload not available, skipped");
87 return;
88 }
89
90 AUDIO_INFO_LOG("sessionId: %{public}d, PowerState: %{public}d, isAppBack: %{public}d",
91 *offloadSessionID_, static_cast<int32_t>(currentPowerState_), currentOffloadSessionIsBackground_);
92 AudioServerProxy::GetInstance().SetOffloadModeProxy(*offloadSessionID_, static_cast<int32_t>(currentPowerState_),
93 currentOffloadSessionIsBackground_);
94 }
95
OffloadStreamSetCheck(uint32_t sessionId)96 void AudioOffloadStream::OffloadStreamSetCheck(uint32_t sessionId)
97 {
98 AudioPipeType pipeType = PIPE_TYPE_OFFLOAD;
99 int32_t ret = AudioStreamCollector::GetAudioStreamCollector().ActivateAudioConcurrency(pipeType);
100 if (ret != SUCCESS) {
101 return;
102 }
103 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
104 std::string curOutputNetworkId = audioActiveDevice_.GetCurrentOutputDeviceNetworkId();
105 std::string curOutputMacAddr = audioActiveDevice_.GetCurrentOutputDeviceMacAddr();
106 DeviceType curOutputDeviceType = audioActiveDevice_.GetCurrentOutputDeviceType();
107 ret = streamCollector_.GetRendererDeviceInfo(sessionId, deviceInfo);
108 if (ret != SUCCESS || curOutputNetworkId != LOCAL_NETWORK_ID ||
109 curOutputDeviceType == DEVICE_TYPE_REMOTE_CAST ||
110 deviceInfo.deviceType_ != curOutputDeviceType ||
111 deviceInfo.networkId_ != curOutputNetworkId ||
112 deviceInfo.macAddress_ != curOutputMacAddr) {
113 AUDIO_INFO_LOG("sessionId[%{public}d] not fetch device, Offload Skipped", sessionId);
114 return;
115 }
116
117 AudioStreamType streamType = streamCollector_.GetStreamType(sessionId);
118 if (!CheckStreamOffloadMode(sessionId, streamType)) {
119 return;
120 }
121
122 auto CallingUid = IPCSkeleton::GetCallingUid();
123 AUDIO_INFO_LOG("sessionId[%{public}d] CallingUid[%{public}d] StreamType[%{public}d] "
124 "Getting offload stream", sessionId, CallingUid, streamType);
125 std::lock_guard<std::mutex> lock(offloadMutex_);
126
127 if (!offloadSessionID_.has_value()) {
128 offloadSessionID_ = sessionId;
129 audioPolicyManager_.SetOffloadSessionId(sessionId);
130
131 AUDIO_DEBUG_LOG("sessionId[%{public}d] try get offload stream", sessionId);
132 if (MoveToNewPipeInner(sessionId, PIPE_TYPE_OFFLOAD) != SUCCESS) {
133 AUDIO_ERR_LOG("sessionId[%{public}d] CallingUid[%{public}d] StreamType[%{public}d] "
134 "failed to offload stream", sessionId, CallingUid, streamType);
135 offloadSessionID_.reset();
136 audioPolicyManager_.ResetOffloadSessionId();
137 return;
138 }
139 SetOffloadMode();
140 } else {
141 if (sessionId == *(offloadSessionID_)) {
142 AUDIO_DEBUG_LOG("sessionId[%{public}d] is already get offload stream", sessionId);
143 } else {
144 AUDIO_DEBUG_LOG("sessionId[%{public}d] no get offload, current offload sessionId[%{public}d]",
145 sessionId, *(offloadSessionID_));
146 }
147 }
148
149 return;
150 }
151
CheckStreamOffloadMode(int64_t activateSessionId,AudioStreamType streamType)152 bool AudioOffloadStream::CheckStreamOffloadMode(int64_t activateSessionId, AudioStreamType streamType)
153 {
154 if (!GetOffloadAvailableFromXml()) {
155 AUDIO_INFO_LOG("Offload not available, skipped for set");
156 return false;
157 }
158
159 if (!audioActiveDevice_.CheckActiveOutputDeviceSupportOffload()) {
160 AUDIO_PRERELEASE_LOGI("Offload not available on current output device, skipped");
161 return false;
162 }
163
164 if (!streamCollector_.IsOffloadAllowed(activateSessionId)) {
165 AUDIO_PRERELEASE_LOGI("Offload is not allowed, Skipped");
166 return false;
167 }
168
169 if ((streamType != STREAM_MUSIC) && (streamType != STREAM_SPEECH)) {
170 AUDIO_DEBUG_LOG("StreamType not allowed get offload mode, Skipped");
171 return false;
172 }
173
174 AudioPipeType pipeType;
175 streamCollector_.GetPipeType(activateSessionId, pipeType);
176 if (pipeType == PIPE_TYPE_DIRECT_MUSIC) {
177 AUDIO_INFO_LOG("stream is direct, Skipped");
178 return false;
179 }
180
181 int32_t channelCount = streamCollector_.GetChannelCount(activateSessionId);
182 if ((channelCount != AudioChannel::MONO) && (channelCount != AudioChannel::STEREO)) {
183 AUDIO_DEBUG_LOG("ChannelNum not allowed get offload mode, Skipped");
184 return false;
185 }
186
187 int32_t offloadUID = streamCollector_.GetUid(activateSessionId);
188 if (offloadUID == -1) {
189 AUDIO_DEBUG_LOG("offloadUID not valid, Skipped");
190 return false;
191 }
192 if (offloadUID == UID_AUDIO) {
193 AUDIO_DEBUG_LOG("Skip anco_audio out of offload mode");
194 return false;
195 }
196
197 if (CheckSpatializationAndEffectState()) {
198 AUDIO_INFO_LOG("spatialization effect in arm, Skipped");
199 return false;
200 }
201 return true;
202 }
203
ConstructMchAudioModuleInfo(DeviceType deviceType)204 AudioModuleInfo AudioOffloadStream::ConstructMchAudioModuleInfo(DeviceType deviceType)
205 {
206 AudioModuleInfo audioModuleInfo = {};
207 audioModuleInfo.lib = "libmodule-hdi-sink.z.so";
208 audioModuleInfo.format = "s32le"; // 32bit little endian
209 audioModuleInfo.fixedLatency = "1"; // here we need to set latency fixed for a fixed buffer size.
210
211 // used as "sink_name" in hdi_sink.c, hope we could use name to find target sink.
212 audioModuleInfo.name = MCH_PRIMARY_SPEAKER;
213
214 std::stringstream typeValue;
215 typeValue << static_cast<int32_t>(deviceType);
216 audioModuleInfo.deviceType = typeValue.str();
217
218 audioModuleInfo.defaultAdapterEnable = AudioConfigManager::GetInstance().GetDefaultAdapterEnable() ? "1" : "0";
219 audioModuleInfo.adapterName = "primary";
220 audioModuleInfo.className = "multichannel"; // used in renderer_sink_adapter.c
221 audioModuleInfo.fileName = "mch_dump_file";
222
223 audioModuleInfo.channels = "6";
224 audioModuleInfo.rate = "48000";
225 audioModuleInfo.bufferSize = "7680";
226
227 return audioModuleInfo;
228 }
229
CheckSpatializationAndEffectState()230 bool AudioOffloadStream::CheckSpatializationAndEffectState()
231 {
232 AudioSpatializationState spatialState =
233 AudioSpatializationService::GetAudioSpatializationService().GetSpatializationState();
234 bool effectOffloadFlag = AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
235 return spatialState.spatializationEnabled && !effectOffloadFlag;
236 }
237
LoadMchModule()238 int32_t AudioOffloadStream::LoadMchModule()
239 {
240 AUDIO_INFO_LOG("load multichannel mode");
241 DeviceType deviceType = DEVICE_TYPE_SPEAKER;
242 AudioModuleInfo moduleInfo = ConstructMchAudioModuleInfo(deviceType);
243 audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
244 return SUCCESS;
245 }
246
UnloadMchModule()247 int32_t AudioOffloadStream::UnloadMchModule()
248 {
249 AUDIO_INFO_LOG("unload multichannel module");
250 return audioIOHandleMap_.ClosePortAndEraseIOHandle(MCH_PRIMARY_SPEAKER);
251 }
252
MoveToNewPipeInner(uint32_t sessionId,AudioPipeType pipeType)253 int32_t AudioOffloadStream::MoveToNewPipeInner(uint32_t sessionId, AudioPipeType pipeType)
254 {
255 AudioPipeType oldPipeType;
256 streamCollector_.GetPipeType(sessionId, oldPipeType);
257 if (oldPipeType == pipeType) {
258 AUDIO_ERR_LOG("the same type [%{public}d],no need to move", pipeType);
259 return SUCCESS;
260 }
261 Trace trace("AudioOffloadStream::MoveToNewPipeInner");
262 AUDIO_INFO_LOG("start move stream into new pipe %{public}d", pipeType);
263 int32_t ret = ERROR;
264 std::string portName = PORT_NONE;
265 AudioStreamType streamType = streamCollector_.GetStreamType(sessionId);
266 DeviceType deviceType = audioActiveDevice_.GetCurrentOutputDeviceType();
267 switch (pipeType) {
268 case PIPE_TYPE_OFFLOAD: {
269 if (!CheckStreamOffloadMode(sessionId, streamType)) {
270 return ERROR;
271 }
272 if (LoadOffloadModule() != SUCCESS) {
273 return ERROR;
274 }
275 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
276 ret = MoveToOutputDevice(sessionId, portName);
277 break;
278 }
279 case PIPE_TYPE_MULTICHANNEL: {
280 if (!CheckStreamMultichannelMode(sessionId)) {
281 return ERROR;
282 }
283
284 if (audioIOHandleMap_.CheckIOHandleExist(MCH_PRIMARY_SPEAKER) == false) {
285 // load moudle and move into new sink
286 LoadMchModule();
287 }
288 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
289 ret = MoveToOutputDevice(sessionId, portName);
290 break;
291 }
292 case PIPE_TYPE_NORMAL_OUT: {
293 portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType, pipeType);
294 ret = MoveToOutputDevice(sessionId, portName);
295 break;
296 }
297 default:
298 AUDIO_WARNING_LOG("not supported for pipe type %{public}d", pipeType);
299 break;
300 }
301 if (ret == SUCCESS) {
302 streamCollector_.UpdateRendererPipeInfo(sessionId, pipeType);
303 }
304 return ret;
305 }
306
ResetOffloadMode(int32_t sessionId)307 void AudioOffloadStream::ResetOffloadMode(int32_t sessionId)
308 {
309 AUDIO_DEBUG_LOG("Doing reset offload mode!");
310
311 if (!audioActiveDevice_.CheckActiveOutputDeviceSupportOffload()) {
312 AUDIO_DEBUG_LOG("Resetting offload not available on this output device! Release.");
313 OffloadStreamReleaseCheck(*offloadSessionID_);
314 return;
315 }
316
317 OffloadStreamSetCheck(sessionId);
318 }
319
OffloadStreamReleaseCheck(uint32_t sessionId)320 void AudioOffloadStream::OffloadStreamReleaseCheck(uint32_t sessionId)
321 {
322 if (!GetOffloadAvailableFromXml()) {
323 AUDIO_INFO_LOG("Offload not available, skipped for release");
324 return;
325 }
326
327 std::lock_guard<std::mutex> lock(offloadMutex_);
328
329 if (((*offloadSessionID_) == sessionId) && offloadSessionID_.has_value()) {
330 AUDIO_DEBUG_LOG("Doing unset offload mode!");
331 AudioServerProxy::GetInstance().UnsetOffloadModeProxy(*offloadSessionID_);
332 AudioPipeType normalPipe = PIPE_TYPE_NORMAL_OUT;
333 MoveToNewPipe(sessionId, normalPipe);
334 streamCollector_.UpdateRendererPipeInfo(sessionId, normalPipe);
335 DynamicUnloadOffloadModule();
336 offloadSessionID_.reset();
337 audioPolicyManager_.ResetOffloadSessionId();
338 AUDIO_DEBUG_LOG("sessionId[%{public}d] release offload stream", sessionId);
339 } else {
340 if (offloadSessionID_.has_value()) {
341 AUDIO_DEBUG_LOG("sessionId[%{public}d] stopping stream not get offload, current offload [%{public}d]",
342 sessionId, *offloadSessionID_);
343 } else {
344 AUDIO_DEBUG_LOG("sessionId[%{public}d] stopping stream not get offload, current offload stream is None",
345 sessionId);
346 }
347 }
348 return;
349 }
350
MoveToNewPipe(uint32_t sessionId,AudioPipeType pipeType)351 int32_t AudioOffloadStream::MoveToNewPipe(uint32_t sessionId, AudioPipeType pipeType)
352 {
353 // Check if the stream exists
354 int32_t defaultUid = -1;
355 if (defaultUid == streamCollector_.GetUid(sessionId)) {
356 AUDIO_ERR_LOG("The audio stream information [%{public}d] is illegal", sessionId);
357 return ERROR;
358 }
359 // move the stream to new pipe
360 return MoveToNewPipeInner(sessionId, pipeType);
361 }
362
ConstructOffloadAudioModuleInfo(DeviceType deviceType)363 AudioModuleInfo AudioOffloadStream::ConstructOffloadAudioModuleInfo(DeviceType deviceType)
364 {
365 AudioModuleInfo audioModuleInfo = {};
366 audioModuleInfo.lib = "libmodule-hdi-sink.z.so";
367 audioModuleInfo.format = "s32le"; // 32bit little endian
368 audioModuleInfo.fixedLatency = "1"; // here we need to set latency fixed for a fixed buffer size.
369
370 // used as "sink_name" in hdi_sink.c, hope we could use name to find target sink.
371 audioModuleInfo.name = OFFLOAD_PRIMARY_SPEAKER;
372
373 std::stringstream typeValue;
374 typeValue << static_cast<int32_t>(deviceType);
375 audioModuleInfo.deviceType = typeValue.str();
376
377 audioModuleInfo.adapterName = "primary";
378 audioModuleInfo.className = "offload"; // used in renderer_sink_adapter.c
379 audioModuleInfo.fileName = "offload_dump_file";
380 audioModuleInfo.offloadEnable = "1";
381
382 audioModuleInfo.channels = "2";
383 audioModuleInfo.rate = "48000";
384 audioModuleInfo.bufferSize = "7680";
385
386 return audioModuleInfo;
387 }
388
LoadOffloadModule()389 int32_t AudioOffloadStream::LoadOffloadModule()
390 {
391 AUDIO_INFO_LOG("load offload mode");
392 std::unique_lock<std::mutex> lock(offloadCloseMutex_);
393 isOffloadOpened_.store(true);
394 offloadCloseCondition_.notify_all();
395 {
396 std::lock_guard<std::mutex> lk(offloadOpenMutex_);
397 if (audioIOHandleMap_.CheckIOHandleExist(OFFLOAD_PRIMARY_SPEAKER)) {
398 AUDIO_INFO_LOG("offload is open");
399 return SUCCESS;
400 }
401
402 DeviceType deviceType = DEVICE_TYPE_SPEAKER;
403 AudioModuleInfo moduleInfo = ConstructOffloadAudioModuleInfo(deviceType);
404 return audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
405 }
406 return SUCCESS;
407 }
408
UnloadOffloadModule()409 int32_t AudioOffloadStream::UnloadOffloadModule()
410 {
411 AUDIO_INFO_LOG("unload offload module");
412 std::unique_lock<std::mutex> lock(offloadCloseMutex_);
413 // Try to wait 3 seconds before unloading the module, because the audio driver takes some time to process
414 // the shutdown process..
415 offloadCloseCondition_.wait_for(lock, std::chrono::seconds(WAIT_OFFLOAD_CLOSE_TIME_S),
416 [this] () { return isOffloadOpened_.load(); });
417 {
418 std::lock_guard<std::mutex> lk(offloadOpenMutex_);
419 if (isOffloadOpened_.load()) {
420 AUDIO_INFO_LOG("offload restart");
421 return ERROR;
422 }
423 audioIOHandleMap_.ClosePortAndEraseIOHandle(OFFLOAD_PRIMARY_SPEAKER);
424 }
425 return SUCCESS;
426 }
427
428
DynamicUnloadOffloadModule()429 int32_t AudioOffloadStream::DynamicUnloadOffloadModule()
430 {
431 if (isOffloadOpened_.load()) {
432 isOffloadOpened_.store(false);
433 auto unloadFirOffloadThrd = [this] { this->UnloadOffloadModule(); };
434 std::thread unloadOffloadThrd(unloadFirOffloadThrd);
435 unloadOffloadThrd.detach();
436 }
437 return SUCCESS;
438 }
439
RemoteOffloadStreamRelease(uint32_t sessionId)440 void AudioOffloadStream::RemoteOffloadStreamRelease(uint32_t sessionId)
441 {
442 std::lock_guard<std::mutex> lock(offloadMutex_);
443 if (offloadSessionID_.has_value() && ((*offloadSessionID_) == sessionId)) {
444 AUDIO_DEBUG_LOG("Doing unset offload mode!");
445 AudioServerProxy::GetInstance().UnsetOffloadModeProxy(*offloadSessionID_);
446 AudioPipeType normalPipe = PIPE_TYPE_UNKNOWN;
447 MoveToNewPipe(sessionId, normalPipe);
448 streamCollector_.UpdateRendererPipeInfo(sessionId, normalPipe);
449 DynamicUnloadOffloadModule();
450 offloadSessionID_.reset();
451 audioPolicyManager_.ResetOffloadSessionId();
452 AUDIO_DEBUG_LOG("sessionId[%{public}d] release offload stream", sessionId);
453 }
454 }
455
MoveToOutputDevice(uint32_t sessionId,std::string portName)456 int32_t AudioOffloadStream::MoveToOutputDevice(uint32_t sessionId, std::string portName)
457 {
458 std::vector<SinkInput> sinkInputs;
459 audioPolicyManager_.GetAllSinkInputs(sinkInputs);
460 std::vector<SinkInput> sinkInputIds = FilterSinkInputs(sessionId, sinkInputs);
461
462 if (portName == BLUETOOTH_SPEAKER) {
463 std::string activePort = BLUETOOTH_SPEAKER;
464 audioPolicyManager_.SuspendAudioDevice(activePort, false);
465 }
466 AUDIO_INFO_LOG("move for session [%{public}d], portName %{public}s", sessionId, portName.c_str());
467 // start move.
468 uint32_t sinkId = -1; // invalid sink id, use sink name instead.
469 for (size_t i = 0; i < sinkInputIds.size(); i++) {
470 int32_t ret = audioPolicyManager_.MoveSinkInputByIndexOrName(sinkInputIds[i].paStreamId, sinkId, portName);
471 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR,
472 "move [%{public}d] to local failed", sinkInputIds[i].streamId);
473 audioRouteMap_.AddRouteMapInfo(sinkInputIds[i].uid, LOCAL_NETWORK_ID, sinkInputIds[i].pid);
474 }
475 return SUCCESS;
476 }
477
CheckStreamMultichannelMode(const int64_t activateSessionId)478 bool AudioOffloadStream::CheckStreamMultichannelMode(const int64_t activateSessionId)
479 {
480 if (audioActiveDevice_.GetCurrentOutputDeviceNetworkId() != LOCAL_NETWORK_ID ||
481 audioActiveDevice_.GetCurrentOutputDeviceType() == DEVICE_TYPE_REMOTE_CAST) {
482 return false;
483 }
484
485 // Multi-channel mode only when the number of channels is greater than 2.
486 int32_t channelCount = streamCollector_.GetChannelCount(activateSessionId);
487 if (channelCount < AudioChannel::CHANNEL_3) {
488 AUDIO_DEBUG_LOG("ChannelNum not allowed get multichannel mode, Skipped");
489 return false;
490 }
491
492 // The multi-channel algorithm needs to be supported in the DSP
493 return AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
494 }
CheckStreamMode(const int64_t activateSessionId)495 void AudioOffloadStream::CheckStreamMode(const int64_t activateSessionId)
496 {
497 if (CheckStreamMultichannelMode(activateSessionId)) {
498 AudioPipeType pipeMultiChannel = PIPE_TYPE_MULTICHANNEL;
499 int32_t ret = streamCollector_.ActivateAudioConcurrency(pipeMultiChannel);
500 CHECK_AND_RETURN_LOG(ret == SUCCESS, "concede incoming multichannel");
501 MoveToNewPipeInner(activateSessionId, PIPE_TYPE_MULTICHANNEL);
502 }
503 }
504
FilterSinkInputs(int32_t sessionId,std::vector<SinkInput> sinkInputs)505 std::vector<SinkInput> AudioOffloadStream::FilterSinkInputs(int32_t sessionId, std::vector<SinkInput> sinkInputs)
506 {
507 // find sink-input id with audioRendererFilter
508 std::vector<SinkInput> targetSinkInputs = {};
509
510 for (size_t i = 0; i < sinkInputs.size(); i++) {
511 CHECK_AND_CONTINUE_LOG(sinkInputs[i].uid != dAudioClientUid,
512 "Find sink-input with daudio[%{public}d]", sinkInputs[i].pid);
513 CHECK_AND_CONTINUE_LOG(sinkInputs[i].streamType != STREAM_DEFAULT,
514 "Sink-input[%{public}zu] of effect sink, don't move", i);
515 AUDIO_DEBUG_LOG("sinkinput[%{public}zu]:%{public}s", i, PrintSinkInput(sinkInputs[i]).c_str());
516 if (sessionId == sinkInputs[i].streamId) {
517 targetSinkInputs.push_back(sinkInputs[i]);
518 }
519 }
520 return targetSinkInputs;
521 }
522
ResetOffloadModeOnSpatializationChanged(std::vector<int32_t> & allSessions)523 void AudioOffloadStream::ResetOffloadModeOnSpatializationChanged(std::vector<int32_t> &allSessions)
524 {
525 AudioSpatializationState spatialState =
526 AudioSpatializationService::GetAudioSpatializationService().GetSpatializationState();
527 bool effectOffloadFlag = AudioServerProxy::GetInstance().GetEffectOffloadEnabledProxy();
528 AUDIO_INFO_LOG("spatialization: %{public}d, headTracking: %{public}d, effectOffloadFlag: %{public}d",
529 spatialState.spatializationEnabled, spatialState.headTrackingEnabled, effectOffloadFlag);
530 if (spatialState.spatializationEnabled) {
531 if (effectOffloadFlag) {
532 for (auto it = allSessions.begin(); it != allSessions.end(); it++) {
533 OffloadStreamSetCheck(*it);
534 }
535 } else {
536 OffloadStreamReleaseCheck(*offloadSessionID_);
537 }
538 }
539 }
540
ActivateConcurrencyFromServer(AudioPipeType incomingPipe)541 int32_t AudioOffloadStream::ActivateConcurrencyFromServer(AudioPipeType incomingPipe)
542 {
543 std::lock_guard<std::mutex> lock(offloadMutex_);
544 CHECK_AND_RETURN_RET_LOG(!offloadSessionID_.has_value(),
545 ERR_ILLEGAL_STATE, "Offload stream existing, concede incoming lowlatency stream");
546 return SUCCESS;
547 }
548
549 }
550 }