1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef FAST_AUDIO_STREAM_H
16 #define FAST_AUDIO_STREAM_H
17
18 #ifndef LOG_TAG
19 #define LOG_TAG "RendererInClientInner"
20 #endif
21
22 #include "futex_tool.h"
23 #include "renderer_in_client.h"
24 #include "renderer_in_client_private.h"
25
26 #include "audio_errors.h"
27 #include "audio_policy_manager.h"
28 #include "audio_manager_base.h"
29 #include "audio_renderer_log.h"
30 #include "audio_ring_cache.h"
31 #include "audio_channel_blend.h"
32 #include "audio_server_death_recipient.h"
33 #include "audio_stream_tracker.h"
34 #include "audio_system_manager.h"
35 #include "audio_utils.h"
36 #include "futex_tool.h"
37 #include "ipc_stream_listener_impl.h"
38 #include "ipc_stream_listener_stub.h"
39 #include "volume_ramp.h"
40 #include "callback_handler.h"
41 #include "audio_speed.h"
42 #include "audio_spatial_channel_converter.h"
43 #include "audio_policy_manager.h"
44 #include "audio_spatialization_manager.h"
45 #include "policy_handler.h"
46 #include "audio_log_utils.h"
47
48 #include "media_monitor_manager.h"
49 using namespace OHOS::HiviewDFX;
50 using namespace OHOS::AppExecFwk;
51
52 namespace OHOS {
53 namespace AudioStandard {
54 namespace {
55 const uint64_t OLD_BUF_DURATION_IN_USEC = 92880; // This value is used for compatibility purposes.
56 const uint64_t MAX_BUF_DURATION_IN_USEC = 2000000; // 2S
57 const uint64_t AUDIO_FIRST_FRAME_LATENCY = 120; //ms
58 static const size_t MAX_WRITE_SIZE = 20 * 1024 * 1024; // 20M
59 static const int32_t CREATE_TIMEOUT_IN_SECOND = 9; // 9S
60 static const int32_t OPERATION_TIMEOUT_IN_MS = 1000; // 1000ms
61 static const int32_t OFFLOAD_OPERATION_TIMEOUT_IN_MS = 8000; // 8000ms for offload
62 static const int32_t WRITE_CACHE_TIMEOUT_IN_MS = 1500; // 1500ms
63 static const int32_t WRITE_BUFFER_TIMEOUT_IN_MS = 20; // ms
64 static const int32_t SHORT_TIMEOUT_IN_MS = 20; // ms
65 static const uint32_t WAIT_FOR_NEXT_CB = 5000; // 5ms
66 static const int32_t HALF_FACTOR = 2;
67 static const int32_t DATA_CONNECTION_TIMEOUT_IN_MS = 1000; // ms
68 static constexpr int CB_QUEUE_CAPACITY = 3;
69 constexpr int32_t MAX_BUFFER_SIZE = 100000;
70 static constexpr int32_t ONE_MINUTE = 60;
71 static constexpr int32_t MEDIA_SERVICE_UID = 1013;
72 static const int32_t MAX_WRITE_INTERVAL_MS = 40;
73 } // namespace
74
75 static AppExecFwk::BundleInfo gBundleInfo_;
76
GetInstance(AudioStreamType eStreamType,int32_t appUid)77 std::shared_ptr<RendererInClient> RendererInClient::GetInstance(AudioStreamType eStreamType, int32_t appUid)
78 {
79 return std::make_shared<RendererInClientInner>(eStreamType, appUid);
80 }
81
RendererInClientInner(AudioStreamType eStreamType,int32_t appUid)82 RendererInClientInner::RendererInClientInner(AudioStreamType eStreamType, int32_t appUid)
83 : eStreamType_(eStreamType), appUid_(appUid), cbBufferQueue_(CB_QUEUE_CAPACITY)
84 {
85 AUDIO_INFO_LOG("Create with StreamType:%{public}d appUid:%{public}d ", eStreamType_, appUid_);
86 audioStreamTracker_ = std::make_unique<AudioStreamTracker>(AUDIO_MODE_PLAYBACK, appUid);
87 state_ = NEW;
88 }
89
~RendererInClientInner()90 RendererInClientInner::~RendererInClientInner()
91 {
92 AUDIO_INFO_LOG("~RendererInClientInner()");
93 DumpFileUtil::CloseDumpFile(&dumpOutFd_);
94 RendererInClientInner::ReleaseAudioStream(true);
95 std::lock_guard<std::mutex> runnerlock(runnerMutex_);
96 if (!runnerReleased_ && callbackHandler_ != nullptr) {
97 AUDIO_INFO_LOG("runner remove");
98 callbackHandler_->ReleaseEventRunner();
99 runnerReleased_ = true;
100 callbackHandler_ = nullptr;
101 }
102 UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
103 AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
104 }
105
OnOperationHandled(Operation operation,int64_t result)106 int32_t RendererInClientInner::OnOperationHandled(Operation operation, int64_t result)
107 {
108 Trace trace(traceTag_ + " OnOperationHandled:" + std::to_string(operation));
109 AUDIO_INFO_LOG("sessionId %{public}d recv operation:%{public}d result:%{public}" PRId64".", sessionId_, operation,
110 result);
111 if (operation == SET_OFFLOAD_ENABLE) {
112 AUDIO_INFO_LOG("SET_OFFLOAD_ENABLE result:%{public}" PRId64".", result);
113 if (!offloadEnable_ && static_cast<bool>(result)) {
114 offloadStartReadPos_ = 0;
115 }
116 offloadEnable_ = static_cast<bool>(result);
117 rendererInfo_.pipeType = offloadEnable_ ? PIPE_TYPE_OFFLOAD : PIPE_TYPE_NORMAL_OUT;
118 return SUCCESS;
119 }
120
121 if (operation == DATA_LINK_CONNECTING || operation == DATA_LINK_CONNECTED) {
122 if (operation == DATA_LINK_CONNECTING) {
123 isDataLinkConnected_ = false;
124 } else {
125 isDataLinkConnected_ = true;
126 dataConnectionCV_.notify_all();
127 }
128 return SUCCESS;
129 }
130
131 std::unique_lock<std::mutex> lock(callServerMutex_);
132 notifiedOperation_ = operation;
133 notifiedResult_ = result;
134
135 if (notifiedResult_ == SUCCESS) {
136 switch (operation) {
137 case START_STREAM :
138 state_ = RUNNING;
139 break;
140 case PAUSE_STREAM :
141 state_ = PAUSED;
142 break;
143 case STOP_STREAM :
144 state_ = STOPPED;
145 break;
146 default :
147 break;
148 }
149 } else {
150 AUDIO_ERR_LOG("operation %{public}d failed, result: %{public}" PRId64 "", operation, result);
151 }
152
153 callServerCV_.notify_all();
154 return SUCCESS;
155 }
156
SetClientID(int32_t clientPid,int32_t clientUid,uint32_t appTokenId,uint64_t fullTokenId)157 void RendererInClientInner::SetClientID(int32_t clientPid, int32_t clientUid, uint32_t appTokenId, uint64_t fullTokenId)
158 {
159 AUDIO_INFO_LOG("PID:%{public}d UID:%{public}d.", clientPid, clientUid);
160 clientPid_ = clientPid;
161 clientUid_ = clientUid;
162 appTokenId_ = appTokenId;
163 fullTokenId_ = fullTokenId;
164 }
165
UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig & config)166 int32_t RendererInClientInner::UpdatePlaybackCaptureConfig(const AudioPlaybackCaptureConfig &config)
167 {
168 AUDIO_ERR_LOG("Unsupported operation!");
169 return ERR_NOT_SUPPORTED;
170 }
171
SetRendererInfo(const AudioRendererInfo & rendererInfo)172 void RendererInClientInner::SetRendererInfo(const AudioRendererInfo &rendererInfo)
173 {
174 rendererInfo_ = rendererInfo;
175 if (rendererInfo_.streamUsage == STREAM_USAGE_SYSTEM ||
176 rendererInfo_.streamUsage == STREAM_USAGE_DTMF ||
177 rendererInfo_.streamUsage == STREAM_USAGE_ENFORCED_TONE ||
178 rendererInfo_.streamUsage == STREAM_USAGE_ULTRASONIC ||
179 rendererInfo_.streamUsage == STREAM_USAGE_NAVIGATION ||
180 rendererInfo_.streamUsage == STREAM_USAGE_NOTIFICATION) {
181 effectMode_ = EFFECT_NONE;
182 }
183 rendererInfo_.sceneType = GetEffectSceneName(rendererInfo_.streamUsage);
184 AUDIO_PRERELEASE_LOGI("SetRendererInfo with flag %{public}d, sceneType %{public}s", rendererInfo_.rendererFlags,
185 rendererInfo_.sceneType.c_str());
186 AudioSpatializationState spatializationState =
187 AudioPolicyManager::GetInstance().GetSpatializationState(rendererInfo_.streamUsage);
188 rendererInfo_.spatializationEnabled = spatializationState.spatializationEnabled;
189 rendererInfo_.headTrackingEnabled = spatializationState.headTrackingEnabled;
190 rendererInfo_.encodingType = curStreamParams_.encoding;
191 rendererInfo_.channelLayout = curStreamParams_.channelLayout;
192 UpdateTracker("UPDATE");
193 }
194
SetCapturerInfo(const AudioCapturerInfo & capturerInfo)195 void RendererInClientInner::SetCapturerInfo(const AudioCapturerInfo &capturerInfo)
196 {
197 AUDIO_WARNING_LOG("SetCapturerInfo is not supported");
198 return;
199 }
200
RegisterTracker(const std::shared_ptr<AudioClientTracker> & proxyObj)201 void RendererInClientInner::RegisterTracker(const std::shared_ptr<AudioClientTracker> &proxyObj)
202 {
203 if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) {
204 // make sure sessionId_ is valid.
205 AUDIO_INFO_LOG("Calling register tracker, sessionid is %{public}d", sessionId_);
206 AudioRegisterTrackerInfo registerTrackerInfo;
207
208 rendererInfo_.samplingRate = static_cast<AudioSamplingRate>(curStreamParams_.samplingRate);
209 rendererInfo_.format = static_cast<AudioSampleFormat>(curStreamParams_.format);
210 registerTrackerInfo.sessionId = sessionId_;
211 registerTrackerInfo.clientPid = clientPid_;
212 registerTrackerInfo.state = state_;
213 registerTrackerInfo.rendererInfo = rendererInfo_;
214 registerTrackerInfo.capturerInfo = capturerInfo_;
215 registerTrackerInfo.channelCount = curStreamParams_.channels;
216
217 audioStreamTracker_->RegisterTracker(registerTrackerInfo, proxyObj);
218 streamTrackerRegistered_ = true;
219 }
220 }
221
UpdateTracker(const std::string & updateCase)222 void RendererInClientInner::UpdateTracker(const std::string &updateCase)
223 {
224 if (audioStreamTracker_ && audioStreamTracker_.get()) {
225 AUDIO_DEBUG_LOG("Renderer:Calling Update tracker for %{public}s", updateCase.c_str());
226 audioStreamTracker_->UpdateTracker(sessionId_, state_, clientPid_, rendererInfo_, capturerInfo_);
227 }
228 }
229
IsHightResolution() const230 bool RendererInClientInner::IsHightResolution() const noexcept
231 {
232 return eStreamType_ == STREAM_MUSIC && curStreamParams_.samplingRate >= SAMPLE_RATE_48000 &&
233 curStreamParams_.format >= SAMPLE_S24LE;
234 }
235
SetAudioStreamInfo(const AudioStreamParams info,const std::shared_ptr<AudioClientTracker> & proxyObj)236 int32_t RendererInClientInner::SetAudioStreamInfo(const AudioStreamParams info,
237 const std::shared_ptr<AudioClientTracker> &proxyObj)
238 {
239 // In plan: If paramsIsSet_ is true, and new info is same as old info, return
240 AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d,"
241 " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format,
242 eStreamType_, info.encoding);
243
244 AudioXCollie guard("RendererInClientInner::SetAudioStreamInfo", CREATE_TIMEOUT_IN_SECOND);
245 if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) {
246 AUDIO_ERR_LOG("Unsupported audio parameter");
247 return ERR_NOT_SUPPORTED;
248 }
249
250 streamParams_ = curStreamParams_ = info; // keep it for later use
251 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
252 ConverterConfig cfg = AudioPolicyManager::GetInstance().GetConverterConfig();
253 converter_ = std::make_unique<AudioSpatialChannelConverter>();
254 if (converter_ == nullptr || !converter_->Init(curStreamParams_, cfg) || !converter_->AllocateMem()) {
255 AUDIO_ERR_LOG("AudioStream: converter construct error");
256 return ERR_NOT_SUPPORTED;
257 }
258 converter_->ConverterChannels(curStreamParams_.channels, curStreamParams_.channelLayout);
259 }
260
261 if (!IsPlaybackChannelRelatedInfoValid(curStreamParams_.channels, curStreamParams_.channelLayout)) {
262 return ERR_NOT_SUPPORTED;
263 }
264
265 CHECK_AND_RETURN_RET_LOG(IAudioStream::GetByteSizePerFrame(curStreamParams_, sizePerFrameInByte_) == SUCCESS,
266 ERROR_INVALID_PARAM, "GetByteSizePerFrame failed with invalid params");
267
268 if (state_ != NEW) {
269 AUDIO_ERR_LOG("State is not new, release existing stream and recreate, state %{public}d", state_.load());
270 int32_t ret = DeinitIpcStream();
271 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "release existing stream failed.");
272 }
273 paramsIsSet_ = true;
274 int32_t initRet = InitIpcStream();
275 CHECK_AND_RETURN_RET_LOG(initRet == SUCCESS, initRet, "Init stream failed: %{public}d", initRet);
276 state_ = PREPARED;
277
278 // eg: 100005_44100_2_1_client_out.pcm
279 dumpOutFile_ = std::to_string(sessionId_) + "_" + std::to_string(curStreamParams_.samplingRate) + "_" +
280 std::to_string(curStreamParams_.channels) + "_" + std::to_string(curStreamParams_.format) + "_client_out.pcm";
281
282 DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpOutFile_, &dumpOutFd_);
283 logUtilsTag_ = "[" + std::to_string(sessionId_) + "]NormalRenderer";
284 InitDirectPipeType();
285
286 proxyObj_ = proxyObj;
287 RegisterTracker(proxyObj);
288 RegisterSpatializationStateEventListener();
289 return SUCCESS;
290 }
291
InitDirectPipeType()292 void RendererInClientInner::InitDirectPipeType()
293 {
294 if (rendererInfo_.rendererFlags == AUDIO_FLAG_VOIP_DIRECT || IsHightResolution()) {
295 AudioPipeType originType = rendererInfo_.pipeType;
296 int32_t type = ipcStream_->GetStreamManagerType();
297 if (type == AUDIO_DIRECT_MANAGER_TYPE) {
298 rendererInfo_.pipeType = (rendererInfo_.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) ?
299 PIPE_TYPE_CALL_OUT : PIPE_TYPE_DIRECT_MUSIC;
300 } else if (originType == PIPE_TYPE_DIRECT_MUSIC) {
301 rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
302 }
303 }
304 }
305
306 std::mutex g_serverProxyMutex;
307 sptr<IStandardAudioService> gServerProxy_ = nullptr;
GetAudioServerProxy()308 const sptr<IStandardAudioService> RendererInClientInner::GetAudioServerProxy()
309 {
310 std::lock_guard<std::mutex> lock(g_serverProxyMutex);
311 if (gServerProxy_ == nullptr) {
312 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
313 if (samgr == nullptr) {
314 AUDIO_ERR_LOG("GetAudioServerProxy: get sa manager failed");
315 return nullptr;
316 }
317 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
318 if (object == nullptr) {
319 AUDIO_ERR_LOG("GetAudioServerProxy: get audio service remote object failed");
320 return nullptr;
321 }
322 gServerProxy_ = iface_cast<IStandardAudioService>(object);
323 if (gServerProxy_ == nullptr) {
324 AUDIO_ERR_LOG("GetAudioServerProxy: get audio service proxy failed");
325 return nullptr;
326 }
327
328 // register death recipent to restore proxy
329 sptr<AudioServerDeathRecipient> asDeathRecipient = new(std::nothrow) AudioServerDeathRecipient(getpid());
330 if (asDeathRecipient != nullptr) {
331 asDeathRecipient->SetNotifyCb([] (pid_t pid) { AudioServerDied(pid); });
332 bool result = object->AddDeathRecipient(asDeathRecipient);
333 if (!result) {
334 AUDIO_ERR_LOG("GetAudioServerProxy: failed to add deathRecipient");
335 }
336 }
337 }
338 sptr<IStandardAudioService> gasp = gServerProxy_;
339 return gasp;
340 }
341
AudioServerDied(pid_t pid)342 void RendererInClientInner::AudioServerDied(pid_t pid)
343 {
344 AUDIO_INFO_LOG("audio server died clear proxy, will restore proxy in next call");
345 std::lock_guard<std::mutex> lock(g_serverProxyMutex);
346 gServerProxy_ = nullptr;
347 }
348
OnHandle(uint32_t code,int64_t data)349 void RendererInClientInner::OnHandle(uint32_t code, int64_t data)
350 {
351 AUDIO_DEBUG_LOG("On handle event, event code: %{public}d, data: %{public}" PRIu64 "", code, data);
352 switch (code) {
353 case STATE_CHANGE_EVENT:
354 HandleStateChangeEvent(data);
355 break;
356 case RENDERER_MARK_REACHED_EVENT:
357 HandleRenderMarkReachedEvent(data);
358 break;
359 case RENDERER_PERIOD_REACHED_EVENT:
360 HandleRenderPeriodReachedEvent(data);
361 break;
362 default:
363 break;
364 }
365 }
366
HandleStateChangeEvent(int64_t data)367 void RendererInClientInner::HandleStateChangeEvent(int64_t data)
368 {
369 State state = INVALID;
370 StateChangeCmdType cmdType = CMD_FROM_CLIENT;
371 ParamsToStateCmdType(data, state, cmdType);
372 std::unique_lock<std::mutex> lock(streamCbMutex_);
373 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
374 if (streamCb != nullptr) {
375 state = state != STOPPING ? state : STOPPED; // client only need STOPPED
376 streamCb->OnStateChange(state, cmdType);
377 }
378 }
379
HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)380 void RendererInClientInner::HandleRenderMarkReachedEvent(int64_t rendererMarkPosition)
381 {
382 AUDIO_DEBUG_LOG("Start HandleRenderMarkReachedEvent");
383 std::unique_lock<std::mutex> lock(markReachMutex_);
384 if (rendererPositionCallback_) {
385 rendererPositionCallback_->OnMarkReached(rendererMarkPosition);
386 }
387 }
388
HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)389 void RendererInClientInner::HandleRenderPeriodReachedEvent(int64_t rendererPeriodNumber)
390 {
391 AUDIO_DEBUG_LOG("Start HandleRenderPeriodReachedEvent");
392 std::unique_lock<std::mutex> lock(periodReachMutex_);
393 if (rendererPeriodPositionCallback_) {
394 rendererPeriodPositionCallback_->OnPeriodReached(rendererPeriodNumber);
395 }
396 }
397
SafeSendCallbackEvent(uint32_t eventCode,int64_t data)398 void RendererInClientInner::SafeSendCallbackEvent(uint32_t eventCode, int64_t data)
399 {
400 std::lock_guard<std::mutex> lock(runnerMutex_);
401 AUDIO_INFO_LOG("Send callback event, code: %{public}u, data: %{public}" PRId64 "", eventCode, data);
402 CHECK_AND_RETURN_LOG(callbackHandler_ != nullptr && runnerReleased_ == false, "Runner is Released");
403 callbackHandler_->SendCallbackEvent(eventCode, data);
404 }
405
InitCallbackHandler()406 void RendererInClientInner::InitCallbackHandler()
407 {
408 std::lock_guard<std::mutex> lock(runnerMutex_);
409 if (callbackHandler_ == nullptr) {
410 callbackHandler_ = CallbackHandler::GetInstance(shared_from_this(), "OS_AudioStateCB");
411 }
412 }
413
414 // call this without lock, we should be able to call deinit in any case.
DeinitIpcStream()415 int32_t RendererInClientInner::DeinitIpcStream()
416 {
417 Trace trace("RendererInClientInner::DeinitIpcStream");
418 ipcStream_->Release();
419 ringCache_->ResetBuffer();
420 return SUCCESS;
421 }
422
ConstructConfig()423 const AudioProcessConfig RendererInClientInner::ConstructConfig()
424 {
425 AudioProcessConfig config = {};
426
427 config.appInfo.appPid = clientPid_;
428 config.appInfo.appUid = clientUid_;
429 config.appInfo.appTokenId = appTokenId_;
430 config.appInfo.appFullTokenId = fullTokenId_;
431
432 config.streamInfo.channels = static_cast<AudioChannel>(curStreamParams_.channels);
433 config.streamInfo.encoding = static_cast<AudioEncodingType>(curStreamParams_.encoding);
434 config.streamInfo.format = static_cast<AudioSampleFormat>(curStreamParams_.format);
435 config.streamInfo.samplingRate = static_cast<AudioSamplingRate>(curStreamParams_.samplingRate);
436 config.streamInfo.channelLayout = static_cast<AudioChannelLayout>(curStreamParams_.channelLayout);
437 config.originalSessionId = curStreamParams_.originalSessionId;
438
439 config.audioMode = AUDIO_MODE_PLAYBACK;
440
441 if (rendererInfo_.rendererFlags != AUDIO_FLAG_NORMAL && rendererInfo_.rendererFlags != AUDIO_FLAG_VOIP_DIRECT) {
442 AUDIO_WARNING_LOG("ConstructConfig find renderer flag invalid:%{public}d", rendererInfo_.rendererFlags);
443 rendererInfo_.rendererFlags = 0;
444 }
445 config.rendererInfo = rendererInfo_;
446
447 config.capturerInfo = {};
448
449 config.streamType = eStreamType_;
450
451 config.deviceType = AudioPolicyManager::GetInstance().GetActiveOutputDevice();
452
453 config.privacyType = privacyType_;
454
455 clientConfig_ = config;
456
457 return config;
458 }
459
InitSharedBuffer()460 int32_t RendererInClientInner::InitSharedBuffer()
461 {
462 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "InitSharedBuffer failed, null ipcStream_.");
463 int32_t ret = ipcStream_->ResolveBuffer(clientBuffer_);
464
465 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && clientBuffer_ != nullptr, ret, "ResolveBuffer failed:%{public}d", ret);
466
467 uint32_t totalSizeInFrame = 0;
468 uint32_t byteSizePerFrame = 0;
469 ret = clientBuffer_->GetSizeParameter(totalSizeInFrame, spanSizeInFrame_, byteSizePerFrame);
470
471 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && byteSizePerFrame == sizePerFrameInByte_, ret, "GetSizeParameter failed"
472 ":%{public}d, byteSizePerFrame:%{public}u, sizePerFrameInByte_:%{public}zu", ret, byteSizePerFrame,
473 sizePerFrameInByte_);
474
475 clientSpanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame;
476
477 AUDIO_INFO_LOG("totalSizeInFrame_[%{public}u] spanSizeInFrame[%{public}u] sizePerFrameInByte_[%{public}zu]"
478 "clientSpanSizeInByte_[%{public}zu]", totalSizeInFrame, spanSizeInFrame_, sizePerFrameInByte_,
479 clientSpanSizeInByte_);
480
481 return SUCCESS;
482 }
483
484 // InitCacheBuffer should be able to modify the cache size between clientSpanSizeInByte_ and 4 * clientSpanSizeInByte_
InitCacheBuffer(size_t targetSize)485 int32_t RendererInClientInner::InitCacheBuffer(size_t targetSize)
486 {
487 CHECK_AND_RETURN_RET_LOG(clientSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "clientSpanSizeInByte_ invalid");
488
489 AUDIO_INFO_LOG("old size:%{public}zu, new size:%{public}zu", cacheSizeInByte_, targetSize);
490 cacheSizeInByte_ = targetSize;
491
492 if (ringCache_ == nullptr) {
493 ringCache_ = AudioRingCache::Create(cacheSizeInByte_);
494 } else {
495 OptResult result = ringCache_->ReConfig(cacheSizeInByte_, false); // false --> clear buffer
496 if (result.ret != OPERATION_SUCCESS) {
497 AUDIO_ERR_LOG("ReConfig AudioRingCache to size %{public}u failed:ret%{public}zu", result.ret, targetSize);
498 return ERR_OPERATION_FAILED;
499 }
500 }
501
502 return SUCCESS;
503 }
504
InitIpcStream()505 int32_t RendererInClientInner::InitIpcStream()
506 {
507 Trace trace("RendererInClientInner::InitIpcStream");
508 AudioProcessConfig config = ConstructConfig();
509 bool resetSilentMode = (gServerProxy_ == nullptr) ? true : false;
510 sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
511 CHECK_AND_RETURN_RET_LOG(gasp != nullptr, ERR_OPERATION_FAILED, "Create failed, can not get service.");
512 int32_t errorCode = 0;
513 sptr<IRemoteObject> ipcProxy = gasp->CreateAudioProcess(config, errorCode);
514 CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, ERR_OPERATION_FAILED, "failed with null ipcProxy.");
515 ipcStream_ = iface_cast<IpcStream>(ipcProxy);
516 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "failed when iface_cast.");
517
518 // in plan next: old listener_ is destoried here, will server receive dieth notify?
519 listener_ = sptr<IpcStreamListenerImpl>::MakeSptr(shared_from_this());
520 int32_t ret = ipcStream_->RegisterStreamListener(listener_->AsObject());
521 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "RegisterStreamListener failed:%{public}d", ret);
522
523 if (resetSilentMode && gServerProxy_ != nullptr && silentModeAndMixWithOthers_) {
524 ipcStream_->SetSilentModeAndMixWithOthers(silentModeAndMixWithOthers_);
525 }
526
527 ret = InitSharedBuffer();
528 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitSharedBuffer failed:%{public}d", ret);
529
530 ret = InitCacheBuffer(clientSpanSizeInByte_);
531 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitCacheBuffer failed:%{public}d", ret);
532
533 ret = ipcStream_->GetAudioSessionID(sessionId_);
534 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "GetAudioSessionID failed:%{public}d", ret);
535 traceTag_ = "[" + std::to_string(sessionId_) + "]RendererInClient"; // [100001]RendererInClient
536 InitCallbackHandler();
537 return SUCCESS;
538 }
539
GetAudioStreamInfo(AudioStreamParams & info)540 int32_t RendererInClientInner::GetAudioStreamInfo(AudioStreamParams &info)
541 {
542 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, ERR_OPERATION_FAILED, "Params is not set");
543 info = streamParams_;
544 return SUCCESS;
545 }
546
CheckRecordingCreate(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,SourceType sourceType)547 bool RendererInClientInner::CheckRecordingCreate(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
548 SourceType sourceType)
549 {
550 AUDIO_WARNING_LOG("CheckRecordingCreate is not supported");
551 return false;
552 }
553
CheckRecordingStateChange(uint32_t appTokenId,uint64_t appFullTokenId,int32_t appUid,AudioPermissionState state)554 bool RendererInClientInner::CheckRecordingStateChange(uint32_t appTokenId, uint64_t appFullTokenId, int32_t appUid,
555 AudioPermissionState state)
556 {
557 AUDIO_WARNING_LOG("CheckRecordingCreate is not supported");
558 return false;
559 }
560
GetAudioSessionID(uint32_t & sessionID)561 int32_t RendererInClientInner::GetAudioSessionID(uint32_t &sessionID)
562 {
563 CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != NEW), ERR_ILLEGAL_STATE,
564 "State error %{public}d", state_.load());
565 sessionID = sessionId_;
566 return SUCCESS;
567 }
568
GetAudioPipeType(AudioPipeType & pipeType)569 void RendererInClientInner::GetAudioPipeType(AudioPipeType &pipeType)
570 {
571 pipeType = rendererInfo_.pipeType;
572 }
573
GetState()574 State RendererInClientInner::GetState()
575 {
576 return state_;
577 }
578
GetAudioTime(Timestamp & timestamp,Timestamp::Timestampbase base)579 bool RendererInClientInner::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base)
580 {
581 CHECK_AND_RETURN_RET_LOG(paramsIsSet_ == true, false, "Params is not set");
582 CHECK_AND_RETURN_RET_LOG(state_ != STOPPED, false, "Invalid status:%{public}d", state_.load());
583
584 uint64_t readPos = 0;
585 int64_t handleTime = 0;
586 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, false, "invalid buffer status");
587 clientBuffer_->GetHandleInfo(readPos, handleTime);
588 if (readPos == 0 || handleTime == 0) {
589 AUDIO_WARNING_LOG("GetHandleInfo may failed");
590 }
591
592 timestamp.framePosition = readPos;
593 int64_t audioTimeResult = handleTime;
594
595 if (offloadEnable_) {
596 uint64_t timestampHdi = 0;
597 uint64_t paWriteIndex = 0;
598 uint64_t cacheTimeDsp = 0;
599 uint64_t cacheTimePa = 0;
600 ipcStream_->GetOffloadApproximatelyCacheTime(timestampHdi, paWriteIndex, cacheTimeDsp, cacheTimePa);
601 int64_t cacheTime = static_cast<int64_t>(cacheTimeDsp + cacheTimePa) * AUDIO_NS_PER_US;
602 int64_t timeNow = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
603 std::chrono::system_clock::now().time_since_epoch()).count());
604 int64_t deltaTimeStamp = (static_cast<int64_t>(timeNow) - static_cast<int64_t>(timestampHdi)) * AUDIO_NS_PER_US;
605 uint64_t paWriteIndexNs = paWriteIndex * AUDIO_NS_PER_US;
606 uint64_t readPosNs = readPos * AUDIO_MS_PER_SECOND / streamParams_.samplingRate * AUDIO_US_PER_S;
607
608 int64_t deltaPaWriteIndexNs = static_cast<int64_t>(readPosNs) - static_cast<int64_t>(paWriteIndexNs);
609 int64_t cacheTimeNow = cacheTime - deltaTimeStamp + deltaPaWriteIndexNs;
610 if (offloadStartReadPos_ == 0) {
611 offloadStartReadPos_ = readPosNs;
612 offloadStartHandleTime_ = handleTime;
613 }
614 int64_t offloadDelta = 0;
615 if (offloadStartReadPos_ != 0) {
616 offloadDelta = (static_cast<int64_t>(readPosNs) - static_cast<int64_t>(offloadStartReadPos_)) -
617 (handleTime - offloadStartHandleTime_) - cacheTimeNow;
618 }
619 audioTimeResult += offloadDelta;
620 }
621
622 timestamp.time.tv_sec = static_cast<time_t>(audioTimeResult / AUDIO_NS_PER_SECOND);
623 timestamp.time.tv_nsec = static_cast<time_t>(audioTimeResult % AUDIO_NS_PER_SECOND);
624 AUDIO_DEBUG_LOG("audioTimeResult: %{public}" PRIi64, audioTimeResult);
625 return true;
626 }
627
GetAudioPosition(Timestamp & timestamp,Timestamp::Timestampbase base)628 bool RendererInClientInner::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base)
629 {
630 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Renderer stream state is not RUNNING");
631 uint64_t readIndex = 0;
632 uint64_t timestampVal = 0;
633 uint64_t latency = 0;
634 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
635 int32_t ret = ipcStream_->GetAudioPosition(readIndex, timestampVal, latency);
636
637 uint64_t framePosition = readIndex > lastFlushReadIndex_ ? readIndex - lastFlushReadIndex_ : 0;
638 framePosition = framePosition > latency ? framePosition - latency : 0;
639
640 // add MCR latency
641 uint32_t mcrLatency = 0;
642 if (converter_ != nullptr) {
643 mcrLatency = converter_->GetLatency();
644 framePosition = framePosition - (mcrLatency * rendererRate_ / AUDIO_MS_PER_S);
645 }
646
647 if (lastFramePosition_ < framePosition) {
648 lastFramePosition_ = framePosition;
649 lastFrameTimestamp_ = timestampVal;
650 } else {
651 AUDIO_DEBUG_LOG("The frame position should be continuously increasing");
652 framePosition = lastFramePosition_;
653 timestampVal = lastFrameTimestamp_;
654 }
655 AUDIO_DEBUG_LOG("[CLIENT]Latency info: framePosition: %{public}" PRIu64 ", lastFlushReadIndex_ %{public}" PRIu64
656 ", timestamp %{public}" PRIu64 ", mcrLatency %{public}u, Sinklatency %{public}" PRIu64, framePosition,
657 lastFlushReadIndex_, timestampVal, mcrLatency, latency);
658
659 timestamp.framePosition = framePosition;
660 timestamp.time.tv_sec = static_cast<time_t>(timestampVal / AUDIO_NS_PER_SECOND);
661 timestamp.time.tv_nsec = static_cast<time_t>(timestampVal % AUDIO_NS_PER_SECOND);
662 return ret == SUCCESS;
663 }
664
GetBufferSize(size_t & bufferSize)665 int32_t RendererInClientInner::GetBufferSize(size_t &bufferSize)
666 {
667 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
668 bufferSize = clientSpanSizeInByte_;
669 if (renderMode_ == RENDER_MODE_CALLBACK) {
670 bufferSize = cbBufferSize_;
671 }
672
673 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
674 CHECK_AND_RETURN_RET(converter_ != nullptr && converter_->GetInputBufferSize(bufferSize), ERR_OPERATION_FAILED);
675 }
676
677 AUDIO_INFO_LOG("Buffer size is %{public}zu, mode is %{public}s", bufferSize, renderMode_ == RENDER_MODE_NORMAL ?
678 "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
679 return SUCCESS;
680 }
681
GetFrameCount(uint32_t & frameCount)682 int32_t RendererInClientInner::GetFrameCount(uint32_t &frameCount)
683 {
684 CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Renderer stream is released");
685 CHECK_AND_RETURN_RET_LOG(sizePerFrameInByte_ != 0, ERR_ILLEGAL_STATE, "sizePerFrameInByte_ is 0!");
686 frameCount = spanSizeInFrame_;
687 if (renderMode_ == RENDER_MODE_CALLBACK) {
688 frameCount = cbBufferSize_ / sizePerFrameInByte_;
689 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
690 frameCount = frameCount * curStreamParams_.channels / streamParams_.channels;
691 }
692 }
693 AUDIO_INFO_LOG("Frame count is %{public}u, mode is %{public}s", frameCount, renderMode_ == RENDER_MODE_NORMAL ?
694 "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
695 return SUCCESS;
696 }
697
GetLatency(uint64_t & latency)698 int32_t RendererInClientInner::GetLatency(uint64_t &latency)
699 {
700 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
701 return ipcStream_->GetLatency(latency);
702 }
703
SetAudioStreamType(AudioStreamType audioStreamType)704 int32_t RendererInClientInner::SetAudioStreamType(AudioStreamType audioStreamType)
705 {
706 AUDIO_ERR_LOG("Change stream type %{public}d to %{public}d is not supported", eStreamType_, audioStreamType);
707 return SUCCESS;
708 }
709
SetInnerVolume(float volume)710 int32_t RendererInClientInner::SetInnerVolume(float volume)
711 {
712 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
713 clientBuffer_->SetStreamVolume(volume);
714 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
715 int32_t ret = ipcStream_->SetClientVolume();
716 if (ret != SUCCESS) {
717 AUDIO_ERR_LOG("Set Client Volume failed:%{public}u", ret);
718 return -1;
719 }
720 AUDIO_PRERELEASE_LOGI("SetClientVolume success, volume: %{public}f", volume);
721 return SUCCESS;
722 }
723
SetVolume(float volume)724 int32_t RendererInClientInner::SetVolume(float volume)
725 {
726 Trace trace("RendererInClientInner::SetVolume:" + std::to_string(volume));
727 AUDIO_INFO_LOG("[%{public}s]sessionId:%{public}d volume:%{public}f", (offloadEnable_ ? "offload" : "normal"),
728 sessionId_, volume);
729 if (volume < 0.0 || volume > 1.0) {
730 AUDIO_ERR_LOG("SetVolume with invalid volume %{public}f", volume);
731 return ERR_INVALID_PARAM;
732 }
733 if (volumeRamp_.IsActive()) {
734 volumeRamp_.Terminate();
735 }
736 clientVolume_ = volume;
737
738 return SetInnerVolume(volume);
739 }
740
GetVolume()741 float RendererInClientInner::GetVolume()
742 {
743 Trace trace("RendererInClientInner::GetVolume:" + std::to_string(clientVolume_));
744 return clientVolume_;
745 }
746
SetDuckVolume(float volume)747 int32_t RendererInClientInner::SetDuckVolume(float volume)
748 {
749 Trace trace("RendererInClientInner::SetDuckVolume:" + std::to_string(volume));
750 AUDIO_INFO_LOG("sessionId:%{public}d SetDuck:%{public}f", sessionId_, volume);
751 if (volume < 0.0 || volume > 1.0) {
752 AUDIO_ERR_LOG("SetDuckVolume with invalid volume %{public}f", volume);
753 return ERR_INVALID_PARAM;
754 }
755 duckVolume_ = volume;
756 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
757 clientBuffer_->SetDuckFactor(volume);
758 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "ipcStream is not inited!");
759 int32_t ret = ipcStream_->SetDuckFactor(volume);
760 if (ret != SUCCESS) {
761 AUDIO_ERR_LOG("Set Duck failed:%{public}u", ret);
762 return ERROR;
763 }
764 return SUCCESS;
765 }
766
SetRenderRate(AudioRendererRate renderRate)767 int32_t RendererInClientInner::SetRenderRate(AudioRendererRate renderRate)
768 {
769 if (rendererRate_ == renderRate) {
770 AUDIO_INFO_LOG("Set same rate");
771 return SUCCESS;
772 }
773 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
774 rendererRate_ = renderRate;
775 return ipcStream_->SetRate(renderRate);
776 }
777
SetSpeed(float speed)778 int32_t RendererInClientInner::SetSpeed(float speed)
779 {
780 if (audioSpeed_ == nullptr) {
781 audioSpeed_ = std::make_unique<AudioSpeed>(curStreamParams_.samplingRate, curStreamParams_.format,
782 curStreamParams_.channels);
783 GetBufferSize(bufferSize_);
784 speedBuffer_ = std::make_unique<uint8_t[]>(MAX_BUFFER_SIZE);
785 }
786 audioSpeed_->SetSpeed(speed);
787 speed_ = speed;
788 AUDIO_DEBUG_LOG("SetSpeed %{public}f, OffloadEnable %{public}d", speed_, offloadEnable_);
789 return SUCCESS;
790 }
791
GetSpeed()792 float RendererInClientInner::GetSpeed()
793 {
794 return speed_;
795 }
796
ChangeSpeed(uint8_t * buffer,int32_t bufferSize,std::unique_ptr<uint8_t[]> & outBuffer,int32_t & outBufferSize)797 int32_t RendererInClientInner::ChangeSpeed(uint8_t *buffer, int32_t bufferSize, std::unique_ptr<uint8_t []> &outBuffer,
798 int32_t &outBufferSize)
799 {
800 return audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, outBuffer, outBufferSize);
801 }
802
GetRenderRate()803 AudioRendererRate RendererInClientInner::GetRenderRate()
804 {
805 AUDIO_INFO_LOG("Get RenderRate %{public}d", rendererRate_);
806 return rendererRate_;
807 }
808
SetStreamCallback(const std::shared_ptr<AudioStreamCallback> & callback)809 int32_t RendererInClientInner::SetStreamCallback(const std::shared_ptr<AudioStreamCallback> &callback)
810 {
811 if (callback == nullptr) {
812 AUDIO_ERR_LOG("SetStreamCallback failed. callback == nullptr");
813 return ERR_INVALID_PARAM;
814 }
815
816 std::unique_lock<std::mutex> lock(streamCbMutex_);
817 streamCallback_ = callback;
818 lock.unlock();
819
820 if (state_ != PREPARED) {
821 return SUCCESS;
822 }
823 SafeSendCallbackEvent(STATE_CHANGE_EVENT, PREPARED);
824 return SUCCESS;
825 }
826
SetRendererFirstFrameWritingCallback(const std::shared_ptr<AudioRendererFirstFrameWritingCallback> & callback)827 int32_t RendererInClientInner::SetRendererFirstFrameWritingCallback(
828 const std::shared_ptr<AudioRendererFirstFrameWritingCallback> &callback)
829 {
830 AUDIO_INFO_LOG("SetRendererFirstFrameWritingCallback in.");
831 CHECK_AND_RETURN_RET_LOG(callback, ERR_INVALID_PARAM, "callback is nullptr");
832 firstFrameWritingCb_ = callback;
833 return SUCCESS;
834 }
835
OnFirstFrameWriting()836 void RendererInClientInner::OnFirstFrameWriting()
837 {
838 hasFirstFrameWrited_ = true;
839 CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null.");
840 uint64_t latency = AUDIO_FIRST_FRAME_LATENCY;
841 AUDIO_DEBUG_LOG("OnFirstFrameWriting: latency %{public}" PRIu64 "", latency);
842 firstFrameWritingCb_->OnFirstFrameWriting(latency);
843 }
844
InitCallbackBuffer(uint64_t bufferDurationInUs)845 void RendererInClientInner::InitCallbackBuffer(uint64_t bufferDurationInUs)
846 {
847 if (bufferDurationInUs > MAX_BUF_DURATION_IN_USEC) {
848 AUDIO_ERR_LOG("InitCallbackBuffer with invalid duration %{public}" PRIu64", use default instead.",
849 bufferDurationInUs);
850 bufferDurationInUs = OLD_BUF_DURATION_IN_USEC;
851 }
852 // Calculate buffer size based on duration.
853
854 size_t metaSize = 0;
855 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
856 CHECK_AND_RETURN_LOG(converter_ != nullptr, "converter is not inited");
857 metaSize = converter_->GetMetaSize();
858 converter_->GetInputBufferSize(cbBufferSize_);
859 } else {
860 cbBufferSize_ = static_cast<size_t>(bufferDurationInUs * curStreamParams_.samplingRate / AUDIO_US_PER_S) *
861 sizePerFrameInByte_;
862 }
863 AUDIO_INFO_LOG("duration %{public}" PRIu64 ", ecodingType: %{public}d, size: %{public}zu, metaSize: %{public}zu",
864 bufferDurationInUs, curStreamParams_.encoding, cbBufferSize_, metaSize);
865 std::lock_guard<std::mutex> lock(cbBufferMutex_);
866 cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_ + metaSize);
867 }
868
SetRenderMode(AudioRenderMode renderMode)869 int32_t RendererInClientInner::SetRenderMode(AudioRenderMode renderMode)
870 {
871 AUDIO_INFO_LOG("SetRenderMode to %{public}s", renderMode == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
872 "RENDER_MODE_CALLBACK");
873 if (renderMode_ == renderMode) {
874 return SUCCESS;
875 }
876
877 // renderMode_ is inited as RENDER_MODE_NORMAL, can only be set to RENDER_MODE_CALLBACK.
878 if (renderMode_ == RENDER_MODE_CALLBACK && renderMode == RENDER_MODE_NORMAL) {
879 AUDIO_ERR_LOG("SetRenderMode from callback to normal is not supported.");
880 return ERR_INCORRECT_MODE;
881 }
882
883 // state check
884 if (state_ != PREPARED && state_ != NEW) {
885 AUDIO_ERR_LOG("SetRenderMode failed. invalid state:%{public}d", state_.load());
886 return ERR_ILLEGAL_STATE;
887 }
888 renderMode_ = renderMode;
889
890 // init callbackLoop_
891 callbackLoop_ = std::thread([this] { this->WriteCallbackFunc(); });
892 pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioWriteCB");
893
894 std::unique_lock<std::mutex> threadStartlock(statusMutex_);
895 bool stopWaiting = cbThreadCv_.wait_for(threadStartlock, std::chrono::milliseconds(SHORT_TIMEOUT_IN_MS), [this] {
896 return cbThreadReleased_ == false; // When thread is started, cbThreadReleased_ will be false. So stop waiting.
897 });
898 if (!stopWaiting) {
899 AUDIO_WARNING_LOG("Init OS_AudioWriteCB thread time out");
900 }
901
902 InitCallbackBuffer(OLD_BUF_DURATION_IN_USEC);
903 return SUCCESS;
904 }
905
GetRenderMode()906 AudioRenderMode RendererInClientInner::GetRenderMode()
907 {
908 AUDIO_INFO_LOG("Render mode is %{public}s", renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" :
909 "RENDER_MODE_CALLBACK");
910 return renderMode_;
911 }
912
SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> & callback)913 int32_t RendererInClientInner::SetRendererWriteCallback(const std::shared_ptr<AudioRendererWriteCallback> &callback)
914 {
915 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "Invalid null callback");
916 CHECK_AND_RETURN_RET_LOG(renderMode_ == RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE, "incorrect render mode");
917 std::lock_guard<std::mutex> lock(writeCbMutex_);
918 writeCb_ = callback;
919 return SUCCESS;
920 }
921
922 // Sleep or wait in WaitForRunning to avoid dead looping.
WaitForRunning()923 bool RendererInClientInner::WaitForRunning()
924 {
925 Trace trace("RendererInClientInner::WaitForRunning");
926 // check renderer state_: call client write only in running else wait on statusMutex_
927 std::unique_lock<std::mutex> stateLock(statusMutex_);
928 if (state_ != RUNNING) {
929 bool stopWaiting = cbThreadCv_.wait_for(stateLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
930 return state_ == RUNNING || cbThreadReleased_;
931 });
932 if (cbThreadReleased_) {
933 AUDIO_INFO_LOG("CBThread end in non-running status, sessionID :%{public}d", sessionId_);
934 return false;
935 }
936 if (!stopWaiting) {
937 AUDIO_DEBUG_LOG("Wait timeout, current state_ is %{public}d", state_.load()); // wait 0.5s
938 return false;
939 }
940 }
941 return true;
942 }
943
ProcessWriteInner(BufferDesc & bufferDesc)944 int32_t RendererInClientInner::ProcessWriteInner(BufferDesc &bufferDesc)
945 {
946 int32_t result = 0; // Ensure result with default value.
947 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
948 result = WriteInner(bufferDesc.buffer, bufferDesc.bufLength, bufferDesc.metaBuffer, bufferDesc.metaLength);
949 }
950 if (curStreamParams_.encoding == ENCODING_PCM) {
951 if (bufferDesc.dataLength != 0) {
952 result = WriteInner(bufferDesc.buffer, bufferDesc.bufLength);
953 sleepCount_ = LOG_COUNT_LIMIT;
954 } else {
955 if (sleepCount_++ == LOG_COUNT_LIMIT) {
956 sleepCount_ = 0;
957 AUDIO_WARNING_LOG("OnWriteData Process 1st or 500 times INVALID buffer");
958 }
959 usleep(WAIT_FOR_NEXT_CB);
960 }
961 }
962 if (result < 0) {
963 AUDIO_WARNING_LOG("Call write fail, result:%{public}d, bufLength:%{public}zu", result, bufferDesc.bufLength);
964 }
965 return result;
966 }
967
WriteCallbackFunc()968 void RendererInClientInner::WriteCallbackFunc()
969 {
970 AUDIO_INFO_LOG("WriteCallbackFunc start, sessionID :%{public}d", sessionId_);
971 cbThreadReleased_ = false;
972
973 // Modify thread priority is not need as first call write will do these work.
974 cbThreadCv_.notify_one();
975
976 // start loop
977 while (!cbThreadReleased_) {
978 Trace traceLoop("RendererInClientInner::WriteCallbackFunc");
979 if (!WaitForRunning()) {
980 continue;
981 }
982 if (cbBufferQueue_.Size() > 1) { // One callback, one enqueue, queue size should always be 1.
983 AUDIO_WARNING_LOG("The queue is too long, reducing data through loops");
984 }
985 BufferDesc temp;
986 while (cbBufferQueue_.PopNotWait(temp)) {
987 Trace traceQueuePop("RendererInClientInner::QueueWaitPop");
988 if (state_ != RUNNING) {
989 cbBufferQueue_.Push(temp);
990 AUDIO_INFO_LOG("Repush left buffer in queue");
991 break;
992 }
993 traceQueuePop.End();
994 // call write here.
995 int32_t result = ProcessWriteInner(temp);
996 // only run in pause scene
997 if (result > 0 && static_cast<size_t>(result) < temp.dataLength) {
998 BufferDesc tmp = {temp.buffer + static_cast<size_t>(result),
999 temp.bufLength - static_cast<size_t>(result), temp.dataLength - static_cast<size_t>(result)};
1000 cbBufferQueue_.Push(tmp);
1001 AUDIO_INFO_LOG("Repush %{public}zu bytes in queue", temp.dataLength - static_cast<size_t>(result));
1002 break;
1003 }
1004 }
1005 if (state_ != RUNNING) { continue; }
1006 // call client write
1007 std::unique_lock<std::mutex> lockCb(writeCbMutex_);
1008 if (writeCb_ != nullptr) {
1009 Trace traceCb("RendererInClientInner::OnWriteData");
1010 writeCb_->OnWriteData(cbBufferSize_);
1011 }
1012 lockCb.unlock();
1013
1014 Trace traceQueuePush("RendererInClientInner::QueueWaitPush");
1015 std::unique_lock<std::mutex> lockBuffer(cbBufferMutex_);
1016 cbBufferQueue_.WaitNotEmptyFor(std::chrono::milliseconds(WRITE_BUFFER_TIMEOUT_IN_MS));
1017 }
1018 AUDIO_INFO_LOG("CBThread end sessionID :%{public}d", sessionId_);
1019 }
1020
SetCaptureMode(AudioCaptureMode captureMode)1021 int32_t RendererInClientInner::SetCaptureMode(AudioCaptureMode captureMode)
1022 {
1023 AUDIO_ERR_LOG("SetCaptureMode is not supported");
1024 return ERROR;
1025 }
1026
GetCaptureMode()1027 AudioCaptureMode RendererInClientInner::GetCaptureMode()
1028 {
1029 AUDIO_ERR_LOG("GetCaptureMode is not supported");
1030 return CAPTURE_MODE_NORMAL; // not supported
1031 }
1032
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> & callback)1033 int32_t RendererInClientInner::SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallback> &callback)
1034 {
1035 AUDIO_ERR_LOG("SetCapturerReadCallback is not supported");
1036 return ERROR;
1037 }
1038
GetBufferDesc(BufferDesc & bufDesc)1039 int32_t RendererInClientInner::GetBufferDesc(BufferDesc &bufDesc)
1040 {
1041 Trace trace("RendererInClientInner::GetBufferDesc");
1042 if (renderMode_ != RENDER_MODE_CALLBACK) {
1043 AUDIO_ERR_LOG("GetBufferDesc is not supported. Render mode is not callback.");
1044 return ERR_INCORRECT_MODE;
1045 }
1046 std::lock_guard<std::mutex> lock(cbBufferMutex_);
1047 bufDesc.buffer = cbBuffer_.get();
1048 bufDesc.bufLength = cbBufferSize_;
1049 bufDesc.dataLength = cbBufferSize_;
1050 if (curStreamParams_.encoding == ENCODING_AUDIOVIVID) {
1051 CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_INVALID_OPERATION, "converter is not inited");
1052 bufDesc.metaBuffer = bufDesc.buffer + cbBufferSize_;
1053 bufDesc.metaLength = converter_->GetMetaSize();
1054 }
1055 return SUCCESS;
1056 }
1057
GetBufQueueState(BufferQueueState & bufState)1058 int32_t RendererInClientInner::GetBufQueueState(BufferQueueState &bufState)
1059 {
1060 Trace trace("RendererInClientInner::GetBufQueueState");
1061 if (renderMode_ != RENDER_MODE_CALLBACK) {
1062 AUDIO_ERR_LOG("GetBufQueueState is not supported. Render mode is not callback.");
1063 return ERR_INCORRECT_MODE;
1064 }
1065 // only one buffer in queue.
1066 bufState.numBuffers = 1;
1067 bufState.currentIndex = 0;
1068 return SUCCESS;
1069 }
1070
Enqueue(const BufferDesc & bufDesc)1071 int32_t RendererInClientInner::Enqueue(const BufferDesc &bufDesc)
1072 {
1073 Trace trace("RendererInClientInner::Enqueue " + std::to_string(bufDesc.bufLength));
1074 if (renderMode_ != RENDER_MODE_CALLBACK) {
1075 AUDIO_ERR_LOG("Enqueue is not supported. Render mode is not callback.");
1076 return ERR_INCORRECT_MODE;
1077 }
1078 CHECK_AND_RETURN_RET_LOG(bufDesc.buffer != nullptr && bufDesc.bufLength != 0, ERR_INVALID_PARAM, "Invalid buffer");
1079 CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID ||
1080 converter_ != nullptr && converter_->CheckInputValid(bufDesc),
1081 ERR_INVALID_PARAM, "Invalid buffer desc");
1082 if (bufDesc.bufLength > cbBufferSize_ || bufDesc.dataLength > cbBufferSize_) {
1083 AUDIO_WARNING_LOG("Invalid bufLength:%{public}zu or dataLength:%{public}zu, should be %{public}zu",
1084 bufDesc.bufLength, bufDesc.dataLength, cbBufferSize_);
1085 }
1086
1087 BufferDesc temp = bufDesc;
1088
1089 if (state_ == RELEASED) {
1090 AUDIO_WARNING_LOG("Invalid state: %{public}d", state_.load());
1091 return ERR_ILLEGAL_STATE;
1092 }
1093 // Call write here may block, so put it in loop callbackLoop_
1094 cbBufferQueue_.Push(temp);
1095 return SUCCESS;
1096 }
1097
Clear()1098 int32_t RendererInClientInner::Clear()
1099 {
1100 Trace trace("RendererInClientInner::Clear");
1101 if (renderMode_ != RENDER_MODE_CALLBACK) {
1102 AUDIO_ERR_LOG("Clear is not supported. Render mode is not callback.");
1103 return ERR_INCORRECT_MODE;
1104 }
1105 std::unique_lock<std::mutex> lock(cbBufferMutex_);
1106 int32_t ret = memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_);
1107 CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "Clear buffer fail, ret %{public}d.", ret);
1108 lock.unlock();
1109 FlushAudioStream();
1110 return SUCCESS;
1111 }
1112
SetLowPowerVolume(float volume)1113 int32_t RendererInClientInner::SetLowPowerVolume(float volume)
1114 {
1115 AUDIO_INFO_LOG("Volume number: %{public}f", volume);
1116 if (volume < 0.0 || volume > 1.0) {
1117 AUDIO_ERR_LOG("Invalid param: %{public}f", volume);
1118 return ERR_INVALID_PARAM;
1119 }
1120 lowPowerVolume_ = volume;
1121
1122 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1123 return ipcStream_->SetLowPowerVolume(lowPowerVolume_);
1124 }
1125
GetLowPowerVolume()1126 float RendererInClientInner::GetLowPowerVolume()
1127 {
1128 return lowPowerVolume_;
1129 }
1130
SetOffloadMode(int32_t state,bool isAppBack)1131 int32_t RendererInClientInner::SetOffloadMode(int32_t state, bool isAppBack)
1132 {
1133 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1134 return ipcStream_->SetOffloadMode(state, isAppBack);
1135 }
1136
UnsetOffloadMode()1137 int32_t RendererInClientInner::UnsetOffloadMode()
1138 {
1139 rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
1140 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is null!");
1141 return ipcStream_->UnsetOffloadMode();
1142 }
1143
GetSingleStreamVolume()1144 float RendererInClientInner::GetSingleStreamVolume()
1145 {
1146 // in plan. For now, keep it consistent with fast_audio_stream
1147 return 1.0f;
1148 }
1149
GetAudioEffectMode()1150 AudioEffectMode RendererInClientInner::GetAudioEffectMode()
1151 {
1152 AUDIO_DEBUG_LOG("Current audio effect mode is %{public}d", effectMode_);
1153 return effectMode_;
1154 }
1155
SetAudioEffectMode(AudioEffectMode effectMode)1156 int32_t RendererInClientInner::SetAudioEffectMode(AudioEffectMode effectMode)
1157 {
1158 if (effectMode_ == effectMode) {
1159 AUDIO_INFO_LOG("Set same effect mode");
1160 return SUCCESS;
1161 }
1162 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is not inited!");
1163 int32_t ret = ipcStream_->SetAudioEffectMode(effectMode);
1164 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Set audio effect mode failed");
1165 effectMode_ = effectMode;
1166 return SUCCESS;
1167 }
1168
GetFramesWritten()1169 int64_t RendererInClientInner::GetFramesWritten()
1170 {
1171 return totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1172 }
1173
GetFramesRead()1174 int64_t RendererInClientInner::GetFramesRead()
1175 {
1176 AUDIO_ERR_LOG("not supported");
1177 return -1;
1178 }
1179
1180
SetInnerCapturerState(bool isInnerCapturer)1181 void RendererInClientInner::SetInnerCapturerState(bool isInnerCapturer)
1182 {
1183 AUDIO_ERR_LOG("SetInnerCapturerState is not supported");
1184 return;
1185 }
1186
SetWakeupCapturerState(bool isWakeupCapturer)1187 void RendererInClientInner::SetWakeupCapturerState(bool isWakeupCapturer)
1188 {
1189 AUDIO_ERR_LOG("SetWakeupCapturerState is not supported");
1190 return;
1191 }
1192
SetCapturerSource(int capturerSource)1193 void RendererInClientInner::SetCapturerSource(int capturerSource)
1194 {
1195 AUDIO_ERR_LOG("SetCapturerSource is not supported");
1196 return;
1197 }
1198
SetPrivacyType(AudioPrivacyType privacyType)1199 void RendererInClientInner::SetPrivacyType(AudioPrivacyType privacyType)
1200 {
1201 if (privacyType_ == privacyType) {
1202 AUDIO_INFO_LOG("Set same privacy type");
1203 return;
1204 }
1205 privacyType_ = privacyType;
1206 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
1207 int32_t ret = ipcStream_->SetPrivacyType(privacyType);
1208 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Set privacy type failed");
1209 }
1210
StartAudioStream(StateChangeCmdType cmdType,AudioStreamDeviceChangeReasonExt reason)1211 bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType,
1212 AudioStreamDeviceChangeReasonExt reason)
1213 {
1214 Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_));
1215 std::unique_lock<std::mutex> statusLock(statusMutex_);
1216 if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) {
1217 AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load());
1218 return false;
1219 }
1220
1221 hasFirstFrameWrited_ = false;
1222 if (audioStreamTracker_ && audioStreamTracker_.get()) {
1223 audioStreamTracker_->FetchOutputDeviceForTrack(sessionId_, RUNNING, clientPid_, rendererInfo_, reason);
1224 }
1225 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1226 int32_t ret = ipcStream_->Start();
1227 if (ret != SUCCESS) {
1228 AUDIO_ERR_LOG("Start call server failed:%{public}u", ret);
1229 return false;
1230 }
1231 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1232 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1233 return state_ == RUNNING; // will be false when got notified.
1234 });
1235 if (!stopWaiting) {
1236 AUDIO_ERR_LOG("Start failed: timeout");
1237 ipcStream_->Stop();
1238 return false;
1239 }
1240
1241 waitLock.unlock();
1242
1243 AUDIO_INFO_LOG("Start SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1244 UpdateTracker("RUNNING");
1245
1246 std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
1247 if (!isDataLinkConnected_) {
1248 AUDIO_INFO_LOG("data-connection blocking starts.");
1249 stopWaiting = dataConnectionCV_.wait_for(
1250 dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
1251 return isDataLinkConnected_;
1252 });
1253 AUDIO_INFO_LOG("data-connection blocking ends.");
1254 }
1255 dataConnectionWaitLock.unlock();
1256
1257 offloadStartReadPos_ = 0;
1258 if (renderMode_ == RENDER_MODE_CALLBACK) {
1259 // start the callback-write thread
1260 cbThreadCv_.notify_all();
1261 }
1262 statusLock.unlock();
1263 // in plan: call HiSysEventWrite
1264 int64_t param = -1;
1265 StateCmdTypeToParams(param, state_, cmdType);
1266 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1267 preWriteEndTime_ = 0;
1268 return true;
1269 }
1270
PauseAudioStream(StateChangeCmdType cmdType)1271 bool RendererInClientInner::PauseAudioStream(StateChangeCmdType cmdType)
1272 {
1273 Trace trace("RendererInClientInner::PauseAudioStream " + std::to_string(sessionId_));
1274 std::unique_lock<std::mutex> statusLock(statusMutex_);
1275 if (state_ != RUNNING) {
1276 AUDIO_ERR_LOG("State is not RUNNING. Illegal state:%{public}u", state_.load());
1277 return false;
1278 }
1279
1280 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1281 int32_t ret = ipcStream_->Pause();
1282 if (ret != SUCCESS) {
1283 AUDIO_ERR_LOG("call server failed:%{public}u", ret);
1284 return false;
1285 }
1286 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1287 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1288 return state_ == PAUSED; // will be false when got notified.
1289 });
1290 if (!stopWaiting) {
1291 AUDIO_ERR_LOG("Pause failed: timeout");
1292 return false;
1293 }
1294
1295 waitLock.unlock();
1296
1297 FutexTool::FutexWake(clientBuffer_->GetFutex());
1298 statusLock.unlock();
1299
1300 // in plan: call HiSysEventWrite
1301 int64_t param = -1;
1302 StateCmdTypeToParams(param, state_, cmdType);
1303 SafeSendCallbackEvent(STATE_CHANGE_EVENT, param);
1304
1305 AUDIO_INFO_LOG("Pause SUCCESS, sessionId %{public}d, uid %{public}d, mode %{public}s", sessionId_,
1306 clientUid_, renderMode_ == RENDER_MODE_NORMAL ? "RENDER_MODE_NORMAL" : "RENDER_MODE_CALLBACK");
1307 UpdateTracker("PAUSED");
1308 return true;
1309 }
1310
StopAudioStream()1311 bool RendererInClientInner::StopAudioStream()
1312 {
1313 Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_));
1314 AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1315 std::unique_lock<std::mutex> statusLock(statusMutex_);
1316 std::lock_guard<std::mutex> lock(writeMutex_);
1317 if (!offloadEnable_) {
1318 DrainAudioStreamInner(true);
1319 }
1320
1321 if (state_ == STOPPED) {
1322 AUDIO_INFO_LOG("Renderer in client is already stopped");
1323 return true;
1324 }
1325 if ((state_ != RUNNING) && (state_ != PAUSED)) {
1326 AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load());
1327 return false;
1328 }
1329
1330 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1331 if (renderMode_ == RENDER_MODE_CALLBACK) {
1332 state_ = STOPPING;
1333 AUDIO_INFO_LOG("Stop begin in callback mode sessionId %{public}d uid: %{public}d", sessionId_, clientUid_);
1334 }
1335
1336 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1337 int32_t ret = ipcStream_->Stop();
1338 if (ret != SUCCESS) {
1339 AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret);
1340 return false;
1341 }
1342
1343 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1344 return state_ == STOPPED; // will be false when got notified.
1345 });
1346 if (!stopWaiting) {
1347 AUDIO_ERR_LOG("Stop failed: timeout");
1348 state_ = INVALID;
1349 return false;
1350 }
1351
1352 waitLock.unlock();
1353
1354 FutexTool::FutexWake(clientBuffer_->GetFutex());
1355 statusLock.unlock();
1356
1357 // in plan: call HiSysEventWrite
1358 SafeSendCallbackEvent(STATE_CHANGE_EVENT, state_);
1359
1360 AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1361 UpdateTracker("STOPPED");
1362 return true;
1363 }
1364
ReleaseAudioStream(bool releaseRunner,bool isSwitchStream)1365 bool RendererInClientInner::ReleaseAudioStream(bool releaseRunner, bool isSwitchStream)
1366 {
1367 (void)isSwitchStream;
1368 AUDIO_PRERELEASE_LOGI("Enter");
1369 std::unique_lock<std::mutex> statusLock(statusMutex_);
1370 if (state_ == RELEASED) {
1371 AUDIO_WARNING_LOG("Already released, do nothing");
1372 return true;
1373 }
1374 state_ = RELEASED;
1375 statusLock.unlock();
1376
1377 Trace trace("RendererInClientInner::ReleaseAudioStream " + std::to_string(sessionId_));
1378 if (ipcStream_ != nullptr) {
1379 ipcStream_->Release();
1380 } else {
1381 AUDIO_WARNING_LOG("release while ipcStream is null");
1382 }
1383
1384 // no lock, call release in any case, include blocked case.
1385 std::unique_lock<std::mutex> runnerlock(runnerMutex_);
1386 if (releaseRunner && callbackHandler_ != nullptr) {
1387 callbackHandler_->ReleaseEventRunner();
1388 runnerReleased_ = true;
1389 callbackHandler_ = nullptr;
1390 }
1391 runnerlock.unlock();
1392
1393 // clear write callback
1394 if (renderMode_ == RENDER_MODE_CALLBACK) {
1395 cbThreadReleased_ = true; // stop loop
1396 cbThreadCv_.notify_all();
1397 FutexTool::FutexWake(clientBuffer_->GetFutex(), IS_PRE_EXIT);
1398 if (callbackLoop_.joinable()) {
1399 callbackLoop_.join();
1400 }
1401 }
1402 paramsIsSet_ = false;
1403
1404 std::unique_lock<std::mutex> lock(streamCbMutex_);
1405 std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
1406 if (streamCb != nullptr) {
1407 AUDIO_INFO_LOG("Notify client the state is released");
1408 streamCb->OnStateChange(RELEASED, CMD_FROM_CLIENT);
1409 }
1410 lock.unlock();
1411
1412 UpdateTracker("RELEASED");
1413 AUDIO_INFO_LOG("Release end, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_);
1414
1415 audioSpeed_.reset();
1416 audioSpeed_ = nullptr;
1417 return true;
1418 }
1419
FlushAudioStream()1420 bool RendererInClientInner::FlushAudioStream()
1421 {
1422 Trace trace("RendererInClientInner::FlushAudioStream " + std::to_string(sessionId_));
1423 std::unique_lock<std::mutex> statusLock(statusMutex_);
1424 std::lock_guard<std::mutex>lock(writeMutex_);
1425 if ((state_ != RUNNING) && (state_ != PAUSED) && (state_ != STOPPED)) {
1426 AUDIO_ERR_LOG("Flush failed. Illegal state:%{public}u", state_.load());
1427 return false;
1428 }
1429
1430 // clear cbBufferQueue
1431 if (renderMode_ == RENDER_MODE_CALLBACK) {
1432 cbBufferQueue_.Clear();
1433 if (memset_s(cbBuffer_.get(), cbBufferSize_, 0, cbBufferSize_) != EOK) {
1434 AUDIO_ERR_LOG("memset_s buffer failed");
1435 };
1436 }
1437
1438 CHECK_AND_RETURN_RET_LOG(FlushRingCache() == SUCCESS, false, "Flush cache failed");
1439
1440 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
1441 int32_t ret = ipcStream_->Flush();
1442 if (ret != SUCCESS) {
1443 AUDIO_ERR_LOG("Flush call server failed:%{public}u", ret);
1444 return false;
1445 }
1446 std::unique_lock<std::mutex> waitLock(callServerMutex_);
1447 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
1448 return notifiedOperation_ == FLUSH_STREAM; // will be false when got notified.
1449 });
1450
1451 if (notifiedOperation_ != FLUSH_STREAM || notifiedResult_ != SUCCESS) {
1452 AUDIO_ERR_LOG("Flush failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
1453 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
1454 notifiedOperation_ = MAX_OPERATION_CODE;
1455 return false;
1456 }
1457 notifiedOperation_ = MAX_OPERATION_CODE;
1458 waitLock.unlock();
1459 ResetFramePosition();
1460 AUDIO_INFO_LOG("Flush stream SUCCESS, sessionId: %{public}d", sessionId_);
1461 return true;
1462 }
1463
FlushRingCache()1464 int32_t RendererInClientInner::FlushRingCache()
1465 {
1466 ringCache_->ResetBuffer();
1467 return SUCCESS;
1468 }
1469
DrainRingCache()1470 int32_t RendererInClientInner::DrainRingCache()
1471 {
1472 // send all data in ringCache_ to server even if GetReadableSize() < clientSpanSizeInByte_.
1473 Trace trace("RendererInClientInner::DrainRingCache " + std::to_string(sessionId_));
1474
1475 OptResult result = ringCache_->GetReadableSize();
1476 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_OPERATION_FAILED, "ring cache unreadable");
1477 size_t readableSize = result.size;
1478 if (readableSize == 0) {
1479 AUDIO_WARNING_LOG("Readable size is already zero");
1480 return SUCCESS;
1481 }
1482
1483 BufferDesc desc = {};
1484 uint64_t curWriteIndex = clientBuffer_->GetCurWriteFrame();
1485 int32_t ret = clientBuffer_->GetWriteBuffer(curWriteIndex, desc);
1486 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "GetWriteBuffer failed %{public}d", ret);
1487
1488 // if readableSize < clientSpanSizeInByte_, server will recv a data with some empty data.
1489 // it looks like this: |*******_____|
1490 size_t minSize = std::min(readableSize, clientSpanSizeInByte_);
1491 result = ringCache_->Dequeue({desc.buffer, minSize});
1492 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "ringCache Dequeue failed %{public}d", result.ret);
1493 clientBuffer_->SetCurWriteFrame(curWriteIndex + spanSizeInFrame_);
1494 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_ILLEGAL_STATE, "ipcStream is nullptr");
1495 ipcStream_->UpdatePosition(); // notiify server update position
1496 HandleRendererPositionChanges(minSize);
1497 return SUCCESS;
1498 }
1499
DrainAudioStream(bool stopFlag)1500 bool RendererInClientInner::DrainAudioStream(bool stopFlag)
1501 {
1502 std::lock_guard<std::mutex> statusLock(statusMutex_);
1503 std::lock_guard<std::mutex> lock(writeMutex_);
1504 bool ret = DrainAudioStreamInner(stopFlag);
1505 return ret;
1506 }
1507
SetPreferredFrameSize(int32_t frameSize)1508 void RendererInClientInner::SetPreferredFrameSize(int32_t frameSize)
1509 {
1510 std::lock_guard<std::mutex> lockSetPreferredFrameSize(setPreferredFrameSizeMutex_);
1511 userSettedPreferredFrameSize_ = frameSize;
1512 CHECK_AND_RETURN_LOG(curStreamParams_.encoding != ENCODING_AUDIOVIVID,
1513 "playing audiovivid, frameSize is always 1024.");
1514 size_t maxCbBufferSize =
1515 static_cast<size_t>(MAX_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1516 size_t minCbBufferSize =
1517 static_cast<size_t>(MIN_CBBUF_IN_USEC * curStreamParams_.samplingRate / AUDIO_US_PER_S) * sizePerFrameInByte_;
1518 size_t preferredCbBufferSize = static_cast<size_t>(frameSize) * sizePerFrameInByte_;
1519 std::lock_guard<std::mutex> lock(cbBufferMutex_);
1520 cbBufferSize_ = (preferredCbBufferSize > maxCbBufferSize || preferredCbBufferSize < minCbBufferSize) ?
1521 (preferredCbBufferSize > maxCbBufferSize ? maxCbBufferSize : minCbBufferSize) : preferredCbBufferSize;
1522 AUDIO_INFO_LOG("Set CallbackBuffer with byte size: %{public}zu", cbBufferSize_);
1523 cbBuffer_ = std::make_unique<uint8_t[]>(cbBufferSize_);
1524 return;
1525 }
1526
Write(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1527 int32_t RendererInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1528 size_t metaBufferSize)
1529 {
1530 CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1531 "Write with callback is not supported");
1532 int32_t ret = WriteInner(pcmBuffer, pcmBufferSize, metaBuffer, metaBufferSize);
1533 return ret <= 0 ? ret : static_cast<int32_t>(pcmBufferSize);
1534 }
1535
Write(uint8_t * buffer,size_t bufferSize)1536 int32_t RendererInClientInner::Write(uint8_t *buffer, size_t bufferSize)
1537 {
1538 CHECK_AND_RETURN_RET_LOG(renderMode_ != RENDER_MODE_CALLBACK, ERR_INCORRECT_MODE,
1539 "Write with callback is not supported");
1540 return WriteInner(buffer, bufferSize);
1541 }
1542
ProcessSpeed(uint8_t * & buffer,size_t & bufferSize,bool & speedCached)1543 bool RendererInClientInner::ProcessSpeed(uint8_t *&buffer, size_t &bufferSize, bool &speedCached)
1544 {
1545 speedCached = false;
1546 #ifdef SONIC_ENABLE
1547 if (!isEqual(speed_, 1.0f)) {
1548 Trace trace(traceTag_ + " ProcessSpeed");
1549 if (audioSpeed_ == nullptr) {
1550 AUDIO_ERR_LOG("audioSpeed_ is nullptr, use speed default 1.0");
1551 return true;
1552 }
1553 int32_t outBufferSize = 0;
1554 if (audioSpeed_->ChangeSpeedFunc(buffer, bufferSize, speedBuffer_, outBufferSize) == 0) {
1555 bufferSize = 0;
1556 AUDIO_ERR_LOG("process speed error");
1557 return false;
1558 }
1559 if (outBufferSize == 0) {
1560 AUDIO_DEBUG_LOG("speed buffer is not full");
1561 return false;
1562 }
1563 buffer = speedBuffer_.get();
1564 bufferSize = static_cast<size_t>(outBufferSize);
1565 speedCached = true;
1566 }
1567 #endif
1568 return true;
1569 }
1570
DfxWriteInterval()1571 void RendererInClientInner::DfxWriteInterval()
1572 {
1573 if (preWriteEndTime_ != 0 &&
1574 ((ClockTime::GetCurNano() / AUDIO_US_PER_SECOND) - preWriteEndTime_) > MAX_WRITE_INTERVAL_MS) {
1575 AUDIO_WARNING_LOG("[%{public}s] write interval too long cost %{public}" PRId64,
1576 logUtilsTag_.c_str(), (ClockTime::GetCurNano() / AUDIO_US_PER_SECOND) - preWriteEndTime_);
1577 }
1578 }
WriteInner(uint8_t * pcmBuffer,size_t pcmBufferSize,uint8_t * metaBuffer,size_t metaBufferSize)1579 int32_t RendererInClientInner::WriteInner(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer,
1580 size_t metaBufferSize)
1581 {
1582 Trace trace("RendererInClient::Write with meta " + std::to_string(pcmBufferSize));
1583 CHECK_AND_RETURN_RET_LOG(curStreamParams_.encoding == ENCODING_AUDIOVIVID, ERR_NOT_SUPPORTED,
1584 "Write: Write not supported. encoding doesnot match.");
1585 BufferDesc bufDesc = {pcmBuffer, pcmBufferSize, pcmBufferSize, metaBuffer, metaBufferSize};
1586 CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, ERR_WRITE_FAILED, "Write: converter isn't init.");
1587 CHECK_AND_RETURN_RET_LOG(converter_->CheckInputValid(bufDesc), ERR_INVALID_PARAM, "Write: Invalid input.");
1588
1589 WriteMuteDataSysEvent(pcmBuffer, pcmBufferSize);
1590
1591 converter_->Process(bufDesc);
1592 uint8_t *buffer;
1593 uint32_t bufferSize;
1594 converter_->GetOutputBufferStream(buffer, bufferSize);
1595 return WriteInner(buffer, bufferSize);
1596 }
1597
FirstFrameProcess()1598 void RendererInClientInner::FirstFrameProcess()
1599 {
1600 // if first call, call set thread priority. if thread tid change recall set thread priority
1601 if (needSetThreadPriority_) {
1602 ipcStream_->RegisterThreadPriority(gettid(),
1603 AudioSystemManager::GetInstance()->GetSelfBundleName(clientConfig_.appInfo.appUid));
1604 needSetThreadPriority_ = false;
1605 }
1606
1607 if (!hasFirstFrameWrited_) { OnFirstFrameWriting(); }
1608 }
1609
WriteRingCache(uint8_t * buffer,size_t bufferSize,bool speedCached,size_t oriBufferSize)1610 int32_t RendererInClientInner::WriteRingCache(uint8_t *buffer, size_t bufferSize, bool speedCached,
1611 size_t oriBufferSize)
1612 {
1613 size_t targetSize = bufferSize;
1614 size_t offset = 0;
1615 while (targetSize >= sizePerFrameInByte_) {
1616 // 1. write data into ring cache
1617 OptResult result = ringCache_->GetWritableSize();
1618 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, speedCached ? oriBufferSize : bufferSize - targetSize,
1619 "RingCache write status invalid size is:%{public}zu", result.size);
1620
1621 size_t writableSize = result.size;
1622 Trace::Count("RendererInClient::CacheBuffer->writableSize", writableSize);
1623
1624 size_t writeSize = std::min(writableSize, targetSize);
1625 BufferWrap bufferWrap = {buffer + offset, writeSize};
1626
1627 if (writeSize > 0) {
1628 result = ringCache_->Enqueue(bufferWrap);
1629 if (result.ret != OPERATION_SUCCESS) {
1630 // in plan: recall enqueue in some cases
1631 AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size);
1632 break;
1633 }
1634 offset += writeSize;
1635 targetSize -= writeSize;
1636 clientWrittenBytes_ += writeSize;
1637 }
1638
1639 // 2. copy data from cache to OHAudioBuffer
1640 result = ringCache_->GetReadableSize();
1641 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, speedCached ? oriBufferSize : bufferSize - targetSize,
1642 "RingCache read status invalid size is:%{public}zu", result.size);
1643 size_t readableSize = result.size;
1644 Trace::Count("RendererInClient::CacheBuffer->readableSize", readableSize);
1645
1646 if (readableSize < clientSpanSizeInByte_) { continue; }
1647 // if readable size is enough, we will call write data to server
1648 int32_t ret = WriteCacheData();
1649 CHECK_AND_RETURN_RET_LOG(ret != ERR_ILLEGAL_STATE, speedCached ? oriBufferSize : bufferSize - targetSize,
1650 "Status changed while write");
1651 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "WriteCacheData failed %{public}d", ret);
1652 }
1653 preWriteEndTime_ = ClockTime::GetCurNano() / AUDIO_US_PER_SECOND;
1654 return speedCached ? oriBufferSize : bufferSize - targetSize;
1655 }
1656
WriteInner(uint8_t * buffer,size_t bufferSize)1657 int32_t RendererInClientInner::WriteInner(uint8_t *buffer, size_t bufferSize)
1658 {
1659 // eg: RendererInClient::sessionId:100001 WriteSize:3840
1660 DfxWriteInterval();
1661 Trace trace(traceTag_+ " WriteSize:" + std::to_string(bufferSize));
1662 CHECK_AND_RETURN_RET_LOG(buffer != nullptr && bufferSize < MAX_WRITE_SIZE && bufferSize > 0, ERR_INVALID_PARAM,
1663 "invalid size is %{public}zu", bufferSize);
1664 Trace::CountVolume(traceTag_, *buffer);
1665 if (gServerProxy_ == nullptr && getuid() == MEDIA_SERVICE_UID) {
1666 uint32_t samplingRate = clientConfig_.streamInfo.samplingRate;
1667 uint32_t channels = clientConfig_.streamInfo.channels;
1668 uint32_t samplePerFrame = Util::GetSamplePerFrame(clientConfig_.streamInfo.format);
1669 // calculate wait time by buffer size, 10e6 is converting seconds to microseconds
1670 uint32_t waitTimeUs = bufferSize * 10e6 / (samplingRate * channels * samplePerFrame);
1671 AUDIO_ERR_LOG("server is died! wait %{public}d us", waitTimeUs);
1672 usleep(waitTimeUs);
1673 return ERR_WRITE_BUFFER;
1674 }
1675
1676 CHECK_AND_RETURN_RET_LOG(gServerProxy_ != nullptr, ERROR, "server is died");
1677 if (clientBuffer_->GetStreamStatus() == nullptr) {
1678 AUDIO_ERR_LOG("The stream status is null!");
1679 return ERR_INVALID_PARAM;
1680 }
1681
1682 if (clientBuffer_->GetStreamStatus()->load() == STREAM_STAND_BY) {
1683 Trace trace2(traceTag_+ " call start to exit stand-by");
1684 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERROR, "ipcStream is not inited!");
1685 int32_t ret = ipcStream_->Start();
1686 AUDIO_INFO_LOG("%{public}u call start to exit stand-by ret %{public}u", sessionId_, ret);
1687 }
1688 std::lock_guard<std::mutex> lock(writeMutex_);
1689
1690 size_t oriBufferSize = bufferSize;
1691 bool speedCached = false;
1692 if (!ProcessSpeed(buffer, bufferSize, speedCached)) {
1693 return bufferSize;
1694 }
1695
1696 WriteMuteDataSysEvent(buffer, bufferSize);
1697
1698 FirstFrameProcess();
1699
1700 CHECK_AND_RETURN_RET_PRELOG(state_ == RUNNING, ERR_ILLEGAL_STATE,
1701 "Write: Illegal state:%{public}u sessionid: %{public}u", state_.load(), sessionId_);
1702
1703 // hold lock
1704 if (isBlendSet_) {
1705 audioBlend_.Process(buffer, bufferSize);
1706 }
1707
1708 return WriteRingCache(buffer, bufferSize, speedCached, oriBufferSize);
1709 }
1710
ResetFramePosition()1711 void RendererInClientInner::ResetFramePosition()
1712 {
1713 Trace trace("RendererInClientInner::ResetFramePosition");
1714 uint64_t timestampVal = 0;
1715 uint64_t latency = 0;
1716 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "ipcStream is not inited!");
1717 int32_t ret = ipcStream_->GetAudioPosition(lastFlushReadIndex_, timestampVal, latency);
1718 if (ret != SUCCESS) {
1719 AUDIO_PRERELEASE_LOGE("Get position failed: %{public}u", ret);
1720 return;
1721 }
1722 lastFramePosition_ = 0;
1723 }
1724
WriteMuteDataSysEvent(uint8_t * buffer,size_t bufferSize)1725 void RendererInClientInner::WriteMuteDataSysEvent(uint8_t *buffer, size_t bufferSize)
1726 {
1727 if (silentModeAndMixWithOthers_) {
1728 return;
1729 }
1730 if (buffer[0] == 0) {
1731 if (startMuteTime_ == 0) {
1732 startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
1733 }
1734 std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
1735 if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isUpEvent_) {
1736 AUDIO_WARNING_LOG("write silent data for some time");
1737 isUpEvent_ = true;
1738 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
1739 Media::MediaMonitor::AUDIO, Media::MediaMonitor::BACKGROUND_SILENT_PLAYBACK,
1740 Media::MediaMonitor::FREQUENCY_AGGREGATION_EVENT);
1741 bean->Add("CLIENT_UID", appUid_);
1742 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
1743 }
1744 } else if (buffer[0] != 0 && startMuteTime_ != 0) {
1745 startMuteTime_ = 0;
1746 }
1747 }
1748
DrainIncompleteFrame(OptResult result,bool stopFlag,size_t targetSize,BufferDesc * desc,bool & dropFlag)1749 int32_t RendererInClientInner::DrainIncompleteFrame(OptResult result, bool stopFlag,
1750 size_t targetSize, BufferDesc *desc, bool &dropFlag)
1751 {
1752 if (result.size < clientSpanSizeInByte_ && stopFlag) {
1753 result = ringCache_->Dequeue({desc->buffer, targetSize});
1754 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1755 "ringCache Dequeue failed %{public}d", result.ret);
1756 int32_t ret = memset_s(desc->buffer, targetSize, 0, targetSize);
1757 CHECK_AND_RETURN_RET_LOG(ret == EOK, ERROR, "DrainIncompleteFrame memset output failed");
1758 AUDIO_WARNING_LOG("incomplete frame is set to 0");
1759 dropFlag = true;
1760 }
1761 return SUCCESS;
1762 }
1763
1764
WriteCacheData(bool isDrain,bool stopFlag)1765 int32_t RendererInClientInner::WriteCacheData(bool isDrain, bool stopFlag)
1766 {
1767 Trace traceCache(isDrain ? "RendererInClientInner::DrainCacheData" : "RendererInClientInner::WriteCacheData");
1768
1769 OptResult result = ringCache_->GetReadableSize();
1770 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERR_OPERATION_FAILED, "ring cache unreadable");
1771 CHECK_AND_RETURN_RET_LOG(result.size != 0, SUCCESS, "Readable size is already zero");
1772
1773 size_t targetSize = isDrain ? std::min(result.size, clientSpanSizeInByte_) : clientSpanSizeInByte_;
1774
1775 int32_t sizeInFrame = clientBuffer_->GetAvailableDataFrames();
1776 CHECK_AND_RETURN_RET_LOG(sizeInFrame >= 0, ERROR, "GetAvailableDataFrames invalid, %{public}d", sizeInFrame);
1777
1778 int32_t tryCount = 2; // try futex wait for 2 times.
1779 FutexCode futexRes = FUTEX_OPERATION_FAILED;
1780 while (static_cast<uint32_t>(sizeInFrame) < spanSizeInFrame_ && tryCount > 0) {
1781 tryCount--;
1782 int32_t timeout = offloadEnable_ ? OFFLOAD_OPERATION_TIMEOUT_IN_MS : WRITE_CACHE_TIMEOUT_IN_MS;
1783 futexRes = FutexTool::FutexWait(clientBuffer_->GetFutex(), static_cast<int64_t>(timeout) * AUDIO_US_PER_SECOND);
1784 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "failed with state:%{public}d", state_.load());
1785 CHECK_AND_RETURN_RET_LOG(futexRes != FUTEX_TIMEOUT, ERROR,
1786 "write data time out, mode is %{public}s", (offloadEnable_ ? "offload" : "normal"));
1787 sizeInFrame = clientBuffer_->GetAvailableDataFrames();
1788 if (futexRes == FUTEX_SUCCESS && sizeInFrame > 0) { break; }
1789 }
1790
1791 if (sizeInFrame < 0 || static_cast<uint32_t>(clientBuffer_->GetAvailableDataFrames()) < spanSizeInFrame_) {
1792 AUDIO_ERR_LOG("failed: sizeInFrame is:%{public}d, futexRes:%{public}d", sizeInFrame, futexRes);
1793 return ERROR;
1794 }
1795 BufferDesc desc = {};
1796 uint64_t curWriteIndex = clientBuffer_->GetCurWriteFrame();
1797 int32_t ret = clientBuffer_->GetWriteBuffer(curWriteIndex, desc);
1798 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "GetWriteBuffer failed %{public}d", ret);
1799 bool dropFlag = false;
1800 CHECK_AND_RETURN_RET(DrainIncompleteFrame(result, stopFlag, targetSize, &desc, dropFlag) == SUCCESS, ERROR);
1801 if (dropFlag) {
1802 return SUCCESS;
1803 }
1804 result = ringCache_->Dequeue({desc.buffer, targetSize});
1805 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "ringCache Dequeue failed %{public}d", result.ret);
1806
1807 // volume process in client
1808 if (volumeRamp_.IsActive()) {
1809 // do not call SetVolume here.
1810 clientVolume_ = volumeRamp_.GetRampVolume();
1811 AUDIO_INFO_LOG("clientVolume_:%{public}f", clientVolume_);
1812 Trace traceVolume("RendererInClientInner::WriteCacheData:Ramp:clientVolume_:" + std::to_string(clientVolume_));
1813 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, ERR_OPERATION_FAILED, "buffer is not inited");
1814 clientBuffer_->SetStreamVolume(clientVolume_);
1815 }
1816
1817 DumpFileUtil::WriteDumpFile(dumpOutFd_, static_cast<void *>(desc.buffer), desc.bufLength);
1818 DfxOperation(desc, clientConfig_.streamInfo.format, clientConfig_.streamInfo.channels);
1819 clientBuffer_->SetCurWriteFrame(curWriteIndex + spanSizeInFrame_);
1820
1821 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, ERR_OPERATION_FAILED, "WriteCacheData failed, null ipcStream_.");
1822 ipcStream_->UpdatePosition(); // notiify server update position
1823 HandleRendererPositionChanges(desc.bufLength);
1824 return SUCCESS;
1825 }
1826
DfxOperation(BufferDesc & buffer,AudioSampleFormat format,AudioChannel channel) const1827 void RendererInClientInner::DfxOperation(BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel) const
1828 {
1829 ChannelVolumes vols = VolumeTools::CountVolumeLevel(buffer, format, channel);
1830 if (channel == MONO) {
1831 Trace::Count(logUtilsTag_, vols.volStart[0]);
1832 } else {
1833 Trace::Count(logUtilsTag_, (vols.volStart[0] + vols.volStart[1]) / HALF_FACTOR);
1834 }
1835 AudioLogUtils::ProcessVolumeData(logUtilsTag_, vols, volumeDataCount_);
1836 }
1837
HandleRendererPositionChanges(size_t bytesWritten)1838 void RendererInClientInner::HandleRendererPositionChanges(size_t bytesWritten)
1839 {
1840 totalBytesWritten_ += static_cast<int64_t>(bytesWritten);
1841 if (sizePerFrameInByte_ == 0) {
1842 AUDIO_ERR_LOG("HandleRendererPositionChanges: sizePerFrameInByte_ is 0");
1843 return;
1844 }
1845 int64_t writtenFrameNumber = totalBytesWritten_ / static_cast<int64_t>(sizePerFrameInByte_);
1846 AUDIO_DEBUG_LOG("frame size: %{public}zu", sizePerFrameInByte_);
1847
1848 {
1849 std::lock_guard<std::mutex> lock(markReachMutex_);
1850 if (!rendererMarkReached_) {
1851 AUDIO_DEBUG_LOG("Frame mark position: %{public}" PRId64", Total frames written: %{public}" PRId64,
1852 static_cast<int64_t>(rendererMarkPosition_), static_cast<int64_t>(writtenFrameNumber));
1853 if (writtenFrameNumber >= rendererMarkPosition_) {
1854 AUDIO_DEBUG_LOG("OnMarkReached %{public}" PRId64".", rendererMarkPosition_);
1855 SendRenderMarkReachedEvent(rendererMarkPosition_);
1856 rendererMarkReached_ = true;
1857 }
1858 }
1859 }
1860
1861 {
1862 std::lock_guard<std::mutex> lock(periodReachMutex_);
1863 rendererPeriodWritten_ += static_cast<int64_t>((bytesWritten / sizePerFrameInByte_));
1864 AUDIO_DEBUG_LOG("Frame period number: %{public}" PRId64", Total frames written: %{public}" PRId64,
1865 static_cast<int64_t>(rendererPeriodWritten_), static_cast<int64_t>(totalBytesWritten_));
1866 if (rendererPeriodWritten_ >= rendererPeriodSize_ && rendererPeriodSize_ > 0) {
1867 rendererPeriodWritten_ %= rendererPeriodSize_;
1868 AUDIO_DEBUG_LOG("OnPeriodReached, remaining frames: %{public}" PRId64,
1869 static_cast<int64_t>(rendererPeriodWritten_));
1870 SendRenderPeriodReachedEvent(rendererPeriodSize_);
1871 }
1872 }
1873 }
1874
1875 // OnRenderMarkReach by eventHandler
SendRenderMarkReachedEvent(int64_t rendererMarkPosition)1876 void RendererInClientInner::SendRenderMarkReachedEvent(int64_t rendererMarkPosition)
1877 {
1878 SafeSendCallbackEvent(RENDERER_MARK_REACHED_EVENT, rendererMarkPosition);
1879 }
1880
1881 // OnRenderPeriodReach by eventHandler
SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)1882 void RendererInClientInner::SendRenderPeriodReachedEvent(int64_t rendererPeriodSize)
1883 {
1884 SafeSendCallbackEvent(RENDERER_PERIOD_REACHED_EVENT, rendererPeriodSize);
1885 }
1886
ParamsToStateCmdType(int64_t params,State & state,StateChangeCmdType & cmdType)1887 int32_t RendererInClientInner::ParamsToStateCmdType(int64_t params, State &state, StateChangeCmdType &cmdType)
1888 {
1889 cmdType = CMD_FROM_CLIENT;
1890 switch (params) {
1891 case HANDLER_PARAM_NEW:
1892 state = NEW;
1893 break;
1894 case HANDLER_PARAM_PREPARED:
1895 state = PREPARED;
1896 break;
1897 case HANDLER_PARAM_RUNNING:
1898 state = RUNNING;
1899 break;
1900 case HANDLER_PARAM_STOPPED:
1901 state = STOPPED;
1902 break;
1903 case HANDLER_PARAM_RELEASED:
1904 state = RELEASED;
1905 break;
1906 case HANDLER_PARAM_PAUSED:
1907 state = PAUSED;
1908 break;
1909 case HANDLER_PARAM_STOPPING:
1910 state = STOPPING;
1911 break;
1912 case HANDLER_PARAM_RUNNING_FROM_SYSTEM:
1913 state = RUNNING;
1914 cmdType = CMD_FROM_SYSTEM;
1915 break;
1916 case HANDLER_PARAM_PAUSED_FROM_SYSTEM:
1917 state = PAUSED;
1918 cmdType = CMD_FROM_SYSTEM;
1919 break;
1920 default:
1921 state = INVALID;
1922 break;
1923 }
1924 return SUCCESS;
1925 }
1926
StateCmdTypeToParams(int64_t & params,State state,StateChangeCmdType cmdType)1927 int32_t RendererInClientInner::StateCmdTypeToParams(int64_t ¶ms, State state, StateChangeCmdType cmdType)
1928 {
1929 if (cmdType == CMD_FROM_CLIENT) {
1930 params = static_cast<int64_t>(state);
1931 return SUCCESS;
1932 }
1933 switch (state) {
1934 case RUNNING:
1935 params = HANDLER_PARAM_RUNNING_FROM_SYSTEM;
1936 break;
1937 case PAUSED:
1938 params = HANDLER_PARAM_PAUSED_FROM_SYSTEM;
1939 break;
1940 default:
1941 params = HANDLER_PARAM_INVALID;
1942 break;
1943 }
1944 return SUCCESS;
1945 }
1946
Read(uint8_t & buffer,size_t userSize,bool isBlockingRead)1947 int32_t RendererInClientInner::Read(uint8_t &buffer, size_t userSize, bool isBlockingRead)
1948 {
1949 AUDIO_ERR_LOG("Read is not supported");
1950 return ERROR;
1951 }
1952
1953
GetUnderflowCount()1954 uint32_t RendererInClientInner::GetUnderflowCount()
1955 {
1956 CHECK_AND_RETURN_RET_LOG(clientBuffer_ != nullptr, 0, "buffer is not inited");
1957
1958 return clientBuffer_->GetUnderrunCount();
1959 }
1960
GetOverflowCount()1961 uint32_t RendererInClientInner::GetOverflowCount()
1962 {
1963 AUDIO_WARNING_LOG("No Overflow in renderer");
1964 return 0;
1965 }
1966
SetUnderflowCount(uint32_t underflowCount)1967 void RendererInClientInner::SetUnderflowCount(uint32_t underflowCount)
1968 {
1969 CHECK_AND_RETURN_LOG(clientBuffer_ != nullptr, "buffer is not inited");
1970 clientBuffer_->SetUnderrunCount(underflowCount);
1971 }
1972
SetOverflowCount(uint32_t overflowCount)1973 void RendererInClientInner::SetOverflowCount(uint32_t overflowCount)
1974 {
1975 // not support for renderer
1976 AUDIO_WARNING_LOG("No Overflow in renderer");
1977 return;
1978 }
1979
SetRendererPositionCallback(int64_t markPosition,const std::shared_ptr<RendererPositionCallback> & callback)1980 void RendererInClientInner::SetRendererPositionCallback(int64_t markPosition,
1981 const std::shared_ptr<RendererPositionCallback> &callback)
1982 {
1983 // waiting for review
1984 std::lock_guard<std::mutex> lock(markReachMutex_);
1985 CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPositionCallback is nullptr");
1986 rendererPositionCallback_ = callback;
1987 rendererMarkPosition_ = markPosition;
1988 rendererMarkReached_ = false;
1989 }
1990
UnsetRendererPositionCallback()1991 void RendererInClientInner::UnsetRendererPositionCallback()
1992 {
1993 // waiting for review
1994 std::lock_guard<std::mutex> lock(markReachMutex_);
1995 rendererPositionCallback_ = nullptr;
1996 rendererMarkPosition_ = 0;
1997 rendererMarkReached_ = false;
1998 }
1999
SetRendererPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<RendererPeriodPositionCallback> & callback)2000 void RendererInClientInner::SetRendererPeriodPositionCallback(int64_t periodPosition,
2001 const std::shared_ptr<RendererPeriodPositionCallback> &callback)
2002 {
2003 // waiting for review
2004 std::lock_guard<std::mutex> lock(periodReachMutex_);
2005 CHECK_AND_RETURN_LOG(callback != nullptr, "RendererPeriodPositionCallback is nullptr");
2006 rendererPeriodPositionCallback_ = callback;
2007 rendererPeriodSize_ = periodPosition;
2008 totalBytesWritten_ = 0;
2009 rendererPeriodWritten_ = 0;
2010 }
2011
UnsetRendererPeriodPositionCallback()2012 void RendererInClientInner::UnsetRendererPeriodPositionCallback()
2013 {
2014 // waiting for review
2015 std::lock_guard<std::mutex> lock(periodReachMutex_);
2016 rendererPeriodPositionCallback_ = nullptr;
2017 rendererPeriodSize_ = 0;
2018 totalBytesWritten_ = 0;
2019 rendererPeriodWritten_ = 0;
2020 }
2021
SetCapturerPositionCallback(int64_t markPosition,const std::shared_ptr<CapturerPositionCallback> & callback)2022 void RendererInClientInner::SetCapturerPositionCallback(int64_t markPosition,
2023 const std::shared_ptr<CapturerPositionCallback> &callback)
2024 {
2025 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2026 return;
2027 }
2028
UnsetCapturerPositionCallback()2029 void RendererInClientInner::UnsetCapturerPositionCallback()
2030 {
2031 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2032 return;
2033 }
2034
SetCapturerPeriodPositionCallback(int64_t periodPosition,const std::shared_ptr<CapturerPeriodPositionCallback> & callback)2035 void RendererInClientInner::SetCapturerPeriodPositionCallback(int64_t periodPosition,
2036 const std::shared_ptr<CapturerPeriodPositionCallback> &callback)
2037 {
2038 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2039 return;
2040 }
2041
UnsetCapturerPeriodPositionCallback()2042 void RendererInClientInner::UnsetCapturerPeriodPositionCallback()
2043 {
2044 AUDIO_ERR_LOG("SetCapturerPositionCallback is not supported");
2045 return;
2046 }
2047
SetRendererSamplingRate(uint32_t sampleRate)2048 int32_t RendererInClientInner::SetRendererSamplingRate(uint32_t sampleRate)
2049 {
2050 AUDIO_ERR_LOG("SetRendererSamplingRate to %{public}d is not supported", sampleRate);
2051 return ERROR;
2052 }
2053
GetRendererSamplingRate()2054 uint32_t RendererInClientInner::GetRendererSamplingRate()
2055 {
2056 return curStreamParams_.samplingRate;
2057 }
2058
SetBufferSizeInMsec(int32_t bufferSizeInMsec)2059 int32_t RendererInClientInner::SetBufferSizeInMsec(int32_t bufferSizeInMsec)
2060 {
2061 // bufferSizeInMsec is checked between 5ms and 20ms.
2062 bufferSizeInMsec_ = static_cast<uint32_t>(bufferSizeInMsec);
2063 AUDIO_INFO_LOG("SetBufferSizeInMsec to %{public}d", bufferSizeInMsec_);
2064 if (renderMode_ == RENDER_MODE_CALLBACK) {
2065 uint64_t bufferDurationInUs = bufferSizeInMsec_ * AUDIO_US_PER_MS;
2066 InitCallbackBuffer(bufferDurationInUs);
2067 }
2068 return SUCCESS;
2069 }
2070
SetApplicationCachePath(const std::string cachePath)2071 void RendererInClientInner::SetApplicationCachePath(const std::string cachePath)
2072 {
2073 cachePath_ = cachePath;
2074 AUDIO_INFO_LOG("SetApplicationCachePath to %{public}s", cachePath_.c_str());
2075 }
2076
SetChannelBlendMode(ChannelBlendMode blendMode)2077 int32_t RendererInClientInner::SetChannelBlendMode(ChannelBlendMode blendMode)
2078 {
2079 if ((state_ != PREPARED) && (state_ != NEW)) {
2080 AUDIO_ERR_LOG("SetChannelBlendMode in invalid status:%{public}d", state_.load());
2081 return ERR_ILLEGAL_STATE;
2082 }
2083 isBlendSet_ = true;
2084 audioBlend_.SetParams(blendMode, curStreamParams_.format, curStreamParams_.channels);
2085 return SUCCESS;
2086 }
2087
SetVolumeWithRamp(float volume,int32_t duration)2088 int32_t RendererInClientInner::SetVolumeWithRamp(float volume, int32_t duration)
2089 {
2090 CHECK_AND_RETURN_RET_LOG((state_ != RELEASED) && (state_ != INVALID) && (state_ != STOPPED),
2091 ERR_ILLEGAL_STATE, "Illegal state state %{public}d", state_.load());
2092
2093 if (FLOAT_COMPARE_EQ(clientVolume_, volume)) {
2094 AUDIO_INFO_LOG("set same volume %{public}f", volume);
2095 return SUCCESS;
2096 }
2097
2098 volumeRamp_.SetVolumeRampConfig(volume, clientVolume_, duration);
2099 return SUCCESS;
2100 }
2101
SetStreamTrackerState(bool trackerRegisteredState)2102 void RendererInClientInner::SetStreamTrackerState(bool trackerRegisteredState)
2103 {
2104 streamTrackerRegistered_ = trackerRegisteredState;
2105 }
2106
GetSwitchInfo(IAudioStream::SwitchInfo & info)2107 void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info)
2108 {
2109 info.params = streamParams_;
2110
2111 info.rendererInfo = rendererInfo_;
2112 info.capturerInfo = capturerInfo_;
2113 info.eStreamType = eStreamType_;
2114 info.renderMode = renderMode_;
2115 info.state = state_;
2116 info.sessionId = sessionId_;
2117 info.streamTrackerRegistered = streamTrackerRegistered_;
2118 GetStreamSwitchInfo(info);
2119
2120 {
2121 std::lock_guard<std::mutex> lock(setPreferredFrameSizeMutex_);
2122 info.userSettedPreferredFrameSize = userSettedPreferredFrameSize_;
2123 }
2124 }
2125
GetStreamSwitchInfo(IAudioStream::SwitchInfo & info)2126 void RendererInClientInner::GetStreamSwitchInfo(IAudioStream::SwitchInfo& info)
2127 {
2128 info.cachePath = cachePath_;
2129 info.underFlowCount = GetUnderflowCount();
2130 info.effectMode = effectMode_;
2131 info.renderRate = rendererRate_;
2132 info.clientPid = clientPid_;
2133 info.clientUid = clientUid_;
2134 info.volume = clientVolume_;
2135 info.silentModeAndMixWithOthers = silentModeAndMixWithOthers_;
2136
2137 info.frameMarkPosition = static_cast<uint64_t>(rendererMarkPosition_);
2138 info.renderPositionCb = rendererPositionCallback_;
2139
2140 info.framePeriodNumber = static_cast<uint64_t>(rendererPeriodSize_);
2141 info.renderPeriodPositionCb = rendererPeriodPositionCallback_;
2142
2143 info.rendererWriteCallback = writeCb_;
2144 }
2145
GetStreamClass()2146 IAudioStream::StreamClass RendererInClientInner::GetStreamClass()
2147 {
2148 return PA_STREAM;
2149 }
2150
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)2151 void RendererInClientInner::OnSpatializationStateChange(const AudioSpatializationState &spatializationState)
2152 {
2153 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
2154 CHECK_AND_RETURN_LOG(ipcStream_->UpdateSpatializationState(spatializationState.spatializationEnabled,
2155 spatializationState.headTrackingEnabled) == SUCCESS, "Update spatialization state failed");
2156 }
2157
GetOffloadEnable()2158 bool RendererInClientInner::GetOffloadEnable()
2159 {
2160 return offloadEnable_;
2161 }
2162
GetSpatializationEnabled()2163 bool RendererInClientInner::GetSpatializationEnabled()
2164 {
2165 return rendererInfo_.spatializationEnabled;
2166 }
2167
GetHighResolutionEnabled()2168 bool RendererInClientInner::GetHighResolutionEnabled()
2169 {
2170 return AudioPolicyManager::GetInstance().IsHighResolutionExist();
2171 }
2172
RegisterSpatializationStateEventListener()2173 int32_t RendererInClientInner::RegisterSpatializationStateEventListener()
2174 {
2175 if (firstSpatializationRegistered_) {
2176 firstSpatializationRegistered_ = false;
2177 } else {
2178 UnregisterSpatializationStateEventListener(spatializationRegisteredSessionID_);
2179 }
2180
2181 if (!spatializationStateChangeCallback_) {
2182 spatializationStateChangeCallback_ = std::make_shared<SpatializationStateChangeCallbackImpl>();
2183 CHECK_AND_RETURN_RET_LOG(spatializationStateChangeCallback_, ERROR, "Memory Allocation Failed !!");
2184 }
2185 spatializationStateChangeCallback_->SetRendererInClientPtr(shared_from_this());
2186
2187 int32_t ret = AudioPolicyManager::GetInstance().RegisterSpatializationStateEventListener(
2188 sessionId_, rendererInfo_.streamUsage, spatializationStateChangeCallback_);
2189 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "RegisterSpatializationStateEventListener failed");
2190 spatializationRegisteredSessionID_ = sessionId_;
2191
2192 return SUCCESS;
2193 }
2194
UnregisterSpatializationStateEventListener(uint32_t sessionID)2195 int32_t RendererInClientInner::UnregisterSpatializationStateEventListener(uint32_t sessionID)
2196 {
2197 int32_t ret = AudioPolicyManager::GetInstance().UnregisterSpatializationStateEventListener(sessionID);
2198 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "UnregisterSpatializationStateEventListener failed");
2199 return SUCCESS;
2200 }
2201
DrainAudioStreamInner(bool stopFlag)2202 bool RendererInClientInner::DrainAudioStreamInner(bool stopFlag)
2203 {
2204 Trace trace("RendererInClientInner::DrainAudioStreamInner " + std::to_string(sessionId_));
2205 CHECK_AND_RETURN_RET_LOG(state_ == RUNNING, false, "Drain failed. Illegal state:%{public}u", state_.load());
2206 CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed");
2207
2208 CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!");
2209 AUDIO_INFO_LOG("stopFlag:%{public}d", stopFlag);
2210 int32_t ret = ipcStream_->Drain(stopFlag);
2211 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Drain call server failed:%{public}u", ret);
2212 std::unique_lock<std::mutex> waitLock(callServerMutex_);
2213 bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] {
2214 return notifiedOperation_ == DRAIN_STREAM; // will be false when got notified.
2215 });
2216
2217 if (notifiedOperation_ != DRAIN_STREAM || notifiedResult_ != SUCCESS) {
2218 AUDIO_ERR_LOG("Drain failed: %{public}s Operation:%{public}d result:%{public}" PRId64".",
2219 (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_);
2220 notifiedOperation_ = MAX_OPERATION_CODE;
2221 return false;
2222 }
2223 notifiedOperation_ = MAX_OPERATION_CODE;
2224 waitLock.unlock();
2225 AUDIO_INFO_LOG("Drain stream SUCCESS, sessionId: %{public}d", sessionId_);
2226 return true;
2227 }
2228
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)2229 void RendererInClientInner::UpdateLatencyTimestamp(std::string ×tamp, bool isRenderer)
2230 {
2231 sptr<IStandardAudioService> gasp = RendererInClientInner::GetAudioServerProxy();
2232 if (gasp == nullptr) {
2233 AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
2234 return;
2235 }
2236 gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
2237 }
2238
SetSilentModeAndMixWithOthers(bool on)2239 void RendererInClientInner::SetSilentModeAndMixWithOthers(bool on)
2240 {
2241 AUDIO_PRERELEASE_LOGI("SetSilentModeAndMixWithOthers %{public}d", on);
2242 silentModeAndMixWithOthers_ = on;
2243 CHECK_AND_RETURN_LOG(ipcStream_ != nullptr, "Object ipcStream is nullptr");
2244 ipcStream_->SetSilentModeAndMixWithOthers(on);
2245 return;
2246 }
2247
GetSilentModeAndMixWithOthers()2248 bool RendererInClientInner::GetSilentModeAndMixWithOthers()
2249 {
2250 return silentModeAndMixWithOthers_;
2251 }
2252
SpatializationStateChangeCallbackImpl()2253 SpatializationStateChangeCallbackImpl::SpatializationStateChangeCallbackImpl()
2254 {
2255 AUDIO_INFO_LOG("Instance create");
2256 }
2257
~SpatializationStateChangeCallbackImpl()2258 SpatializationStateChangeCallbackImpl::~SpatializationStateChangeCallbackImpl()
2259 {
2260 AUDIO_INFO_LOG("Instance destory");
2261 }
2262
SetRendererInClientPtr(std::shared_ptr<RendererInClientInner> rendererInClientPtr)2263 void SpatializationStateChangeCallbackImpl::SetRendererInClientPtr(
2264 std::shared_ptr<RendererInClientInner> rendererInClientPtr)
2265 {
2266 rendererInClientPtr_ = rendererInClientPtr;
2267 }
2268
OnSpatializationStateChange(const AudioSpatializationState & spatializationState)2269 void SpatializationStateChangeCallbackImpl::OnSpatializationStateChange(
2270 const AudioSpatializationState &spatializationState)
2271 {
2272 std::shared_ptr<RendererInClientInner> rendererInClient = rendererInClientPtr_.lock();
2273 if (rendererInClient != nullptr) {
2274 rendererInClient->OnSpatializationStateChange(spatializationState);
2275 }
2276 }
2277
RestoreAudioStream(bool needStoreState)2278 bool RendererInClientInner::RestoreAudioStream(bool needStoreState)
2279 {
2280 CHECK_AND_RETURN_RET_LOG(proxyObj_ != nullptr, false, "proxyObj_ is null");
2281 CHECK_AND_RETURN_RET_LOG(state_ != NEW && state_ != INVALID && state_ != RELEASED, true,
2282 "state_ is %{public}d, no need for restore", state_.load());
2283 bool result = false;
2284 State oldState = state_;
2285 state_ = NEW;
2286 SetStreamTrackerState(false);
2287 // If pipe type is offload, need reset to normal.
2288 // Otherwise, unable to enter offload mode.
2289 if (rendererInfo_.pipeType == PIPE_TYPE_OFFLOAD) {
2290 rendererInfo_.pipeType = PIPE_TYPE_NORMAL_OUT;
2291 }
2292 int32_t ret = SetAudioStreamInfo(streamParams_, proxyObj_);
2293 if (ret != SUCCESS) {
2294 goto error;
2295 }
2296 if (!needStoreState) {
2297 AUDIO_INFO_LOG("telephony scene, return directly");
2298 return ret == SUCCESS;
2299 }
2300 switch (oldState) {
2301 case RUNNING:
2302 result = StartAudioStream();
2303 break;
2304 case PAUSED:
2305 result = StartAudioStream() && PauseAudioStream();
2306 break;
2307 case STOPPED:
2308 case STOPPING:
2309 result = StartAudioStream() && StopAudioStream();
2310 break;
2311 default:
2312 break;
2313 }
2314 if (!result) {
2315 goto error;
2316 }
2317 return result;
2318
2319 error:
2320 AUDIO_ERR_LOG("RestoreAudioStream failed");
2321 state_ = oldState;
2322 return false;
2323 }
2324 } // namespace AudioStandard
2325 } // namespace OHOS
2326 #endif // FAST_AUDIO_STREAM_H
2327