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