1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "RendererInServer"
17 #endif
18
19 #include "renderer_in_server.h"
20 #include <cinttypes>
21 #include "securec.h"
22 #include "audio_errors.h"
23 #include "audio_renderer_log.h"
24 #include "audio_utils.h"
25 #include "audio_service.h"
26 #include "futex_tool.h"
27 #include "i_stream_manager.h"
28 #ifdef RESSCHE_ENABLE
29 #include "res_type.h"
30 #include "res_sched_client.h"
31 #endif
32 #include "volume_tools.h"
33 #include "policy_handler.h"
34 #include "audio_enhance_chain_manager.h"
35 #include "media_monitor_manager.h"
36 #include "audio_volume.h"
37 #include "audio_dump_pcm.h"
38 #include "audio_performance_monitor.h"
39 #include "audio_volume_c.h"
40 #include "core_service_handler.h"
41 #include "audio_service_enum.h"
42 #include "i_hpae_manager.h"
43 #include "stream_dfx_manager.h"
44 #include "audio_stream_enum.h"
45
46 namespace OHOS {
47 namespace AudioStandard {
48 namespace {
49 static const int64_t MOCK_LATENCY = 45000000; // 45000000 -> 45ms
50 static const int64_t START_MIN_COST = 80000000; // 80000000 -> 80ms
51 static const int32_t NO_FADING = 0;
52 static const int32_t DO_FADINGOUT = 1;
53 static const int32_t FADING_OUT_DONE = 2;
54 static const float FADINGOUT_BEGIN = 1.0f;
55 static const float FADINGOUT_END = 0.0f;
56 static constexpr int32_t ONE_MINUTE = 60;
57 const int32_t MEDIA_UID = 1013;
58 const float AUDIO_VOLOMUE_EPSILON = 0.0001;
59 const int32_t OFFLOAD_INNER_CAP_PREBUF = 3;
60 constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S
61 constexpr int32_t DEFAULT_SPAN_SIZE = 2;
62 constexpr size_t MSEC_PER_SEC = 1000;
63 const int32_t DUP_OFFLOAD_LEN = 7000; // 7000 -> 7000ms
64 const int32_t DUP_COMMON_LEN = 440; // 400 -> 440ms
65 const int32_t DUP_DEFAULT_LEN = 20; // 20 -> 20ms
66 const int32_t DUP_RECOVERY_AUTISHAKE_BUFFER_COUNT = 2; // 2 -> 2 frames -> 40ms
67 }
68
RendererInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)69 RendererInServer::RendererInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
70 : processConfig_(processConfig)
71 {
72 streamListener_ = streamListener;
73 managerType_ = PLAYBACK;
74 if (processConfig_.callerUid == MEDIA_UID) {
75 isNeedFade_ = true;
76 oldAppliedVolume_ = MIN_FLOAT_VOLUME;
77 }
78 audioStreamChecker_ = std::make_shared<AudioStreamChecker>(processConfig);
79 AudioStreamMonitor::GetInstance().AddCheckForMonitor(processConfig.originalSessionId, audioStreamChecker_);
80 }
81
~RendererInServer()82 RendererInServer::~RendererInServer()
83 {
84 if (status_ != I_STATUS_RELEASED) {
85 Release();
86 }
87 DumpFileUtil::CloseDumpFile(&dumpC2S_);
88 AudioStreamMonitor::GetInstance().DeleteCheckForMonitor(processConfig_.originalSessionId);
89 }
90
ConfigServerBuffer()91 int32_t RendererInServer::ConfigServerBuffer()
92 {
93 if (audioServerBuffer_ != nullptr) {
94 AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
95 return SUCCESS;
96 }
97 stream_->GetSpanSizePerFrame(spanSizeInFrame_);
98 int32_t engineFlag = GetEngineFlag();
99 if (engineFlag == 1) {
100 engineTotalSizeInFrame_ = processConfig_.rendererInfo.playerType == PLAYER_TYPE_TONE_PLAYER ?
101 spanSizeInFrame_ * 4 : spanSizeInFrame_ * 2; // default 2 frames, 4 frames for toneplayer
102 } else {
103 engineTotalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE;
104 }
105 stream_->GetByteSizePerFrame(byteSizePerFrame_);
106 if (engineTotalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || engineTotalSizeInFrame_ % spanSizeInFrame_ != 0) {
107 AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
108 return ERR_INVALID_PARAM;
109 }
110
111 size_t maxClientCbBufferInFrame = MAX_CBBUF_IN_USEC * processConfig_.streamInfo.samplingRate / AUDIO_US_PER_S;
112 bufferTotalSizeInFrame_ = engineTotalSizeInFrame_ + maxClientCbBufferInFrame;
113
114 spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_;
115 CHECK_AND_RETURN_RET_LOG(spanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config oh audio buffer failed!");
116 AUDIO_INFO_LOG("engineTotalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu, byteSizePerFrame_:%{public}zu "
117 "spanSizeInByte_: %{public}zu, bufferTotalSizeInFrame_: %{public}zu", engineTotalSizeInFrame_,
118 spanSizeInFrame_, byteSizePerFrame_, spanSizeInByte_, bufferTotalSizeInFrame_);
119
120 // create OHAudioBuffer in server
121 audioServerBuffer_ = OHAudioBufferBase::CreateFromLocal(bufferTotalSizeInFrame_, byteSizePerFrame_);
122 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
123
124 // we need to clear data buffer to avoid dirty data.
125 memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
126 audioServerBuffer_->GetDataSize());
127 int32_t ret = InitBufferStatus();
128 AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
129
130 isBufferConfiged_ = true;
131 isInited_ = true;
132 return SUCCESS;
133 }
134
InitBufferStatus()135 int32_t RendererInServer::InitBufferStatus()
136 {
137 if (audioServerBuffer_ == nullptr) {
138 AUDIO_ERR_LOG("InitBufferStatus failed, null buffer!");
139 return ERR_ILLEGAL_STATE;
140 }
141 return SUCCESS;
142 }
143
GetEAC3ControlParam()144 void RendererInServer::GetEAC3ControlParam()
145 {
146 int32_t eac3TestFlag = 0;
147 GetSysPara("persist.multimedia.eac3test", eac3TestFlag);
148 if (eac3TestFlag == 1) {
149 managerType_ = EAC3_PLAYBACK;
150 }
151 }
152
ProcessManagerType()153 void RendererInServer::ProcessManagerType()
154 {
155 if (processConfig_.rendererInfo.audioFlag == (AUDIO_OUTPUT_FLAG_HD|AUDIO_OUTPUT_FLAG_DIRECT)) {
156 Trace trace("current stream marked as high resolution");
157 managerType_ = DIRECT_PLAYBACK;
158 AUDIO_INFO_LOG("current stream marked as high resolution");
159 }
160 if (processConfig_.streamInfo.encoding == ENCODING_EAC3) {
161 managerType_ = EAC3_PLAYBACK;
162 AUDIO_INFO_LOG("current stream marked as eac3 direct stream");
163 }
164 if (processConfig_.rendererInfo.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) {
165 if (IStreamManager::GetPlaybackManager(VOIP_PLAYBACK).GetStreamCount() <= 0) {
166 AUDIO_INFO_LOG("current stream marked as VoIP direct stream");
167 managerType_ = VOIP_PLAYBACK;
168 } else {
169 AUDIO_WARNING_LOG("One VoIP direct stream has been created! Use normal mode.");
170 }
171 }
172 }
173
Init()174 int32_t RendererInServer::Init()
175 {
176 ProcessManagerType();
177 GetEAC3ControlParam();
178 streamIndex_ = processConfig_.originalSessionId;
179 AUDIO_INFO_LOG("Stream index: %{public}u", streamIndex_);
180
181 int32_t ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
182 if (ret != SUCCESS && (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK)) {
183 Trace trace("high resolution create failed use normal replace");
184 managerType_ = PLAYBACK;
185 ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
186 AUDIO_INFO_LOG("high resolution create failed use normal replace");
187 }
188 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
189 "Construct rendererInServer failed: %{public}d", ret);
190 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
191 StreamVolumeParams streamVolumeParams = { streamIndex_, processConfig_.streamType,
192 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
193 isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
194 AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
195 traceTag_ = "[" + std::to_string(streamIndex_) + "]RendererInServer"; // [100001]RendererInServer:
196 ret = ConfigServerBuffer();
197 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
198 "Construct rendererInServer failed: %{public}d", ret);
199 stream_->RegisterStatusCallback(shared_from_this());
200 stream_->RegisterWriteCallback(shared_from_this());
201
202 // eg: /data/data/.pulse_dir/10000_100001_48000_2_1_server_in.pcm
203 AudioStreamInfo tempInfo = processConfig_.streamInfo;
204 dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
205 + "_renderer_server_in_" + std::to_string(tempInfo.samplingRate) + "_"
206 + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
207 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpC2S_);
208 playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, streamIndex_);
209
210 return SUCCESS;
211 }
212
CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)213 void RendererInServer::CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)
214 {
215 if (standbyEnable == lastWriteStandbyEnableStatus_) {
216 return;
217 }
218 lastWriteStandbyEnableStatus_ = standbyEnable;
219 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
220 Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
221 Media::MediaMonitor::BEHAVIOR_EVENT);
222 bean->Add("STREAMID", static_cast<int32_t>(streamIndex_));
223 bean->Add("STANDBY", standbyEnable ? 1 : 0);
224 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
225 std::unordered_map<std::string, std::string> payload;
226 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
227 payload["sessionId"] = std::to_string(streamIndex_);
228 payload["isStandby"] = std::to_string(standbyEnable ? 1 : 0);
229 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
230 AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
231 }
232
OnStatusUpdate(IOperation operation)233 void RendererInServer::OnStatusUpdate(IOperation operation)
234 {
235 if (operation != OPERATION_UNDERFLOW) {
236 AUDIO_INFO_LOG("%{public}u recv operation:%{public}d standByEnable_:%{public}s", streamIndex_, operation,
237 (standByEnable_ ? "true" : "false"));
238 }
239 Trace trace(traceTag_ + " OnStatusUpdate:" + std::to_string(operation));
240 CHECK_AND_RETURN_LOG(operation != OPERATION_RELEASED, "Stream already released!");
241 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
242 CHECK_AND_RETURN_LOG((stateListener != nullptr && playerDfx_ != nullptr), "nullptr");
243 CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
244 "stream status is nullptr");
245 switch (operation) {
246 case OPERATION_STARTED:
247 HandleOperationStarted();
248 stateListener->OnOperationHandled(START_STREAM, 0);
249 break;
250 case OPERATION_PAUSED:
251 if (standByEnable_) {
252 AUDIO_INFO_LOG("%{public}u recv stand-by paused", streamIndex_);
253 audioServerBuffer_->GetStreamStatus()->store(STREAM_STAND_BY);
254 CheckAndWriterRenderStreamStandbySysEvent(true);
255 return;
256 }
257 status_ = I_STATUS_PAUSED;
258 stateListener->OnOperationHandled(PAUSE_STREAM, 0);
259 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_PAUSE_OK);
260 break;
261 case OPERATION_STOPPED:
262 status_ = I_STATUS_STOPPED;
263 stateListener->OnOperationHandled(STOP_STREAM, 0);
264 HandleOperationStopped(RENDERER_STAGE_STOP_OK);
265 break;
266 case OPERATION_FLUSHED:
267 HandleOperationFlushed();
268 stateListener->OnOperationHandled(FLUSH_STREAM, 0);
269 break;
270 case OPERATION_DRAINED:
271 // Client's StopAudioStream will call Drain first and then Stop. If server's drain times out,
272 // Stop will be completed first. After a period of time, when Drain's callback goes here,
273 // state of server should not be changed to STARTED while the client state is Stopped.
274 OnStatusUpdateExt(operation, stateListener);
275 break;
276 default:
277 OnStatusUpdateSub(operation);
278 }
279 AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
280 }
281
GetLastAudioDuration()282 int64_t RendererInServer::GetLastAudioDuration()
283 {
284 auto ret = lastStopTime_ - lastStartTime_;
285 return ret < 0 ? -1 : ret;
286 }
287
OnStatusUpdateExt(IOperation operation,std::shared_ptr<IStreamListener> stateListener)288 void RendererInServer::OnStatusUpdateExt(IOperation operation, std::shared_ptr<IStreamListener> stateListener)
289 {
290 if (status_ == I_STATUS_DRAINING) {
291 status_ = I_STATUS_STARTED;
292 stateListener->OnOperationHandled(DRAIN_STREAM, 0);
293 }
294 afterDrain = true;
295 }
296
HandleOperationStarted()297 void RendererInServer::HandleOperationStarted()
298 {
299 CHECK_AND_RETURN_LOG(playerDfx_ != nullptr, "nullptr");
300 CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
301 "stream status is nullptr");
302 if (standByEnable_) {
303 standByEnable_ = false;
304 AUDIO_INFO_LOG("%{public}u recv stand-by started", streamIndex_);
305 audioServerBuffer_->GetStreamStatus()->store(STREAM_RUNNING);
306 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
307 }
308 CheckAndWriterRenderStreamStandbySysEvent(false);
309 status_ = I_STATUS_STARTED;
310 startedTime_ = ClockTime::GetCurNano();
311
312 lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
313 std::chrono::system_clock::now().time_since_epoch()).count();
314 lastWriteFrame_ = static_cast<int64_t>(audioServerBuffer_->GetCurReadFrame());
315 lastWriteMuteFrame_ = 0;
316 }
317
318 // LCOV_EXCL_START
OnStatusUpdateSub(IOperation operation)319 void RendererInServer::OnStatusUpdateSub(IOperation operation)
320 {
321 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
322 CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr!");
323 int32_t engineFlag = GetEngineFlag();
324 switch (operation) {
325 case OPERATION_RELEASED:
326 stateListener->OnOperationHandled(RELEASE_STREAM, 0);
327 status_ = I_STATUS_RELEASED;
328 break;
329 case OPERATION_UNDERRUN:
330 AUDIO_INFO_LOG("Underrun: audioServerBuffer_->GetWritableDataFrames(): %{public}d",
331 audioServerBuffer_->GetWritableDataFrames());
332 if (audioServerBuffer_->GetWritableDataFrames() ==
333 static_cast<int32_t>(DEFAULT_SPAN_SIZE * spanSizeInFrame_)) {
334 AUDIO_INFO_LOG("Buffer is empty");
335 needForceWrite_ = 0;
336 } else {
337 AUDIO_INFO_LOG("Buffer is not empty");
338 std::unique_lock lock(writeLock_, std::try_to_lock);
339 if (lock.owns_lock()) {
340 WriteData();
341 }
342 }
343 break;
344 case OPERATION_UNDERFLOW:
345 if (ClockTime::GetCurNano() - startedTime_ > START_MIN_COST) {
346 underrunCount_++;
347 audioServerBuffer_->SetUnderrunCount(underrunCount_);
348 }
349 StandByCheck(); // if stand by is enbaled here, stream will be paused and not recv UNDERFLOW any more.
350 break;
351 case OPERATION_SET_OFFLOAD_ENABLE:
352 case OPERATION_UNSET_OFFLOAD_ENABLE:
353 offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false;
354 if (engineFlag == 1) {
355 ReConfigDupStreamCallback();
356 }
357 stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0);
358 break;
359 default:
360 AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
361 status_ = I_STATUS_INVALID;
362 }
363 }
364 // LCOV_EXCL_STOP
365
ReConfigDupStreamCallback()366 void RendererInServer::ReConfigDupStreamCallback()
367 {
368 size_t dupTotalSizeInFrameTemp_ = 0;
369
370 if (offloadEnable_ == true) {
371 dupTotalSizeInFrameTemp_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN);
372 } else {
373 dupTotalSizeInFrameTemp_ = dupSpanSizeInFrame_ * (DUP_COMMON_LEN / DUP_DEFAULT_LEN);
374 }
375 AUDIO_INFO_LOG("dupTotalSizeInFrameTemp_: %{public}zu, dupTotalSizeInFrame_: %{public}zu",
376 dupTotalSizeInFrameTemp_, dupTotalSizeInFrame_);
377 if (dupTotalSizeInFrameTemp_ == dupTotalSizeInFrame_) {
378 return;
379 }
380 dupTotalSizeInFrame_ = dupTotalSizeInFrameTemp_;
381 std::lock_guard<std::mutex> lock(dupMutex_);
382 for (auto it = innerCapIdToDupStreamCallbackMap_.begin(); it != innerCapIdToDupStreamCallbackMap_.end(); ++it) {
383 if (captureInfos_[(*it).first].dupStream != nullptr && (*it).second != nullptr &&
384 (*it).second->GetDupRingBuffer() != nullptr) {
385 (*it).second->GetDupRingBuffer()->ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false);
386 }
387 }
388 }
389
StandByCheck()390 void RendererInServer::StandByCheck()
391 {
392 Trace trace(traceTag_ + " StandByCheck:standByCounter_:" + std::to_string(standByCounter_.load()));
393
394 // msdp wait for uncertain time when waiting for bt reply, which may case stream change into standby mode.
395 // if client writes date when stream is changing into standby mode, it would cause drain fail problems.
396 // msdp promises to call api correctly to avoid power problems
397 if (processConfig_.rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_ULTRASONIC) {
398 return;
399 }
400 AUDIO_INFO_LOG("sessionId:%{public}u standByCounter_:%{public}u standByEnable_:%{public}s ", streamIndex_,
401 standByCounter_.load(), (standByEnable_ ? "true" : "false"));
402
403 // direct standBy need not in here
404 if (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) {
405 return;
406 }
407
408 if (standByEnable_) {
409 return;
410 }
411 standByCounter_++;
412 audioStreamChecker_->RecordNodataFrame();
413 if (!ShouldEnableStandBy()) {
414 return;
415 }
416
417 // call enable stand by
418 standByEnable_ = true;
419 RecordStandbyTime(standByEnable_, true);
420 enterStandbyTime_ = ClockTime::GetCurNano();
421 // PaAdapterManager::PauseRender will hold mutex, may cause dead lock with pa_lock
422 if (managerType_ == PLAYBACK) {
423 stream_->Pause(true);
424 }
425
426 if (playerDfx_) {
427 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_BEGIN);
428 }
429 }
430
ShouldEnableStandBy()431 bool RendererInServer::ShouldEnableStandBy()
432 {
433 int64_t timeCost = ClockTime::GetCurNano() - lastWriteTime_;
434 uint32_t maxStandByCounter = 50; // for 20ms, 50 * 20 = 1000ms
435 int64_t timeLimit = 1000000000; // 1s
436 if (offloadEnable_) {
437 maxStandByCounter = 400; // for 20ms, 50 * 400 = 8000ms
438 timeLimit = 8 * AUDIO_NS_PER_SECOND; // for 20ms 8s
439 }
440 if (standByCounter_ >= maxStandByCounter && timeCost >= timeLimit) {
441 AUDIO_INFO_LOG("sessionId:%{public}u reach the limit of stand by: %{public}u time:%{public}" PRId64"ns",
442 streamIndex_, standByCounter_.load(), timeCost);
443 return true;
444 }
445 return false;
446 }
447
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)448 int32_t RendererInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
449 {
450 Trace trace("RendererInServer::GetStandbyStatus:" + std::to_string(streamIndex_) + (standByEnable_ ? " Enabled" :
451 "Disabled"));
452 isStandby = standByEnable_;
453 if (isStandby) {
454 enterStandbyTime = enterStandbyTime_;
455 } else {
456 enterStandbyTime = 0;
457 }
458 return SUCCESS;
459 }
460
HandleOperationFlushed()461 void RendererInServer::HandleOperationFlushed()
462 {
463 switch (status_) {
464 case I_STATUS_FLUSHING_WHEN_STARTED:
465 status_ = I_STATUS_STARTED;
466 break;
467 case I_STATUS_FLUSHING_WHEN_PAUSED:
468 status_ = I_STATUS_PAUSED;
469 break;
470 case I_STATUS_FLUSHING_WHEN_STOPPED:
471 status_ = I_STATUS_STOPPED;
472 break;
473 default:
474 AUDIO_WARNING_LOG("Invalid status before flusing");
475 }
476 }
477
HandleOperationStopped(RendererStage stage)478 void RendererInServer::HandleOperationStopped(RendererStage stage)
479 {
480 CHECK_AND_RETURN_LOG(audioServerBuffer_ != nullptr && playerDfx_ != nullptr, "nullptr");
481 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
482 std::chrono::system_clock::now().time_since_epoch()).count();
483 lastWriteFrame_ = static_cast<int64_t>(audioServerBuffer_->GetCurReadFrame()) - lastWriteFrame_;
484 playerDfx_->WriteDfxStopMsg(streamIndex_, stage,
485 {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
486 }
487
DequeueBuffer(size_t length)488 BufferDesc RendererInServer::DequeueBuffer(size_t length)
489 {
490 return stream_->DequeueBuffer(length);
491 }
492
DoFadingOut(RingBufferWrapper & bufferDesc)493 void RendererInServer::DoFadingOut(RingBufferWrapper& bufferDesc)
494 {
495 std::lock_guard<std::mutex> lock(fadeoutLock_);
496 if (fadeoutFlag_ == DO_FADINGOUT) {
497 AUDIO_INFO_LOG("enter. format:%{public}u", processConfig_.streamInfo.format);
498 AudioChannel channel = processConfig_.streamInfo.channels;
499 ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, FADINGOUT_BEGIN, FADINGOUT_END);
500 int32_t ret = VolumeTools::Process(bufferDesc, processConfig_.streamInfo.format, mapVols);
501 if (ret != SUCCESS) {
502 AUDIO_WARNING_LOG("VolumeTools::Process failed: %{public}d", ret);
503 }
504 fadeoutFlag_ = FADING_OUT_DONE;
505 AUDIO_INFO_LOG("fadeoutFlag_ = FADING_OUT_DONE");
506 }
507 }
508
IsInvalidBuffer(uint8_t * buffer,size_t bufferSize)509 bool RendererInServer::IsInvalidBuffer(uint8_t *buffer, size_t bufferSize)
510 {
511 bool isInvalid = false;
512 uint8_t ui8Data = 0;
513 int16_t i16Data = 0;
514 switch (processConfig_.streamInfo.format) {
515 case SAMPLE_U8:
516 CHECK_AND_RETURN_RET_LOG(bufferSize > 0, false, "buffer size is too small");
517 ui8Data = *buffer;
518 isInvalid = ui8Data == 0;
519 break;
520 case SAMPLE_S16LE:
521 CHECK_AND_RETURN_RET_LOG(bufferSize > 1, false, "buffer size is too small");
522 i16Data = *(reinterpret_cast<const int16_t*>(buffer));
523 isInvalid = i16Data == 0;
524 break;
525 default:
526 break;
527 }
528 return isInvalid;
529 }
530
WriteMuteDataSysEvent(BufferDesc & bufferDesc)531 void RendererInServer::WriteMuteDataSysEvent(BufferDesc &bufferDesc)
532 {
533 int64_t muteFrameCnt = 0;
534 VolumeTools::CalcMuteFrame(bufferDesc, processConfig_.streamInfo, traceTag_, volumeDataCount_, muteFrameCnt);
535 lastWriteMuteFrame_ += muteFrameCnt;
536 if (volumeDataCount_ < 0) {
537 audioStreamChecker_->RecordMuteFrame();
538 }
539 if (silentModeAndMixWithOthers_) {
540 return;
541 }
542 if (IsInvalidBuffer(bufferDesc.buffer, bufferDesc.bufLength)) {
543 if (startMuteTime_ == 0) {
544 startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
545 }
546 std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
547 if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isInSilentState_) {
548 isInSilentState_ = true;
549 AUDIO_WARNING_LOG("write invalid data for some time in server");
550
551 std::unordered_map<std::string, std::string> payload;
552 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
553 payload["sessionId"] = std::to_string(streamIndex_);
554 payload["isSilent"] = std::to_string(true);
555 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
556 }
557 } else {
558 if (startMuteTime_ != 0) {
559 startMuteTime_ = 0;
560 }
561 if (isInSilentState_) {
562 AUDIO_WARNING_LOG("begin write valid data in server");
563 isInSilentState_ = false;
564
565 std::unordered_map<std::string, std::string> payload;
566 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
567 payload["sessionId"] = std::to_string(streamIndex_);
568 payload["isSilent"] = std::to_string(false);
569 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
570 }
571 }
572
573 if ((!latestForWorkgroupInited_) || (latestForWorkgroup_.isInSilentState != isInSilentState_)) {
574 AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
575 }
576 }
577
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)578 void RendererInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
579 {
580 #ifdef RESSCHE_ENABLE
581 AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
582 ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
583 #endif
584 }
585
VolumeHandle(BufferDesc & desc)586 void RendererInServer::VolumeHandle(BufferDesc &desc)
587 {
588 // volume process in server
589 if (audioServerBuffer_ == nullptr) {
590 AUDIO_WARNING_LOG("buffer in not inited");
591 return;
592 }
593 float applyVolume = 0.0f;
594 if (muteFlag_) {
595 applyVolume = 0.0f;
596 } else {
597 applyVolume = audioServerBuffer_->GetStreamVolume();
598 }
599 float duckVolume = audioServerBuffer_->GetDuckFactor();
600 float muteVolume = audioServerBuffer_->GetMuteFactor();
601 if (!IsVolumeSame(MAX_FLOAT_VOLUME, lowPowerVolume_, AUDIO_VOLOMUE_EPSILON)) {
602 applyVolume *= lowPowerVolume_;
603 }
604 if (!IsVolumeSame(MAX_FLOAT_VOLUME, duckVolume, AUDIO_VOLOMUE_EPSILON)) {
605 applyVolume *= duckVolume;
606 }
607 if (!IsVolumeSame(MAX_FLOAT_VOLUME, muteVolume, AUDIO_VOLOMUE_EPSILON)) {
608 applyVolume *= muteVolume;
609 }
610
611 if (silentModeAndMixWithOthers_) {
612 applyVolume = 0.0f;
613 }
614
615 //in plan: put system volume handle here
616 if (!IsVolumeSame(MAX_FLOAT_VOLUME, applyVolume, AUDIO_VOLOMUE_EPSILON) ||
617 !IsVolumeSame(oldAppliedVolume_, applyVolume, AUDIO_VOLOMUE_EPSILON)) {
618 Trace traceVol("RendererInServer::VolumeTools::Process " + std::to_string(oldAppliedVolume_) + "~" +
619 std::to_string(applyVolume));
620 AudioChannel channel = processConfig_.streamInfo.channels;
621 ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, oldAppliedVolume_, applyVolume);
622 int32_t volRet = VolumeTools::Process(desc, processConfig_.streamInfo.format, mapVols);
623 oldAppliedVolume_ = applyVolume;
624 if (volRet != SUCCESS) {
625 AUDIO_WARNING_LOG("VolumeTools::Process error: %{public}d", volRet);
626 }
627 }
628 }
629
PrepareOutputBuffer(const RingBufferWrapper & ringBufferDesc)630 BufferDesc RendererInServer::PrepareOutputBuffer(const RingBufferWrapper& ringBufferDesc)
631 {
632 BufferDesc bufferDesc;
633 if (ringBufferDesc.basicBufferDescs[0].bufLength >= ringBufferDesc.dataLength) {
634 bufferDesc.buffer = ringBufferDesc.basicBufferDescs[0].buffer;
635 bufferDesc.bufLength = ringBufferDesc.dataLength;
636 bufferDesc.dataLength = ringBufferDesc.dataLength;
637 } else {
638 rendererTmpBuffer_.resize(ringBufferDesc.dataLength);
639 RingBufferWrapper tmpWrapper;
640 tmpWrapper.dataLength = ringBufferDesc.dataLength;
641 tmpWrapper.basicBufferDescs[0].buffer = rendererTmpBuffer_.data();
642 tmpWrapper.basicBufferDescs[0].bufLength = ringBufferDesc.dataLength;
643 tmpWrapper.CopyInputBufferValueToCurBuffer(ringBufferDesc);
644
645 bufferDesc.buffer = rendererTmpBuffer_.data();
646 bufferDesc.bufLength = ringBufferDesc.dataLength;
647 bufferDesc.dataLength = ringBufferDesc.dataLength;
648 }
649 return bufferDesc;
650 }
651
WriteData()652 int32_t RendererInServer::WriteData()
653 {
654 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
655 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
656 Trace trace1(traceTag_ + " WriteData"); // RendererInServer::sessionid:100001 WriteData
657 if (currentReadFrame >= currentWriteFrame) {
658 Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
659 if (!offloadEnable_) {
660 CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
661 "invalid write and read position.");
662 uint64_t dataSize = currentWriteFrame - currentReadFrame;
663 AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
664 streamIndex_, dataSize);
665 }
666 return ERR_OPERATION_FAILED;
667 }
668
669 RingBufferWrapper ringBufferDesc; // will be changed in GetReadbuffer
670 if (audioServerBuffer_->GetAllReadableBufferFromPosFrame(currentReadFrame, ringBufferDesc) == SUCCESS) {
671 ringBufferDesc.dataLength = std::min(ringBufferDesc.dataLength, spanSizeInByte_);
672 if (ringBufferDesc.dataLength == 0) {
673 AUDIO_ERR_LOG("not enough data!");
674 return ERR_INVALID_PARAM;
675 }
676 uint64_t durationMs = ((byteSizePerFrame_ * processConfig_.streamInfo.samplingRate) == 0) ? 0
677 : ((MSEC_PER_SEC * processConfig_.rendererInfo.expectedPlaybackDurationBytes) /
678 (byteSizePerFrame_ * processConfig_.streamInfo.samplingRate));
679 if (processConfig_.streamType != STREAM_ULTRASONIC && (GetFadeStrategy(durationMs) == FADE_STRATEGY_DEFAULT)) {
680 if (currentReadFrame + spanSizeInFrame_ >= currentWriteFrame) {
681 DoFadingOut(ringBufferDesc);
682 }
683 }
684
685 BufferDesc bufferDesc = PrepareOutputBuffer(ringBufferDesc);
686 stream_->EnqueueBuffer(bufferDesc);
687 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
688 DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
689 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
690 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
691 }
692
693 OtherStreamEnqueue(bufferDesc);
694
695 WriteMuteDataSysEvent(bufferDesc);
696 ringBufferDesc.SetBuffersValueWithSpecifyDataLen(0); // clear is needed for reuse.
697 // Client may write the buffer immediately after SetCurReadFrame, so put memset_s before it!
698 uint64_t nextReadFrame = currentReadFrame + (ringBufferDesc.dataLength / byteSizePerFrame_);
699 audioServerBuffer_->SetCurReadFrame(nextReadFrame);
700 }
701 standByCounter_ = 0;
702 lastWriteTime_ = ClockTime::GetCurNano();
703 return SUCCESS;
704 }
705
GetAvailableSize(size_t & length)706 int32_t RendererInServer::GetAvailableSize(size_t &length)
707 {
708 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
709 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
710 if (currentWriteFrame < currentReadFrame) {
711 return ERROR;
712 }
713
714 length = static_cast<size_t>((currentWriteFrame - currentReadFrame) * byteSizePerFrame_);
715 return SUCCESS;
716 }
717
CopyDataToInputBuffer(int8_t * inputData,size_t requestDataLen,const RingBufferWrapper & ringBufferDesc)718 void RendererInServer::CopyDataToInputBuffer(int8_t* inputData, size_t requestDataLen,
719 const RingBufferWrapper& ringBufferDesc)
720 {
721 RingBufferWrapper wrapperInputData = {
722 .basicBufferDescs = {{
723 {reinterpret_cast<uint8_t*>(inputData), requestDataLen},
724 {}
725 }},
726 .dataLength = requestDataLen
727 };
728
729 CHECK_AND_RETURN_LOG(wrapperInputData.CopyInputBufferValueToCurBuffer(ringBufferDesc) == 0,
730 "memcpy error");
731 }
732
ProcessFadeOutIfNeeded(RingBufferWrapper & ringBufferDesc,uint64_t currentReadFrame,uint64_t currentWriteFrame,size_t requestDataInFrame)733 void RendererInServer::ProcessFadeOutIfNeeded(RingBufferWrapper& ringBufferDesc,
734 uint64_t currentReadFrame, uint64_t currentWriteFrame,
735 size_t requestDataInFrame)
736 {
737 if (processConfig_.streamType != STREAM_ULTRASONIC &&
738 currentReadFrame + requestDataInFrame == currentWriteFrame) {
739 DoFadingOut(ringBufferDesc);
740 }
741 }
742
OnWriteData(int8_t * inputData,size_t requestDataLen)743 int32_t RendererInServer::OnWriteData(int8_t *inputData, size_t requestDataLen)
744 {
745 size_t requestDataInFrame = requestDataLen / byteSizePerFrame_;
746 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
747 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
748 Trace trace1(traceTag_ + " OnWriteData"); // RendererInServer::sessionid:100001 WriteData
749 if (requestDataLen == 0 || currentReadFrame + requestDataInFrame > currentWriteFrame) {
750 Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
751 if (!offloadEnable_) {
752 CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
753 "invalid write and read position.");
754 uint64_t dataSize = currentWriteFrame - currentReadFrame;
755 AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
756 streamIndex_, dataSize);
757 }
758 return ERR_OPERATION_FAILED;
759 }
760
761 RingBufferWrapper ringBufferDesc; // will be changed in GetReadbuffer
762 if (audioServerBuffer_->GetAllReadableBufferFromPosFrame(currentReadFrame, ringBufferDesc) == SUCCESS) {
763 if (ringBufferDesc.dataLength < requestDataLen) {
764 AUDIO_ERR_LOG("data not enouth");
765 return ERR_INVALID_PARAM;
766 }
767 ringBufferDesc.dataLength = requestDataLen;
768 ProcessFadeOutIfNeeded(ringBufferDesc, currentReadFrame, currentWriteFrame, requestDataInFrame);
769
770 CopyDataToInputBuffer(inputData, requestDataLen, ringBufferDesc);
771
772 BufferDesc bufferDesc = {
773 .buffer = reinterpret_cast<uint8_t*>(inputData),
774 .bufLength = requestDataLen,
775 .dataLength = requestDataLen
776 };
777
778 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
779 DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
780 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
781 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
782 }
783
784 OtherStreamEnqueue(bufferDesc);
785 audioStreamChecker_->RecordNormalFrame();
786 WriteMuteDataSysEvent(bufferDesc);
787 ringBufferDesc.SetBuffersValueWithSpecifyDataLen(0); // clear is needed for reuse.
788 uint64_t nextReadFrame = currentReadFrame + requestDataInFrame;
789 audioServerBuffer_->SetCurReadFrame(nextReadFrame);
790 } else {
791 Trace trace3("RendererInServer::WriteData GetReadbuffer failed");
792 }
793 standByCounter_ = 0;
794 lastWriteTime_ = ClockTime::GetCurNano();
795 return SUCCESS;
796 }
797
OtherStreamEnqueue(const BufferDesc & bufferDesc)798 void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc)
799 {
800 {
801 // for inner capture
802 std::lock_guard<std::mutex> captureLock(dupMutex_);
803 for (auto &capInfo : captureInfos_) {
804 InnerCaptureOtherStream(bufferDesc, capInfo.second, capInfo.first);
805 }
806 }
807 // for dual tone
808 if (isDualToneEnabled_) {
809 Trace traceDup("RendererInServer::WriteData DualToneSteam write");
810 std::lock_guard<std::mutex> lock(dualToneMutex_);
811 if (dualToneStream_ != nullptr) {
812 dualToneStream_->EnqueueBuffer(bufferDesc); // what if enqueue fail?
813 }
814 }
815 }
816
InnerCaptureEnqueueBuffer(const BufferDesc & bufferDesc,CaptureInfo & captureInfo,int32_t innerCapId)817 void RendererInServer::InnerCaptureEnqueueBuffer(const BufferDesc &bufferDesc, CaptureInfo &captureInfo,
818 int32_t innerCapId)
819 {
820 int32_t engineFlag = GetEngineFlag();
821 if (renderEmptyCountForInnerCap_ > 0) {
822 size_t emptyBufferSize = static_cast<size_t>(renderEmptyCountForInnerCap_) * spanSizeInByte_;
823 auto buffer = std::make_unique<uint8_t []>(emptyBufferSize);
824 BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize};
825 memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength);
826 if (engineFlag == 1) {
827 WriteDupBufferInner(emptyBufferDesc, innerCapId);
828 } else {
829 captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc);
830 }
831 renderEmptyCountForInnerCap_ = 0;
832 }
833 if (engineFlag == 1) {
834 AUDIO_INFO_LOG("OtherStreamEnqueue running");
835 WriteDupBufferInner(bufferDesc, innerCapId);
836 } else {
837 captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail?
838 }
839 }
840
InnerCaptureOtherStream(const BufferDesc & bufferDesc,CaptureInfo & captureInfo,int32_t innerCapId)841 void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo,
842 int32_t innerCapId)
843 {
844 if (captureInfo.isInnerCapEnabled) {
845 Trace traceDup("RendererInServer::WriteData DupSteam write");
846 if (captureInfo.dupStream != nullptr) {
847 InnerCaptureEnqueueBuffer(bufferDesc, captureInfo, innerCapId);
848 }
849 }
850 }
851
WriteEmptyData()852 void RendererInServer::WriteEmptyData()
853 {
854 Trace trace("RendererInServer::WriteEmptyData");
855 AUDIO_WARNING_LOG("Underrun, write empty data");
856 BufferDesc bufferDesc = stream_->DequeueBuffer(spanSizeInByte_);
857 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
858 stream_->EnqueueBuffer(bufferDesc);
859 return;
860 }
861
OnWriteData(size_t length)862 int32_t RendererInServer::OnWriteData(size_t length)
863 {
864 Trace trace("RendererInServer::OnWriteData length " + std::to_string(length));
865 bool mayNeedForceWrite = false;
866 std::unique_lock lock(writeLock_, std::defer_lock);
867 if (lock.try_lock()) {
868 // length unit is bytes, using spanSizeInByte_
869 if (spanSizeInByte_ <= 0) {
870 return ERR_WRITE_FAILED;
871 }
872 for (size_t i = 0; i < length / spanSizeInByte_; i++) {
873 mayNeedForceWrite = WriteData() != SUCCESS || mayNeedForceWrite;
874 }
875 lock.unlock();
876 } else {
877 mayNeedForceWrite = true;
878 }
879
880 size_t maxEmptyCount = 1;
881 size_t writableSize = stream_->GetWritableSize();
882 if (mayNeedForceWrite && writableSize >= spanSizeInByte_ * maxEmptyCount) {
883 AUDIO_DEBUG_LOG("Server need force write to recycle callback");
884 needForceWrite_ =
885 writableSize / spanSizeInByte_ > 3 ? 0 : 3 - writableSize / spanSizeInByte_; // 3 is maxlength - 1
886 }
887
888 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
889 audioServerBuffer_->SetHandleInfo(currentReadFrame, ClockTime::GetCurNano() + MOCK_LATENCY);
890
891 if (mayNeedForceWrite) {
892 return ERR_RENDERER_IN_SERVER_UNDERRUN;
893 }
894
895 return SUCCESS;
896 }
897
898 // Call WriteData will hold mainloop lock in EnqueueBuffer, we should not lock a mutex in WriteData while OnWriteData is
899 // called with mainloop locking.
UpdateWriteIndex()900 int32_t RendererInServer::UpdateWriteIndex()
901 {
902 Trace trace("RendererInServer::UpdateWriteIndex needForceWrite" + std::to_string(needForceWrite_));
903 if (managerType_ != PLAYBACK) {
904 IStreamManager::GetPlaybackManager(managerType_).TriggerStartIfNecessary();
905 }
906 std::unique_lock lock(writeLock_, std::defer_lock);
907 if (needForceWrite_ < 3 && stream_->GetWritableSize() >= spanSizeInByte_) { // 3 is maxlength - 1
908 if (lock.try_lock()) {
909 AUDIO_DEBUG_LOG("Start force write data");
910 int32_t ret = WriteData();
911 if (ret == SUCCESS) {
912 needForceWrite_++;
913 }
914 lock.unlock();
915 }
916 }
917
918 int32_t engineFlag = GetEngineFlag();
919 if (engineFlag != 1) {
920 if (afterDrain == true) {
921 if (lock.try_lock()) {
922 afterDrain = false;
923 AUDIO_DEBUG_LOG("After drain, start write data");
924 WriteData();
925 lock.unlock();
926 }
927 }
928 }
929 return SUCCESS;
930 }
931
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)932 int32_t RendererInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
933 {
934 AUDIO_ERR_LOG("Not support");
935 return SUCCESS;
936 }
937
ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> & buffer,uint32_t & spanSizeInFrame,uint64_t & engineTotalSizeInFrame)938 int32_t RendererInServer::ResolveBufferBaseAndGetServerSpanSize(std::shared_ptr<OHAudioBufferBase> &buffer,
939 uint32_t &spanSizeInFrame, uint64_t &engineTotalSizeInFrame)
940 {
941 buffer = audioServerBuffer_;
942 spanSizeInFrame = spanSizeInFrame_;
943 engineTotalSizeInFrame = engineTotalSizeInFrame_;
944 return SUCCESS;
945 }
946
GetSessionId(uint32_t & sessionId)947 int32_t RendererInServer::GetSessionId(uint32_t &sessionId)
948 {
949 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
950 sessionId = streamIndex_;
951 CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
952 sessionId);
953
954 return SUCCESS;
955 }
956
Start()957 int32_t RendererInServer::Start()
958 {
959 AudioXCollie audioXCollie(
960 "RendererInServer::Start", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
961 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
962 int32_t ret = StartInner();
963 RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
964 if (playerDfx_) {
965 playerDfx_->WriteDfxStartMsg(streamIndex_, stage, sourceDuration_, processConfig_);
966 }
967 if (ret == SUCCESS) {
968 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, true);
969 }
970 return ret;
971 }
972
StartInnerDuringStandby()973 int32_t RendererInServer::StartInnerDuringStandby()
974 {
975 int32_t ret = 0;
976 AUDIO_INFO_LOG("sessionId: %{public}u call to exit stand by!", streamIndex_);
977 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr, ERR_OPERATION_FAILED, "null stream");
978 standByCounter_ = 0;
979 startedTime_ = ClockTime::GetCurNano();
980 audioServerBuffer_->GetStreamStatus()->store(STREAM_STARTING);
981 ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_START);
982 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy start client failed, reason: %{public}d", ret);
983 ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
984 IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
985 RecordStandbyTime(true, false);
986 return ret;
987 }
988
StartInner()989 int32_t RendererInServer::StartInner()
990 {
991 AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_);
992 int32_t ret = 0;
993 if (standByEnable_) {
994 return StartInnerDuringStandby();
995 } else {
996 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_START, false);
997 }
998 needForceWrite_ = 0;
999 std::unique_lock<std::mutex> lock(statusLock_);
1000 if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
1001 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1002 return ERR_ILLEGAL_STATE;
1003 }
1004 status_ = I_STATUS_STARTING;
1005 std::unique_lock<std::mutex> fadeLock(fadeoutLock_);
1006 AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
1007 fadeoutFlag_ = NO_FADING;
1008 fadeLock.unlock();
1009 ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_START);
1010 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy start client failed, reason: %{public}d", ret);
1011 ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1012 IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
1013 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
1014
1015 startedTime_ = ClockTime::GetCurNano();
1016 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
1017 int64_t tempTime = ClockTime::GetCurNano() + MOCK_LATENCY;
1018 audioServerBuffer_->SetHandleInfo(currentReadFrame, tempTime);
1019 AUDIO_INFO_LOG("Server update position %{public}" PRIu64" time%{public} " PRId64".", currentReadFrame, tempTime);
1020 resetTime_ = true;
1021
1022 std::unique_lock<std::mutex> dupLock(dupMutex_);
1023 for (auto &capInfo : captureInfos_) {
1024 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1025 capInfo.second.dupStream->Start();
1026 }
1027 }
1028 dupLock.unlock();
1029 enterStandbyTime_ = 0;
1030
1031 dualToneStreamInStart();
1032 AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(streamIndex_, processConfig_.appInfo.appTokenId);
1033 return SUCCESS;
1034 }
1035
dualToneStreamInStart()1036 void RendererInServer::dualToneStreamInStart()
1037 {
1038 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1039 //Joint judgment ensures that there is a double ring and there is a stream to enter.
1040 stream_->GetAudioEffectMode(effectModeWhenDual_);
1041 stream_->SetAudioEffectMode(EFFECT_NONE);
1042 std::lock_guard<std::mutex> lock(dualToneMutex_);
1043 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1044 if (dualToneStream_ != nullptr) {
1045 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1046 //modified elsewhere, it was decided again after the lock was awarded.
1047 dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1048 dualToneStream_->Start();
1049 }
1050 }
1051 }
1052
RecordStandbyTime(bool isStandby,bool isStandbyStart)1053 void RendererInServer::RecordStandbyTime(bool isStandby, bool isStandbyStart)
1054 {
1055 if (!isStandby) {
1056 AUDIO_DEBUG_LOG("Not in standby, no need record time");
1057 return;
1058 }
1059 audioStreamChecker_->RecordStandbyTime(isStandbyStart);
1060 }
1061
Pause()1062 int32_t RendererInServer::Pause()
1063 {
1064 AUDIO_INFO_LOG("Pause.");
1065 AudioXCollie audioXCollie("RendererInServer::Pause", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1066 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1067 std::unique_lock<std::mutex> lock(statusLock_);
1068 CHECK_AND_RETURN_RET_LOG(status_ == I_STATUS_STARTED, ERR_ILLEGAL_STATE,
1069 "RendererInServer::Pause failed, Illegal state: %{public}u", status_.load());
1070 status_ = I_STATUS_PAUSING;
1071 bool isStandbyTmp = false;
1072 if (standByEnable_) {
1073 AUDIO_INFO_LOG("sessionId: %{public}u call Pause while stand by", streamIndex_);
1074 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
1075 ERR_OPERATION_FAILED, "stream status is nullptr");
1076 standByEnable_ = false;
1077 enterStandbyTime_ = 0;
1078 audioServerBuffer_->GetStreamStatus()->store(STREAM_PAUSED);
1079 if (playerDfx_) {
1080 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
1081 }
1082 isStandbyTmp = true;
1083 }
1084 standByCounter_ = 0;
1085 GetEAC3ControlParam();
1086 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1087 IStreamManager::GetPlaybackManager(managerType_).PauseRender(streamIndex_) : stream_->Pause();
1088 {
1089 std::lock_guard<std::mutex> lock(dupMutex_);
1090 for (auto &capInfo : captureInfos_) {
1091 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1092 capInfo.second.dupStream->Pause();
1093 }
1094 }
1095 }
1096 pausedTime_ = ClockTime::GetCurNano();
1097 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1098 //Joint judgment ensures that there is a double ring and there is a stream to enter.
1099 stream_->SetAudioEffectMode(effectModeWhenDual_);
1100 std::lock_guard<std::mutex> lock(dualToneMutex_);
1101 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1102 if (dualToneStream_ != nullptr) {
1103 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1104 //modified elsewhere, it was decided again after the lock was awarded.
1105 dualToneStream_->Pause();
1106 }
1107 }
1108 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
1109 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_PAUSE);
1110 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_PAUSE, isStandbyTmp);
1111 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1112 AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(streamIndex_);
1113 return SUCCESS;
1114 }
1115
FlushOhAudioBuffer()1116 int32_t RendererInServer::FlushOhAudioBuffer()
1117 {
1118 std::lock_guard writeLock(writeLock_);
1119 // Flush buffer of audio server
1120 uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
1121 uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
1122 if (readFrame >= writeFrame) {
1123 AUDIO_ERR_LOG("readFrame: %{public}" PRIu64 " writeFrame: %{public}" PRIu64 "", readFrame, writeFrame);
1124 return ERR_ILLEGAL_STATE;
1125 }
1126 RingBufferWrapper buffer;
1127 int32_t readResult = audioServerBuffer_->GetAllReadableBuffer(buffer);
1128 if (readResult != 0) {
1129 return ERR_OPERATION_FAILED;
1130 }
1131 buffer.SetBuffersValueWithSpecifyDataLen(0);
1132 AUDIO_INFO_LOG("On flush, read frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
1133 "writeFrame: %{public}" PRIu64 "", readFrame, spanSizeInFrame_, writeFrame);
1134 audioServerBuffer_->SetCurReadFrame(writeFrame);
1135
1136 return SUCCESS;
1137 }
1138
Flush()1139 int32_t RendererInServer::Flush()
1140 {
1141 AUDIO_PRERELEASE_LOGI("Flush.");
1142 AudioXCollie audioXCollie(
1143 "RendererInServer::Flush", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1144 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1145 Trace trace(traceTag_ + " Flush");
1146 std::unique_lock<std::mutex> lock(statusLock_);
1147 if (status_ == I_STATUS_STARTED) {
1148 status_ = I_STATUS_FLUSHING_WHEN_STARTED;
1149 } else if (status_ == I_STATUS_PAUSED) {
1150 status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
1151 } else if (status_ == I_STATUS_STOPPED) {
1152 status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
1153 } else {
1154 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1155 return ERR_ILLEGAL_STATE;
1156 }
1157
1158 FlushOhAudioBuffer();
1159
1160 flushedTime_ = ClockTime::GetCurNano();
1161 int ret = stream_->Flush();
1162 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
1163 {
1164 std::lock_guard<std::mutex> lock(dupMutex_);
1165 for (auto &capInfo : captureInfos_) {
1166 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1167 capInfo.second.dupStream->Flush();
1168 }
1169 }
1170 }
1171 if (isDualToneEnabled_) {
1172 std::lock_guard<std::mutex> lock(dualToneMutex_);
1173 if (dualToneStream_ != nullptr) {
1174 dualToneStream_->Flush();
1175 }
1176 }
1177 return SUCCESS;
1178 }
1179
DrainAudioBuffer()1180 int32_t RendererInServer::DrainAudioBuffer()
1181 {
1182 return SUCCESS;
1183 }
1184
Drain(bool stopFlag)1185 int32_t RendererInServer::Drain(bool stopFlag)
1186 {
1187 AudioXCollie audioXCollie(
1188 "RendererInServer::Drain", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1189 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1190 {
1191 std::unique_lock<std::mutex> lock(statusLock_);
1192 if (status_ != I_STATUS_STARTED) {
1193 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1194 return ERR_ILLEGAL_STATE;
1195 }
1196 status_ = I_STATUS_DRAINING;
1197 }
1198 AUDIO_INFO_LOG("Start drain. stopFlag:%{public}d", stopFlag);
1199 if (stopFlag) {
1200 std::lock_guard<std::mutex> lock(fadeoutLock_);
1201 AUDIO_INFO_LOG("fadeoutFlag_ = DO_FADINGOUT");
1202 fadeoutFlag_ = DO_FADINGOUT;
1203 }
1204 DrainAudioBuffer();
1205 drainedTime_ = ClockTime::GetCurNano();
1206 AudioPerformanceMonitor::GetInstance().StartSilenceMonitor(streamIndex_, processConfig_.appInfo.appTokenId);
1207 int ret = stream_->Drain(stopFlag);
1208 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Drain stream failed, reason: %{public}d", ret);
1209 {
1210 std::lock_guard<std::mutex> lock(dupMutex_);
1211 for (auto &capInfo : captureInfos_) {
1212 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1213 capInfo.second.dupStream->Drain(stopFlag);
1214 }
1215 }
1216 }
1217 if (isDualToneEnabled_) {
1218 std::lock_guard<std::mutex> lock(dualToneMutex_);
1219 if (dualToneStream_ != nullptr) {
1220 dualToneStream_->Drain(stopFlag);
1221 }
1222 }
1223 return SUCCESS;
1224 }
1225
Stop()1226 int32_t RendererInServer::Stop()
1227 {
1228 AUDIO_INFO_LOG("Stop.");
1229 AudioXCollie audioXCollie(
1230 "RendererInServer::Stop", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1231 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1232 {
1233 std::unique_lock<std::mutex> lock(statusLock_);
1234 if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED && status_ != I_STATUS_DRAINING &&
1235 status_ != I_STATUS_STARTING) {
1236 AUDIO_ERR_LOG("failed, Illegal state: %{public}u", status_.load());
1237 return ERR_ILLEGAL_STATE;
1238 }
1239 status_ = I_STATUS_STOPPING;
1240 }
1241 return StopInner();
1242 }
1243
StopInner()1244 int32_t RendererInServer::StopInner()
1245 {
1246 if (standByEnable_) {
1247 AUDIO_INFO_LOG("sessionId: %{public}u call Stop while stand by", streamIndex_);
1248 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
1249 ERR_OPERATION_FAILED, "stream status is nullptr");
1250 standByEnable_ = false;
1251 enterStandbyTime_ = 0;
1252 audioServerBuffer_->GetStreamStatus()->store(STREAM_STOPPED);
1253 if (playerDfx_) {
1254 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
1255 }
1256 }
1257 {
1258 std::lock_guard<std::mutex> lock(fadeoutLock_);
1259 AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
1260 fadeoutFlag_ = NO_FADING;
1261 }
1262 GetEAC3ControlParam();
1263 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK || managerType_ == EAC3_PLAYBACK) ?
1264 IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop();
1265 {
1266 std::lock_guard<std::mutex> lock(dupMutex_);
1267 for (auto &capInfo : captureInfos_) {
1268 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1269 capInfo.second.dupStream->Stop();
1270 }
1271 }
1272 }
1273 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
1274 //Joint judgment ensures that there is a double ring and there is a stream to enter.
1275 stream_->SetAudioEffectMode(effectModeWhenDual_);
1276 std::lock_guard<std::mutex> lock(dualToneMutex_);
1277 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1278 if (dualToneStream_ != nullptr) {
1279 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1280 //modified elsewhere, it was decided again after the lock was awarded.
1281 dualToneStream_->Stop();
1282 }
1283 }
1284 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
1285 CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_STOP);
1286 audioStreamChecker_->MonitorOnAllCallback(AUDIO_STREAM_STOP, false);
1287 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1288 AudioPerformanceMonitor::GetInstance().PauseSilenceMonitor(streamIndex_);
1289 return SUCCESS;
1290 }
1291
Release(bool isSwitchStream)1292 int32_t RendererInServer::Release(bool isSwitchStream)
1293 {
1294 AUDIO_INFO_LOG("Start release");
1295 AudioXCollie audioXCollie(
1296 "RendererInServer::Release", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1297 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1298 {
1299 std::unique_lock<std::mutex> lock(statusLock_);
1300 if (status_ == I_STATUS_RELEASED) {
1301 AUDIO_INFO_LOG("Already released");
1302 return SUCCESS;
1303 }
1304 }
1305
1306 if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1307 AudioService::GetInstance()->SetDecMaxRendererStreamCnt();
1308 AudioService::GetInstance()->CleanAppUseNumMap(processConfig_.appInfo.appUid);
1309 }
1310
1311 int32_t ret = CoreServiceHandler::GetInstance().UpdateSessionOperation(streamIndex_, SESSION_OPERATION_RELEASE);
1312 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Policy remove client failed, reason: %{public}d", ret);
1313 StreamDfxManager::GetInstance().CheckStreamOccupancy(streamIndex_, processConfig_, false);
1314 ret = IStreamManager::GetPlaybackManager(managerType_).ReleaseRender(streamIndex_);
1315
1316 AudioVolume::GetInstance()->RemoveStreamVolume(streamIndex_);
1317 AudioService::GetInstance()->RemoveRenderer(streamIndex_, isSwitchStream);
1318 if (ret < 0) {
1319 AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
1320 status_ = I_STATUS_INVALID;
1321 return ret;
1322 }
1323 if (status_ != I_STATUS_STOPPING &&
1324 status_ != I_STATUS_STOPPED) {
1325 HandleOperationStopped(RENDERER_STAGE_STOP_BY_RELEASE);
1326 }
1327 status_ = I_STATUS_RELEASED;
1328 DisableAllInnerCap();
1329 if (isDualToneEnabled_) {
1330 DisableDualTone();
1331 }
1332 return SUCCESS;
1333 }
1334
DisableAllInnerCap()1335 int32_t RendererInServer::DisableAllInnerCap()
1336 {
1337 std::lock_guard<std::mutex> lock(dupMutex_);
1338 for (auto &capInfo : captureInfos_) {
1339 if (capInfo.second.isInnerCapEnabled) {
1340 DisableInnerCapHandle(capInfo.first);
1341 }
1342 }
1343 captureInfos_.clear();
1344 return SUCCESS;
1345 }
1346
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)1347 int32_t RendererInServer::GetAudioTime(uint64_t &framePos, uint64_t ×tamp)
1348 {
1349 if (status_ == I_STATUS_STOPPED) {
1350 AUDIO_WARNING_LOG("Current status is stopped");
1351 return ERR_ILLEGAL_STATE;
1352 }
1353 stream_->GetStreamFramesWritten(framePos);
1354 stream_->GetCurrentTimeStamp(timestamp);
1355 if (resetTime_) {
1356 resetTime_ = false;
1357 resetTimestamp_ = timestamp;
1358 }
1359 return SUCCESS;
1360 }
1361
GetAudioPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency,int32_t base)1362 int32_t RendererInServer::GetAudioPosition(uint64_t &framePos, uint64_t ×tamp, uint64_t &latency, int32_t base)
1363 {
1364 if (status_ == I_STATUS_STOPPED) {
1365 AUDIO_PRERELEASE_LOGW("Current status is stopped");
1366 return ERR_ILLEGAL_STATE;
1367 }
1368 stream_->GetCurrentPosition(framePos, timestamp, latency, base);
1369 return SUCCESS;
1370 }
1371
GetSpeedPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency,int32_t base)1372 int32_t RendererInServer::GetSpeedPosition(uint64_t &framePos, uint64_t ×tamp, uint64_t &latency, int32_t base)
1373 {
1374 CHECK_AND_RETURN_RET_LOG(status_ != I_STATUS_STOPPED, ERR_ILLEGAL_STATE, "Current status is stopped");
1375 return stream_->GetSpeedPosition(framePos, timestamp, latency, base);
1376 }
1377
GetLatency(uint64_t & latency)1378 int32_t RendererInServer::GetLatency(uint64_t &latency)
1379 {
1380 std::unique_lock<std::mutex> lock(statusLock_);
1381 if (managerType_ == DIRECT_PLAYBACK) {
1382 latency = IStreamManager::GetPlaybackManager(managerType_).GetLatency();
1383 return SUCCESS;
1384 }
1385 return stream_->GetLatency(latency);
1386 }
1387
SetRate(int32_t rate)1388 int32_t RendererInServer::SetRate(int32_t rate)
1389 {
1390 return stream_->SetRate(rate);
1391 }
1392
SetLowPowerVolume(float volume)1393 int32_t RendererInServer::SetLowPowerVolume(float volume)
1394 {
1395 if (volume < MIN_FLOAT_VOLUME || volume > MAX_FLOAT_VOLUME) {
1396 AUDIO_ERR_LOG("invalid volume:%{public}f", volume);
1397 return ERR_INVALID_PARAM;
1398 }
1399 std::string currentTime = GetTime();
1400 AUDIO_INFO_LOG("SetLowPowerVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1401 volume, streamIndex_, currentTime.c_str());
1402 AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(volume, streamIndex_, currentTime,
1403 static_cast<uint32_t>(AdjustStreamVolume::LOW_POWER_VOLUME_INFO));
1404
1405 lowPowerVolume_ = volume;
1406 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(streamIndex_, volume);
1407 {
1408 std::lock_guard<std::mutex> lock(dupMutex_);
1409 for (auto &capInfo : captureInfos_) {
1410 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1411 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(
1412 capInfo.second.dupStream->GetStreamIndex(), volume);
1413 }
1414 }
1415 }
1416 if (isDualToneEnabled_) {
1417 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, volume);
1418 }
1419 if (offloadEnable_) {
1420 OffloadSetVolumeInner();
1421 }
1422 return SUCCESS;
1423 }
1424
GetLowPowerVolume(float & volume)1425 int32_t RendererInServer::GetLowPowerVolume(float &volume)
1426 {
1427 volume = lowPowerVolume_;
1428 return SUCCESS;
1429 }
1430
SetAudioEffectMode(int32_t effectMode)1431 int32_t RendererInServer::SetAudioEffectMode(int32_t effectMode)
1432 {
1433 if (isDualToneEnabled_) {
1434 effectModeWhenDual_ = effectMode;
1435 return SUCCESS;
1436 }
1437 return stream_->SetAudioEffectMode(effectMode);
1438 }
1439
GetAudioEffectMode(int32_t & effectMode)1440 int32_t RendererInServer::GetAudioEffectMode(int32_t &effectMode)
1441 {
1442 return stream_->GetAudioEffectMode(effectMode);
1443 }
1444
SetPrivacyType(int32_t privacyType)1445 int32_t RendererInServer::SetPrivacyType(int32_t privacyType)
1446 {
1447 return stream_->SetPrivacyType(privacyType);
1448 }
1449
GetPrivacyType(int32_t & privacyType)1450 int32_t RendererInServer::GetPrivacyType(int32_t &privacyType)
1451 {
1452 return stream_->GetPrivacyType(privacyType);
1453 }
1454
EnableInnerCap(int32_t innerCapId)1455 int32_t RendererInServer::EnableInnerCap(int32_t innerCapId)
1456 {
1457 // in plan
1458 int32_t ret = InitDupStream(innerCapId);
1459 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dup stream failed");
1460 return SUCCESS;
1461 }
1462
DisableInnerCap(int32_t innerCapId)1463 int32_t RendererInServer::DisableInnerCap(int32_t innerCapId)
1464 {
1465 std::lock_guard<std::mutex> lock(dupMutex_);
1466 if (!captureInfos_.count(innerCapId) || !captureInfos_[innerCapId].isInnerCapEnabled) {
1467 AUDIO_WARNING_LOG("InnerCap is already disabled.capId:%{public}d", innerCapId);
1468 return ERR_INVALID_OPERATION;
1469 }
1470 return DisableInnerCapHandle(innerCapId);
1471 }
1472
DisableInnerCapHandle(int32_t innerCapId)1473 int32_t RendererInServer::DisableInnerCapHandle(int32_t innerCapId)
1474 {
1475 captureInfos_[innerCapId].isInnerCapEnabled = false;
1476 AUDIO_INFO_LOG("Disable dup renderer %{public}u with status: %{public}d", streamIndex_, status_.load());
1477 // in plan: call stop?
1478 if (captureInfos_[innerCapId].dupStream != nullptr) {
1479 uint32_t dupStreamIndex = captureInfos_[innerCapId].dupStream->GetStreamIndex();
1480 IStreamManager::GetDupPlaybackManager().ReleaseRender(dupStreamIndex);
1481 AudioVolume::GetInstance()->RemoveStreamVolume(dupStreamIndex);
1482 captureInfos_[innerCapId].dupStream = nullptr;
1483 }
1484 int32_t engineFlag = GetEngineFlag();
1485 if (engineFlag == 1) {
1486 DumpFileUtil::CloseDumpFile(&dumpDupIn_);
1487 }
1488 return SUCCESS;
1489 }
1490
InitDupStream(int32_t innerCapId)1491 int32_t RendererInServer::InitDupStream(int32_t innerCapId)
1492 {
1493 AUDIO_INFO_LOG("InitDupStream for innerCapId:%{public}d", innerCapId);
1494 Trace trace(traceTag_ + "InitDupStream innerCapId:" + std::to_string(innerCapId));
1495 std::lock_guard<std::mutex> lock(dupMutex_);
1496 if (captureInfos_.count(innerCapId) && captureInfos_[innerCapId].isInnerCapEnabled) {
1497 AUDIO_INFO_LOG("InnerCap is already enabled,id:%{public}d", innerCapId);
1498 return SUCCESS;
1499 }
1500 auto &capInfo = captureInfos_[innerCapId];
1501 AudioProcessConfig dupConfig = processConfig_;
1502 dupConfig.innerCapId = innerCapId;
1503 int32_t ret = IStreamManager::GetDupPlaybackManager().CreateRender(dupConfig, capInfo.dupStream);
1504 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && capInfo.dupStream != nullptr,
1505 ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1506 uint32_t dupStreamIndex = capInfo.dupStream->GetStreamIndex();
1507 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1508 StreamVolumeParams streamVolumeParams = { dupStreamIndex, processConfig_.streamType,
1509 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1510 isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
1511 AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
1512 innerCapIdToDupStreamCallbackMap_[innerCapId] = std::make_shared<StreamCallbacks>(dupStreamIndex);
1513 int32_t engineFlag = GetEngineFlag();
1514 if (engineFlag == 1) {
1515 ret = CreateDupBufferInner(innerCapId);
1516 dumpDupInFileName_ = std::to_string(dupStreamIndex) + "_dup_in_" + ".pcm";
1517 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupInFileName_, &dumpDupIn_);
1518 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Config dup buffer failed");
1519 }
1520 // todo check index
1521 capInfo.dupStream->RegisterStatusCallback(innerCapIdToDupStreamCallbackMap_[innerCapId]);
1522 capInfo.dupStream->RegisterWriteCallback(innerCapIdToDupStreamCallbackMap_[innerCapId]);
1523
1524 AUDIO_INFO_LOG("Dup Renderer %{public}u with status: %{public}d", streamIndex_, status_.load());
1525 capInfo.isInnerCapEnabled = true;
1526 InitDupStreamVolume(dupStreamIndex);
1527 capInfo.dupStream->SetLoudnessGain(loudnessGain_);
1528
1529 if (status_ == I_STATUS_STARTED) {
1530 AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dup stream", streamIndex_);
1531 capInfo.dupStream->Start();
1532
1533 if (offloadEnable_) {
1534 renderEmptyCountForInnerCap_ = OFFLOAD_INNER_CAP_PREBUF;
1535 }
1536 }
1537 return SUCCESS;
1538 }
1539
InitDupStreamVolume(uint32_t dupStreamIndex)1540 int32_t RendererInServer::InitDupStreamVolume(uint32_t dupStreamIndex)
1541 {
1542 if (audioServerBuffer_ != nullptr) {
1543 float clientVolume = audioServerBuffer_->GetStreamVolume();
1544 float duckFactor = audioServerBuffer_->GetDuckFactor();
1545 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1546 // If some factors are not needed, remove them.
1547 AudioVolume::GetInstance()->SetStreamVolume(dupStreamIndex, clientVolume);
1548 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dupStreamIndex, duckFactor);
1549 AudioVolume::GetInstance()->SetStreamVolumeMute(dupStreamIndex, isMuted);
1550 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dupStreamIndex, lowPowerVolume_);
1551 }
1552 return SUCCESS;
1553 }
1554
EnableDualTone()1555 int32_t RendererInServer::EnableDualTone()
1556 {
1557 if (isDualToneEnabled_) {
1558 AUDIO_INFO_LOG("DualTone is already enabled");
1559 return SUCCESS;
1560 }
1561 int32_t ret = InitDualToneStream();
1562 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dual tone stream failed");
1563 return SUCCESS;
1564 }
1565
DisableDualTone()1566 int32_t RendererInServer::DisableDualTone()
1567 {
1568 std::lock_guard<std::mutex> lock(dualToneMutex_);
1569 if (!isDualToneEnabled_) {
1570 AUDIO_WARNING_LOG("DualTone is already disabled.");
1571 return ERR_INVALID_OPERATION;
1572 }
1573 isDualToneEnabled_ = false;
1574 AUDIO_INFO_LOG("Disable dual tone renderer:[%{public}u] with status: %{public}d",
1575 dualToneStreamIndex_, status_.load());
1576 IStreamManager::GetDualPlaybackManager().ReleaseRender(dualToneStreamIndex_);
1577 AudioVolume::GetInstance()->RemoveStreamVolume(dualToneStreamIndex_);
1578 dualToneStream_ = nullptr;
1579
1580 return ERROR;
1581 }
1582
InitDualToneStream()1583 int32_t RendererInServer::InitDualToneStream()
1584 {
1585 {
1586 std::lock_guard<std::mutex> lock(dualToneMutex_);
1587
1588 int32_t ret = IStreamManager::GetDualPlaybackManager().CreateRender(processConfig_, dualToneStream_);
1589 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && dualToneStream_ != nullptr,
1590 ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1591 dualToneStreamIndex_ = dualToneStream_->GetStreamIndex();
1592 AUDIO_INFO_LOG("init dual tone renderer:[%{public}u]", dualToneStreamIndex_);
1593 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1594 StreamVolumeParams streamVolumeParams = { dualToneStreamIndex_, processConfig_.streamType,
1595 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1596 isSystemApp, processConfig_.rendererInfo.volumeMode, processConfig_.rendererInfo.isVirtualKeyboard };
1597 AudioVolume::GetInstance()->AddStreamVolume(streamVolumeParams);
1598
1599 isDualToneEnabled_ = true;
1600 }
1601
1602 if (audioServerBuffer_ != nullptr) {
1603 float clientVolume = audioServerBuffer_->GetStreamVolume();
1604 float duckFactor = audioServerBuffer_->GetDuckFactor();
1605 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1606 // If some factors are not needed, remove them.
1607 AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1608 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1609 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1610 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, lowPowerVolume_);
1611 }
1612 if (status_ == I_STATUS_STARTED) {
1613 AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dual stream", dualToneStreamIndex_);
1614 stream_->GetAudioEffectMode(effectModeWhenDual_);
1615 stream_->SetAudioEffectMode(EFFECT_NONE);
1616 std::lock_guard<std::mutex> lock(dualToneMutex_);
1617 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1618 if (dualToneStream_ != nullptr) {
1619 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1620 //modified elsewhere, it was decided again after the lock was awarded.
1621 dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1622 dualToneStream_->Start();
1623 }
1624 }
1625 return SUCCESS;
1626 }
1627
StreamCallbacks(uint32_t streamIndex)1628 StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex)
1629 {
1630 AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_);
1631 int32_t engineFlag = GetEngineFlag();
1632 if (engineFlag == 1) {
1633 dumpDupOutFileName_ = std::to_string(streamIndex_) + "_dup_out_" + ".pcm";
1634 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpDupOutFileName_, &dumpDupOut_);
1635 }
1636 }
1637
~StreamCallbacks()1638 StreamCallbacks::~StreamCallbacks()
1639 {
1640 int32_t engineFlag = GetEngineFlag();
1641 if (engineFlag == 1) {
1642 DumpFileUtil::CloseDumpFile(&dumpDupOut_);
1643 }
1644 }
1645
OnStatusUpdate(IOperation operation)1646 void StreamCallbacks::OnStatusUpdate(IOperation operation)
1647 {
1648 AUDIO_INFO_LOG("DupStream %{public}u recv operation: %{public}d", streamIndex_, operation);
1649 }
1650
OnWriteData(size_t length)1651 int32_t StreamCallbacks::OnWriteData(size_t length)
1652 {
1653 Trace trace("DupStream::OnWriteData length " + std::to_string(length));
1654 return SUCCESS;
1655 }
1656
OnWriteData(int8_t * inputData,size_t requestDataLen)1657 int32_t StreamCallbacks::OnWriteData(int8_t *inputData, size_t requestDataLen)
1658 {
1659 Trace trace("DupStream::OnWriteData length " + std::to_string(requestDataLen));
1660 int32_t engineFlag = GetEngineFlag();
1661 if (engineFlag == 1 && dupRingBuffer_ != nullptr) {
1662 std::unique_ptr<AudioRingCache> &dupBuffer = dupRingBuffer_;
1663 // no need mutex
1664 // todo wait readable
1665 AUDIO_INFO_LOG("running");
1666 OptResult result = dupBuffer->GetReadableSize();
1667 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1668 "dupBuffer get readable size failed, size is:%{public}zu", result.size);
1669 if (result.size == 0 || result.size < requestDataLen) {
1670 recoveryAntiShakeBufferCount_ = DUP_RECOVERY_AUTISHAKE_BUFFER_COUNT;
1671 AUDIO_INFO_LOG("Readable size is invaild, result.size:%{public}zu, requstDataLen:%{public}zu",
1672 result.size, requestDataLen);
1673 return ERROR;
1674 }
1675 if (recoveryAntiShakeBufferCount_ > 0) {
1676 recoveryAntiShakeBufferCount_--;
1677 AUDIO_INFO_LOG("need recovery data anti-shake, no onWriteData, recoveryAntiShakeBufferCount_: %{public}d",
1678 recoveryAntiShakeBufferCount_);
1679 return ERROR;
1680 }
1681 AUDIO_DEBUG_LOG("requstDataLen is:%{public}zu readSize is:%{public}zu", requestDataLen, result.size);
1682 result = dupBuffer->Dequeue({reinterpret_cast<uint8_t *>(inputData), requestDataLen});
1683 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR, "dupBuffer dequeue failed");
1684 DumpFileUtil::WriteDumpFile(dumpDupOut_, static_cast<void *>(inputData), requestDataLen);
1685 }
1686 return SUCCESS;
1687 }
1688
GetAvailableSize(size_t & length)1689 int32_t StreamCallbacks::GetAvailableSize(size_t &length)
1690 {
1691 if (dupRingBuffer_ == nullptr) {
1692 AUDIO_ERR_LOG("nullptr");
1693 return ERROR;
1694 }
1695
1696 OptResult result = dupRingBuffer_->GetReadableSize();
1697 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
1698 "get readable size failed, size is:%{public}zu", result.size);
1699
1700 length = result.size;
1701 return SUCCESS;
1702 }
1703
GetDupRingBuffer()1704 std::unique_ptr<AudioRingCache>& StreamCallbacks::GetDupRingBuffer()
1705 {
1706 return dupRingBuffer_;
1707 }
1708
SetOffloadMode(int32_t state,bool isAppBack)1709 int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack)
1710 {
1711 int32_t ret = stream_->SetOffloadMode(state, isAppBack);
1712 {
1713 std::lock_guard<std::mutex> lock(dupMutex_);
1714 for (auto &capInfo : captureInfos_) {
1715 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1716 capInfo.second.dupStream->UpdateMaxLength(350); // 350 for cover offload
1717 }
1718 }
1719 }
1720 if (isDualToneEnabled_) {
1721 std::lock_guard<std::mutex> lock(dualToneMutex_);
1722 if (dualToneStream_ != nullptr) {
1723 dualToneStream_->UpdateMaxLength(350); // 350 for cover offload
1724 }
1725 }
1726 return ret;
1727 }
1728
UnsetOffloadMode()1729 int32_t RendererInServer::UnsetOffloadMode()
1730 {
1731 int32_t ret = stream_->UnsetOffloadMode();
1732 {
1733 std::lock_guard<std::mutex> lock(dupMutex_);
1734 for (auto &capInfo : captureInfos_) {
1735 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1736 capInfo.second.dupStream->UpdateMaxLength(20); // 20 for unset offload
1737 }
1738 }
1739 }
1740 if (isDualToneEnabled_) {
1741 std::lock_guard<std::mutex> lock(dualToneMutex_);
1742 if (dualToneStream_ != nullptr) {
1743 dualToneStream_->UpdateMaxLength(20); // 20 for cover offload
1744 }
1745 }
1746 return ret;
1747 }
1748
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)1749 int32_t RendererInServer::GetOffloadApproximatelyCacheTime(uint64_t ×tamp, uint64_t &paWriteIndex,
1750 uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
1751 {
1752 return stream_->GetOffloadApproximatelyCacheTime(timestamp, paWriteIndex, cacheTimeDsp, cacheTimePa);
1753 }
1754
OffloadSetVolumeInner()1755 int32_t RendererInServer::OffloadSetVolumeInner()
1756 {
1757 struct VolumeValues volumes = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
1758 float volume = AudioVolume::GetInstance()->GetVolume(streamIndex_, processConfig_.streamType, "offload", &volumes);
1759 AUDIO_INFO_LOG("sessionID %{public}u volume: %{public}f", streamIndex_, volume);
1760 if (!IsVolumeSame(volumes.volumeHistory, volume, AUDIO_VOLOMUE_EPSILON)) {
1761 AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, volume);
1762 AudioVolume::GetInstance()->Monitor(streamIndex_, true);
1763 }
1764 return stream_->OffloadSetVolume(volume);
1765 }
1766
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)1767 int32_t RendererInServer::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
1768 {
1769 return stream_->UpdateSpatializationState(spatializationEnabled, headTrackingEnabled);
1770 }
1771
GetStreamManagerType() const1772 int32_t RendererInServer::GetStreamManagerType() const noexcept
1773 {
1774 return managerType_ == DIRECT_PLAYBACK ? AUDIO_DIRECT_MANAGER_TYPE : AUDIO_NORMAL_MANAGER_TYPE;
1775 }
1776
IsHighResolution() const1777 bool RendererInServer::IsHighResolution() const noexcept
1778 {
1779 Trace trace("CheckHighResolution");
1780 if (processConfig_.deviceType != DEVICE_TYPE_WIRED_HEADSET &&
1781 processConfig_.deviceType != DEVICE_TYPE_USB_HEADSET) {
1782 AUDIO_INFO_LOG("normal stream,device type:%{public}d", processConfig_.deviceType);
1783 return false;
1784 }
1785 if (processConfig_.streamType != STREAM_MUSIC || processConfig_.streamInfo.samplingRate < SAMPLE_RATE_48000 ||
1786 processConfig_.streamInfo.format < SAMPLE_S24LE) {
1787 AUDIO_INFO_LOG("normal stream because stream info");
1788 return false;
1789 }
1790 if (processConfig_.streamInfo.samplingRate > SAMPLE_RATE_192000) {
1791 AUDIO_INFO_LOG("sample rate over 192k");
1792 return false;
1793 }
1794 if (IStreamManager::GetPlaybackManager(DIRECT_PLAYBACK).GetStreamCount() > 0) {
1795 AUDIO_INFO_LOG("high resolution exist.");
1796 return false;
1797 }
1798 return true;
1799 }
1800
SetSilentModeAndMixWithOthers(bool on)1801 int32_t RendererInServer::SetSilentModeAndMixWithOthers(bool on)
1802 {
1803 silentModeAndMixWithOthers_ = on;
1804 bool isMuted = (isMuted_ || on || muteFlag_);
1805 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1806 {
1807 std::lock_guard<std::mutex> lock(dupMutex_);
1808 for (auto &capInfo : captureInfos_) {
1809 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1810 AudioVolume::GetInstance()->SetStreamVolumeMute(
1811 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1812 }
1813 }
1814 }
1815 if (isDualToneEnabled_) {
1816 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1817 }
1818 if (offloadEnable_) {
1819 OffloadSetVolumeInner();
1820 }
1821 AudioService::GetInstance()->RenderersCheckForAudioWorkgroup(processConfig_.appInfo.appPid);
1822 return SUCCESS;
1823 }
1824
SetClientVolume()1825 int32_t RendererInServer::SetClientVolume()
1826 {
1827 if (audioServerBuffer_ == nullptr || playerDfx_ == nullptr) {
1828 AUDIO_WARNING_LOG("buffer in not inited");
1829 return ERROR;
1830 }
1831 float clientVolume = audioServerBuffer_->GetStreamVolume();
1832 std::string currentTime = GetTime();
1833 AUDIO_INFO_LOG("SetVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1834 clientVolume, streamIndex_, currentTime.c_str());
1835 AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(clientVolume, streamIndex_, currentTime,
1836 static_cast<uint32_t>(AdjustStreamVolume::STREAM_VOLUME_INFO));
1837 int32_t ret = stream_->SetClientVolume(clientVolume);
1838 SetStreamVolumeInfoForEnhanceChain();
1839 AudioVolume::GetInstance()->SetStreamVolume(streamIndex_, clientVolume);
1840 {
1841 std::lock_guard<std::mutex> lock(dupMutex_);
1842 for (auto &capInfo : captureInfos_) {
1843 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1844 AudioVolume::GetInstance()->SetStreamVolume(
1845 capInfo.second.dupStream->GetStreamIndex(), clientVolume);
1846 }
1847 }
1848 }
1849 if (isDualToneEnabled_) {
1850 AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1851 }
1852 if (offloadEnable_) {
1853 OffloadSetVolumeInner();
1854 }
1855
1856 RendererStage stage = static_cast<size_t>(clientVolume) == 0 ?
1857 RENDERER_STAGE_SET_VOLUME_ZERO : RENDERER_STAGE_SET_VOLUME_NONZERO;
1858 playerDfx_->WriteDfxActionMsg(streamIndex_, stage);
1859 return ret;
1860 }
1861
SetLoudnessGain(float loudnessGain)1862 int32_t RendererInServer::SetLoudnessGain(float loudnessGain)
1863 {
1864 loudnessGain_ = loudnessGain;
1865 int32_t ret = stream_->SetLoudnessGain(loudnessGain);
1866 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "setloudnessGain failed");
1867 {
1868 std::lock_guard<std::mutex> lock(dupMutex_);
1869 for (auto &capInfo : captureInfos_) {
1870 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1871 ret += capInfo.second.dupStream->SetLoudnessGain(loudnessGain);
1872 }
1873 }
1874 }
1875 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "setloudnessGain failed during capture, error: %{public}d", ret);
1876 return SUCCESS;
1877 }
1878
SetMute(bool isMute)1879 int32_t RendererInServer::SetMute(bool isMute)
1880 {
1881 isMuted_ = isMute;
1882 AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", isMute);
1883 bool isMuted = (isMute || silentModeAndMixWithOthers_ || muteFlag_);
1884 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1885 {
1886 std::lock_guard<std::mutex> lock(dupMutex_);
1887 for (auto &capInfo : captureInfos_) {
1888 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1889 AudioVolume::GetInstance()->SetStreamVolumeMute(
1890 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1891 }
1892 }
1893 }
1894 if (isDualToneEnabled_) {
1895 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1896 }
1897 if (offloadEnable_) {
1898 OffloadSetVolumeInner();
1899 }
1900 return SUCCESS;
1901 }
1902
SetDuckFactor(float duckFactor)1903 int32_t RendererInServer::SetDuckFactor(float duckFactor)
1904 {
1905 if (duckFactor < MIN_FLOAT_VOLUME || duckFactor > MAX_FLOAT_VOLUME) {
1906 AUDIO_ERR_LOG("invalid duck volume:%{public}f", duckFactor);
1907 return ERR_INVALID_PARAM;
1908 }
1909
1910 std::string currentTime = GetTime();
1911 AUDIO_INFO_LOG("SetDuckVolumeInfo volume: %{public}f, sessionID: %{public}d, adjustTime: %{public}s",
1912 duckFactor, streamIndex_, currentTime.c_str());
1913 AudioVolume::GetInstance()->SaveAdjustStreamVolumeInfo(duckFactor, streamIndex_, currentTime,
1914 static_cast<uint32_t>(AdjustStreamVolume::DUCK_VOLUME_INFO));
1915
1916 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(streamIndex_, duckFactor);
1917 {
1918 std::lock_guard<std::mutex> lock(dupMutex_);
1919 for (auto &capInfo : captureInfos_) {
1920 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1921 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(
1922 capInfo.second.dupStream->GetStreamIndex(), duckFactor);
1923 }
1924 }
1925 }
1926 if (isDualToneEnabled_) {
1927 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1928 }
1929 if (offloadEnable_) {
1930 OffloadSetVolumeInner();
1931 }
1932 return SUCCESS;
1933 }
1934
SetStreamVolumeInfoForEnhanceChain()1935 int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain()
1936 {
1937 uint32_t sessionId = streamIndex_;
1938 float streamVolume = audioServerBuffer_->GetStreamVolume();
1939 int32_t engineFlag = GetEngineFlag();
1940 if (engineFlag == 1) {
1941 return HPAE::IHpaeManager::GetHpaeManager().SetStreamVolumeInfo(sessionId, streamVolume);
1942 } else {
1943 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
1944 CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr");
1945 int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume);
1946 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed");
1947 return ret;
1948 }
1949 }
1950
OnDataLinkConnectionUpdate(IOperation operation)1951 void RendererInServer::OnDataLinkConnectionUpdate(IOperation operation)
1952 {
1953 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
1954 CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr");
1955 switch (operation) {
1956 case OPERATION_DATA_LINK_CONNECTING:
1957 AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTING received");
1958 stateListener->OnOperationHandled(DATA_LINK_CONNECTING, 0);
1959 break;
1960 case OPERATION_DATA_LINK_CONNECTED:
1961 AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTED received");
1962 stateListener->OnOperationHandled(DATA_LINK_CONNECTED, 0);
1963 break;
1964 default:
1965 return;
1966 }
1967 }
1968
GetActualStreamManagerType() const1969 int32_t RendererInServer::GetActualStreamManagerType() const noexcept
1970 {
1971 return managerType_;
1972 }
1973
GetStatusStr(IStatus status)1974 static std::string GetStatusStr(IStatus status)
1975 {
1976 switch (status) {
1977 case I_STATUS_INVALID:
1978 return "INVALID";
1979 case I_STATUS_IDLE:
1980 return "IDEL";
1981 case I_STATUS_STARTING:
1982 return "STARTING";
1983 case I_STATUS_STARTED:
1984 return "STARTED";
1985 case I_STATUS_PAUSING:
1986 return "PAUSING";
1987 case I_STATUS_PAUSED:
1988 return "PAUSED";
1989 case I_STATUS_FLUSHING_WHEN_STARTED:
1990 return "FLUSHING_WHEN_STARTED";
1991 case I_STATUS_FLUSHING_WHEN_PAUSED:
1992 return "FLUSHING_WHEN_PAUSED";
1993 case I_STATUS_FLUSHING_WHEN_STOPPED:
1994 return "FLUSHING_WHEN_STOPPED";
1995 case I_STATUS_DRAINING:
1996 return "DRAINING";
1997 case I_STATUS_DRAINED:
1998 return "DRAINED";
1999 case I_STATUS_STOPPING:
2000 return "STOPPING";
2001 case I_STATUS_STOPPED:
2002 return "STOPPED";
2003 case I_STATUS_RELEASING:
2004 return "RELEASING";
2005 case I_STATUS_RELEASED:
2006 return "RELEASED";
2007 default:
2008 break;
2009 }
2010 return "NO_SUCH_STATUS";
2011 }
2012
GetManagerTypeStr(ManagerType type)2013 static std::string GetManagerTypeStr(ManagerType type)
2014 {
2015 switch (type) {
2016 case PLAYBACK:
2017 return "Normal";
2018 case DUP_PLAYBACK:
2019 return "Dup Playback";
2020 case DUAL_PLAYBACK:
2021 return "DUAL Playback";
2022 case DIRECT_PLAYBACK:
2023 return "Direct";
2024 case VOIP_PLAYBACK:
2025 return "Voip";
2026 case RECORDER:
2027 return "Recorder";
2028 default:
2029 break;
2030 }
2031 return "NO_SUCH_TYPE";
2032 }
2033
Dump(std::string & dumpString)2034 bool RendererInServer::Dump(std::string &dumpString)
2035 {
2036 if (managerType_ != DIRECT_PLAYBACK && managerType_ != VOIP_PLAYBACK) {
2037 return false;
2038 }
2039 // dump audio stream info
2040 dumpString += "audio stream info:\n";
2041 AppendFormat(dumpString, " - session id:%u\n", streamIndex_);
2042 AppendFormat(dumpString, " - appid:%d\n", processConfig_.appInfo.appPid);
2043 AppendFormat(dumpString, " - stream type:%d\n", processConfig_.streamType);
2044
2045 AppendFormat(dumpString, " - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
2046 AppendFormat(dumpString, " - channels: %u\n", processConfig_.streamInfo.channels);
2047 AppendFormat(dumpString, " - format: %u\n", processConfig_.streamInfo.format);
2048 AppendFormat(dumpString, " - device type: %u\n", processConfig_.deviceType);
2049 AppendFormat(dumpString, " - sink type: %s\n", GetManagerTypeStr(managerType_).c_str());
2050
2051 // dump status info
2052 AppendFormat(dumpString, " - Current stream status: %s\n", GetStatusStr(status_.load()).c_str());
2053 if (audioServerBuffer_ != nullptr) {
2054 AppendFormat(dumpString, " - Current read position: %u\n", audioServerBuffer_->GetCurReadFrame());
2055 AppendFormat(dumpString, " - Current write position: %u\n", audioServerBuffer_->GetCurWriteFrame());
2056 }
2057
2058 dumpString += "\n";
2059 return true;
2060 }
2061
SetNonInterruptMute(const bool muteFlag)2062 void RendererInServer::SetNonInterruptMute(const bool muteFlag)
2063 {
2064 AUDIO_INFO_LOG("mute flag %{public}d", muteFlag);
2065 muteFlag_ = muteFlag;
2066 AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
2067
2068 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag);
2069 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
2070 {
2071 std::lock_guard<std::mutex> lock(dupMutex_);
2072 for (auto &captureInfo : captureInfos_) {
2073 if (captureInfo.second.isInnerCapEnabled && captureInfo.second.dupStream != nullptr) {
2074 AudioVolume::GetInstance()->SetStreamVolumeMute(
2075 captureInfo.second.dupStream->GetStreamIndex(), isMuted);
2076 }
2077 }
2078 }
2079 if (isDualToneEnabled_) {
2080 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
2081 }
2082 if (offloadEnable_) {
2083 OffloadSetVolumeInner();
2084 }
2085 }
2086
RestoreSession(RestoreInfo restoreInfo)2087 RestoreStatus RendererInServer::RestoreSession(RestoreInfo restoreInfo)
2088 {
2089 RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
2090 if (restoreStatus == NEED_RESTORE) {
2091 audioServerBuffer_->SetRestoreInfo(restoreInfo);
2092 }
2093 audioServerBuffer_->WakeFutex();
2094 return restoreStatus;
2095 }
2096
SetDefaultOutputDevice(const DeviceType defaultOutputDevice,bool skipForce)2097 int32_t RendererInServer::SetDefaultOutputDevice(const DeviceType defaultOutputDevice, bool skipForce)
2098 {
2099 return CoreServiceHandler::GetInstance().SetDefaultOutputDevice(defaultOutputDevice, streamIndex_,
2100 processConfig_.rendererInfo.streamUsage, status_ == I_STATUS_STARTED, skipForce);
2101 }
2102
SetSourceDuration(int64_t duration)2103 int32_t RendererInServer::SetSourceDuration(int64_t duration)
2104 {
2105 sourceDuration_ = duration;
2106 return SUCCESS;
2107 }
2108
GetDupRingBuffer()2109 std::unique_ptr<AudioRingCache>& RendererInServer::GetDupRingBuffer()
2110 {
2111 return dupRingBuffer_;
2112 }
2113
CreateDupBufferInner(int32_t innerCapId)2114 int32_t RendererInServer::CreateDupBufferInner(int32_t innerCapId)
2115 {
2116 // todo dynamic
2117 if (innerCapIdToDupStreamCallbackMap_.find(innerCapId) == innerCapIdToDupStreamCallbackMap_.end() ||
2118 innerCapIdToDupStreamCallbackMap_[innerCapId] == nullptr ||
2119 innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr) {
2120 AUDIO_INFO_LOG("dup buffer already configed!");
2121 return SUCCESS;
2122 }
2123
2124 auto &capInfo = captureInfos_[innerCapId];
2125 capInfo.dupStream->GetSpanSizePerFrame(dupSpanSizeInFrame_);
2126 if (offloadEnable_ == true) {
2127 dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_OFFLOAD_LEN / DUP_DEFAULT_LEN);
2128 } else {
2129 dupTotalSizeInFrame_ = dupSpanSizeInFrame_ * (DUP_COMMON_LEN/DUP_DEFAULT_LEN);
2130 }
2131
2132 capInfo.dupStream->GetByteSizePerFrame(dupByteSizePerFrame_);
2133 if (dupSpanSizeInFrame_ == 0 || dupByteSizePerFrame_ == 0) {
2134 AUDIO_ERR_LOG("ERR_INVALID_PARAM");
2135 return ERR_INVALID_PARAM;
2136 }
2137 dupSpanSizeInByte_ = dupSpanSizeInFrame_ * dupByteSizePerFrame_;
2138 CHECK_AND_RETURN_RET_LOG(dupSpanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config dup buffer failed");
2139 AUDIO_INFO_LOG("dupTotalSizeInFrame_: %{public}zu, dupSpanSizeInFrame_: %{public}zu,"
2140 "dupByteSizePerFrame_:%{public}zu dupSpanSizeInByte_: %{public}zu,",
2141 dupTotalSizeInFrame_, dupSpanSizeInFrame_, dupByteSizePerFrame_, dupSpanSizeInByte_);
2142
2143 // create dupBuffer in server
2144 innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() =
2145 AudioRingCache::Create(dupTotalSizeInFrame_ * dupByteSizePerFrame_);
2146 CHECK_AND_RETURN_RET_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr,
2147 ERR_OPERATION_FAILED, "Create dup buffer failed");
2148 return SUCCESS;
2149 }
2150
WriteDupBufferInner(const BufferDesc & bufferDesc,int32_t innerCapId)2151 int32_t RendererInServer::WriteDupBufferInner(const BufferDesc &bufferDesc, int32_t innerCapId)
2152 {
2153 size_t targetSize = bufferDesc.bufLength;
2154 if (innerCapIdToDupStreamCallbackMap_.find(innerCapId) == innerCapIdToDupStreamCallbackMap_.end() ||
2155 innerCapIdToDupStreamCallbackMap_[innerCapId] == nullptr ||
2156 innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() == nullptr) {
2157 AUDIO_INFO_LOG("dup buffer is nnullptr, failed WriteDupBuffer!");
2158 return ERROR;
2159 }
2160 OptResult result = innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->GetWritableSize();
2161 // todo get writeable size failed
2162 CHECK_AND_RETURN_RET_LOG(result.ret == OPERATION_SUCCESS, ERROR,
2163 "DupRingBuffer write invalid size is:%{public}zu", result.size);
2164 size_t writableSize = result.size;
2165 AUDIO_DEBUG_LOG("targetSize: %{public}zu, writableSize: %{public}zu", targetSize, writableSize);
2166 size_t writeSize = std::min(writableSize, targetSize);
2167 BufferWrap bufferWrap = {bufferDesc.buffer, writeSize};
2168 if (writeSize > 0) {
2169 result = innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->Enqueue(bufferWrap);
2170 if (result.ret != OPERATION_SUCCESS) {
2171 AUDIO_ERR_LOG("RingCache Enqueue failed ret:%{public}d size:%{public}zu", result.ret, result.size);
2172 }
2173 DumpFileUtil::WriteDumpFile(dumpDupIn_, static_cast<void *>(bufferDesc.buffer), writeSize);
2174 }
2175 return SUCCESS;
2176 }
2177
SetSpeed(float speed)2178 int32_t RendererInServer::SetSpeed(float speed)
2179 {
2180 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "stream_ is null");
2181 return stream_->SetSpeed(speed);
2182 }
2183
SetOffloadDataCallbackState(int32_t state)2184 int32_t RendererInServer::SetOffloadDataCallbackState(int32_t state)
2185 {
2186 return stream_->SetOffloadDataCallbackState(state);
2187 }
2188
StopSession()2189 int32_t RendererInServer::StopSession()
2190 {
2191 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_INVALID_PARAM, "audioServerBuffer_ is nullptr");
2192 audioServerBuffer_->SetStopFlag(true);
2193 return SUCCESS;
2194 }
2195
SetAudioHapticsSyncId(const int32_t & audioHapticsSyncId)2196 int32_t RendererInServer::SetAudioHapticsSyncId(const int32_t &audioHapticsSyncId)
2197 {
2198 audioHapticsSyncId_.store(audioHapticsSyncId);
2199 return SUCCESS;
2200 }
2201
UpdateLatestForWorkgroup(float systemVolume)2202 void RendererInServer::UpdateLatestForWorkgroup(float systemVolume)
2203 {
2204 latestForWorkgroup_.status = status_;
2205 latestForWorkgroup_.isInSilentState = isInSilentState_;
2206 latestForWorkgroup_.silentModeAndMixWithOthers = silentModeAndMixWithOthers_.load();
2207 latestForWorkgroup_.lastWriteStandbyEnableStatus = lastWriteStandbyEnableStatus_;
2208 latestForWorkgroup_.streamVolume = audioServerBuffer_->GetStreamVolume();
2209 latestForWorkgroup_.systemVolume = systemVolume;
2210 AUDIO_INFO_LOG("[WorkgroupInServer] pid = %{public}d, status_ = %{public}d, "
2211 "isInSilentState_ = %{public}d, "
2212 "silentModeAndMixWithOthers_ = %{public}d, "
2213 "lastWriteStandbyEnableStatus_ = %{public}d, "
2214 "streamVolume = %{public}f, "
2215 "systemVolume = %{public}f",
2216 processConfig_.appInfo.appPid, latestForWorkgroup_.status, latestForWorkgroup_.isInSilentState,
2217 latestForWorkgroup_.silentModeAndMixWithOthers, latestForWorkgroup_.lastWriteStandbyEnableStatus,
2218 latestForWorkgroup_.streamVolume, latestForWorkgroup_.systemVolume);
2219 }
2220
CollectInfosForWorkgroup(float systemVolume)2221 bool RendererInServer::CollectInfosForWorkgroup(float systemVolume)
2222 {
2223 bool running = (status_ == I_STATUS_STARTED) ? true : false;
2224 float streamVolume = audioServerBuffer_->GetStreamVolume();
2225 bool haveStreamSound = (fabs(streamVolume) > AUDIO_VOLOMUE_EPSILON) ? true : false;
2226 bool haveSystemSound = (fabs(systemVolume) > AUDIO_VOLOMUE_EPSILON) ? true : false;
2227
2228 if (!latestForWorkgroupInited_) {
2229 UpdateLatestForWorkgroup(systemVolume);
2230 latestForWorkgroupInited_ = true;
2231 }
2232 UpdateLatestForWorkgroup(systemVolume);
2233
2234 return running && haveStreamSound && haveSystemSound &&
2235 !isInSilentState_ && !silentModeAndMixWithOthers_ && !lastWriteStandbyEnableStatus_;
2236 }
2237
InitDupBuffer(int32_t innerCapId)2238 void RendererInServer::InitDupBuffer(int32_t innerCapId)
2239 {
2240 std::lock_guard<std::mutex> lock(dupMutex_);
2241 CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_.find(innerCapId) != innerCapIdToDupStreamCallbackMap_.end(),
2242 "innerCapIdToDupStreamCallbackMap_ is no find innerCapId: %{public}d", innerCapId);
2243 CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId] != nullptr,
2244 "innerCapIdToDupStreamCallbackMap_ is null, innerCapId: %{public}d", innerCapId);
2245 CHECK_AND_RETURN_LOG(innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer() != nullptr,
2246 "DupRingBuffe is null, innerCapId: %{public}d", innerCapId);
2247 innerCapIdToDupStreamCallbackMap_[innerCapId]->GetDupRingBuffer()->
2248 ReConfig(dupTotalSizeInFrame_ * dupByteSizePerFrame_, false);
2249 AUDIO_INFO_LOG("InitDupBuffer success, innerCapId: %{public}d, stream sessionId: %{public}u",
2250 innerCapId, streamIndex_);
2251 }
2252 } // namespace AudioStandard
2253 } // namespace OHOS
2254