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