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
41 namespace OHOS {
42 namespace AudioStandard {
43 namespace {
44 static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
45 static const int64_t MOCK_LATENCY = 45000000; // 45000000 -> 45ms
46 static const int64_t START_MIN_COST = 80000000; // 80000000 -> 80ms
47 static const int32_t NO_FADING = 0;
48 static const int32_t DO_FADINGOUT = 1;
49 static const int32_t FADING_OUT_DONE = 2;
50 static const float FADINGOUT_BEGIN = 1.0f;
51 static const float FADINGOUT_END = 0.0f;
52 static constexpr int32_t ONE_MINUTE = 60;
53 const int32_t MEDIA_UID = 1013;
54 const float AUDIO_VOLOMUE_EPSILON = 0.0001;
55 const int32_t OFFLOAD_INNER_CAP_PREBUF = 3;
56 constexpr int32_t RELEASE_TIMEOUT_IN_SEC = 10; // 10S
57 constexpr int32_t DEFAULT_SPAN_SIZE = 1;
58 constexpr size_t MSEC_PER_SEC = 1000;
59 }
60
RendererInServer(AudioProcessConfig processConfig,std::weak_ptr<IStreamListener> streamListener)61 RendererInServer::RendererInServer(AudioProcessConfig processConfig, std::weak_ptr<IStreamListener> streamListener)
62 : processConfig_(processConfig)
63 {
64 streamListener_ = streamListener;
65 managerType_ = PLAYBACK;
66 if (processConfig_.callerUid == MEDIA_UID) {
67 isNeedFade_ = true;
68 oldAppliedVolume_ = MIN_FLOAT_VOLUME;
69 }
70 }
71
~RendererInServer()72 RendererInServer::~RendererInServer()
73 {
74 if (status_ != I_STATUS_RELEASED) {
75 Release();
76 }
77 DumpFileUtil::CloseDumpFile(&dumpC2S_);
78 }
79
ConfigServerBuffer()80 int32_t RendererInServer::ConfigServerBuffer()
81 {
82 if (audioServerBuffer_ != nullptr) {
83 AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
84 return SUCCESS;
85 }
86 stream_->GetSpanSizePerFrame(spanSizeInFrame_);
87 totalSizeInFrame_ = spanSizeInFrame_ * DEFAULT_SPAN_SIZE;
88 stream_->GetByteSizePerFrame(byteSizePerFrame_);
89 if (totalSizeInFrame_ == 0 || spanSizeInFrame_ == 0 || totalSizeInFrame_ % spanSizeInFrame_ != 0) {
90 AUDIO_ERR_LOG("ConfigProcessBuffer: ERR_INVALID_PARAM");
91 return ERR_INVALID_PARAM;
92 }
93
94 spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_;
95 CHECK_AND_RETURN_RET_LOG(spanSizeInByte_ != 0, ERR_OPERATION_FAILED, "Config oh audio buffer failed");
96 AUDIO_INFO_LOG("totalSizeInFrame_: %{public}zu, spanSizeInFrame_: %{public}zu, byteSizePerFrame_:%{public}zu "
97 "spanSizeInByte_: %{public}zu,", totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_, spanSizeInByte_);
98
99 // create OHAudioBuffer in server
100 audioServerBuffer_ = OHAudioBuffer::CreateFromLocal(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_);
101 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create oh audio buffer failed");
102
103 // we need to clear data buffer to avoid dirty data.
104 memset_s(audioServerBuffer_->GetDataBase(), audioServerBuffer_->GetDataSize(), 0,
105 audioServerBuffer_->GetDataSize());
106 int32_t ret = InitBufferStatus();
107 AUDIO_DEBUG_LOG("Clear data buffer, ret:%{public}d", ret);
108
109 isBufferConfiged_ = true;
110 isInited_ = true;
111 return SUCCESS;
112 }
113
InitBufferStatus()114 int32_t RendererInServer::InitBufferStatus()
115 {
116 if (audioServerBuffer_ == nullptr) {
117 AUDIO_ERR_LOG("InitBufferStatus failed, null buffer.");
118 return ERR_ILLEGAL_STATE;
119 }
120
121 uint32_t spanCount = audioServerBuffer_->GetSpanCount();
122 AUDIO_INFO_LOG("InitBufferStatus: spanCount %{public}u", spanCount);
123 for (uint32_t i = 0; i < spanCount; i++) {
124 SpanInfo *spanInfo = audioServerBuffer_->GetSpanInfoByIndex(i);
125 if (spanInfo == nullptr) {
126 AUDIO_ERR_LOG("InitBufferStatus failed, null spaninfo");
127 return ERR_ILLEGAL_STATE;
128 }
129 spanInfo->spanStatus = SPAN_READ_DONE;
130 spanInfo->offsetInFrame = 0;
131
132 spanInfo->readStartTime = 0;
133 spanInfo->readDoneTime = 0;
134
135 spanInfo->writeStartTime = 0;
136 spanInfo->writeDoneTime = 0;
137
138 spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
139 spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
140 spanInfo->isMute = false;
141 }
142 return SUCCESS;
143 }
144
Init()145 int32_t RendererInServer::Init()
146 {
147 if (IsHighResolution()) {
148 Trace trace("current stream marked as high resolution");
149 managerType_ = DIRECT_PLAYBACK;
150 AUDIO_INFO_LOG("current stream marked as high resolution");
151 }
152
153 if (processConfig_.rendererInfo.rendererFlags == AUDIO_FLAG_VOIP_DIRECT) {
154 if (IStreamManager::GetPlaybackManager(VOIP_PLAYBACK).GetStreamCount() <= 0) {
155 AUDIO_INFO_LOG("current stream marked as VoIP direct stream");
156 managerType_ = VOIP_PLAYBACK;
157 } else {
158 AUDIO_WARNING_LOG("One VoIP direct stream has been created! Use normal mode.");
159 }
160 }
161
162 int32_t ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
163 if (ret != SUCCESS && (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK)) {
164 Trace trace("high resolution create failed use normal replace");
165 managerType_ = PLAYBACK;
166 ret = IStreamManager::GetPlaybackManager(managerType_).CreateRender(processConfig_, stream_);
167 AUDIO_INFO_LOG("high resolution create failed use normal replace");
168 }
169 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && stream_ != nullptr, ERR_OPERATION_FAILED,
170 "Construct rendererInServer failed: %{public}d", ret);
171 streamIndex_ = stream_->GetStreamIndex();
172 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
173 AudioVolume::GetInstance()->AddStreamVolume(streamIndex_, processConfig_.streamType,
174 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
175 isSystemApp, processConfig_.rendererInfo.volumeMode);
176 traceTag_ = "[" + std::to_string(streamIndex_) + "]RendererInServer"; // [100001]RendererInServer:
177 ret = ConfigServerBuffer();
178 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
179 "Construct rendererInServer failed: %{public}d", ret);
180 stream_->RegisterStatusCallback(shared_from_this());
181 stream_->RegisterWriteCallback(shared_from_this());
182
183 // eg: /data/data/.pulse_dir/10000_100001_48000_2_1_server_in.pcm
184 AudioStreamInfo tempInfo = processConfig_.streamInfo;
185 dumpFileName_ = std::to_string(processConfig_.appInfo.appPid) + "_" + std::to_string(streamIndex_)
186 + "_renderer_server_in_" + std::to_string(tempInfo.samplingRate) + "_"
187 + std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
188 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpC2S_);
189 playerDfx_ = std::make_unique<PlayerDfxWriter>(processConfig_.appInfo, streamIndex_);
190
191 return SUCCESS;
192 }
193
CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)194 void RendererInServer::CheckAndWriterRenderStreamStandbySysEvent(bool standbyEnable)
195 {
196 if (standbyEnable == lastWriteStandbyEnableStatus_) {
197 return;
198 }
199 lastWriteStandbyEnableStatus_ = standbyEnable;
200 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
201 Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
202 Media::MediaMonitor::BEHAVIOR_EVENT);
203 bean->Add("STREAMID", static_cast<int32_t>(streamIndex_));
204 bean->Add("STANDBY", standbyEnable ? 1 : 0);
205 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
206 std::unordered_map<std::string, std::string> payload;
207 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
208 payload["sessionId"] = std::to_string(streamIndex_);
209 payload["isStandby"] = std::to_string(standbyEnable ? 1 : 0);
210 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_STANDBY);
211 }
212
OnStatusUpdate(IOperation operation)213 void RendererInServer::OnStatusUpdate(IOperation operation)
214 {
215 AUDIO_INFO_LOG("%{public}u recv operation:%{public}d standByEnable_:%{public}s", streamIndex_, operation,
216 (standByEnable_ ? "true" : "false"));
217 Trace trace(traceTag_ + " OnStatusUpdate:" + std::to_string(operation));
218 CHECK_AND_RETURN_LOG(operation != OPERATION_RELEASED, "Stream already released");
219 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
220 CHECK_AND_RETURN_LOG((stateListener != nullptr && playerDfx_ != nullptr), "nullptr");
221 CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
222 "stream status is nullptr");
223 switch (operation) {
224 case OPERATION_STARTED:
225 HandleOperationStarted();
226 stateListener->OnOperationHandled(START_STREAM, 0);
227 break;
228 case OPERATION_PAUSED:
229 if (standByEnable_) {
230 AUDIO_INFO_LOG("%{public}u recv stand-by paused", streamIndex_);
231 audioServerBuffer_->GetStreamStatus()->store(STREAM_STAND_BY);
232 CheckAndWriterRenderStreamStandbySysEvent(true);
233 return;
234 }
235 status_ = I_STATUS_PAUSED;
236 stateListener->OnOperationHandled(PAUSE_STREAM, 0);
237 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_PAUSE_OK);
238 break;
239 case OPERATION_STOPPED:
240 status_ = I_STATUS_STOPPED;
241 stateListener->OnOperationHandled(STOP_STREAM, 0);
242 lastStopTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
243 std::chrono::system_clock::now().time_since_epoch()).count();
244 lastWriteFrame_ = audioServerBuffer_->GetCurReadFrame() - lastWriteFrame_;
245 playerDfx_->WriteDfxStopMsg(streamIndex_, RENDERER_STAGE_STOP_OK,
246 {lastWriteFrame_, lastWriteMuteFrame_, GetLastAudioDuration(), underrunCount_}, processConfig_);
247 break;
248 case OPERATION_FLUSHED:
249 HandleOperationFlushed();
250 stateListener->OnOperationHandled(FLUSH_STREAM, 0);
251 break;
252 case OPERATION_DRAINED:
253 // Client's StopAudioStream will call Drain first and then Stop. If server's drain times out,
254 // Stop will be completed first. After a period of time, when Drain's callback goes here,
255 // state of server should not be changed to STARTED while the client state is Stopped.
256 OnStatusUpdateExt(operation, stateListener);
257 break;
258 default:
259 OnStatusUpdateSub(operation);
260 }
261 }
262
GetLastAudioDuration()263 int64_t RendererInServer::GetLastAudioDuration()
264 {
265 auto ret = lastStopTime_ - lastStartTime_;
266 return ret < 0 ? -1 : ret;
267 }
268
OnStatusUpdateExt(IOperation operation,std::shared_ptr<IStreamListener> stateListener)269 void RendererInServer::OnStatusUpdateExt(IOperation operation, std::shared_ptr<IStreamListener> stateListener)
270 {
271 if (status_ == I_STATUS_DRAINING) {
272 status_ = I_STATUS_STARTED;
273 stateListener->OnOperationHandled(DRAIN_STREAM, 0);
274 }
275 afterDrain = true;
276 }
277
HandleOperationStarted()278 void RendererInServer::HandleOperationStarted()
279 {
280 CHECK_AND_RETURN_LOG(playerDfx_ != nullptr, "nullptr");
281 CHECK_AND_RETURN_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
282 "stream status is nullptr");
283 if (standByEnable_) {
284 standByEnable_ = false;
285 AUDIO_INFO_LOG("%{public}u recv stand-by started", streamIndex_);
286 audioServerBuffer_->GetStreamStatus()->store(STREAM_RUNNING);
287 FutexTool::FutexWake(audioServerBuffer_->GetFutex());
288 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
289 }
290 CheckAndWriterRenderStreamStandbySysEvent(false);
291 status_ = I_STATUS_STARTED;
292 startedTime_ = ClockTime::GetCurNano();
293
294 lastStartTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
295 std::chrono::system_clock::now().time_since_epoch()).count();
296 lastWriteFrame_ = audioServerBuffer_->GetCurReadFrame();
297 lastWriteMuteFrame_ = 0;
298 }
299
OnStatusUpdateSub(IOperation operation)300 void RendererInServer::OnStatusUpdateSub(IOperation operation)
301 {
302 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
303 switch (operation) {
304 case OPERATION_RELEASED:
305 stateListener->OnOperationHandled(RELEASE_STREAM, 0);
306 status_ = I_STATUS_RELEASED;
307 break;
308 case OPERATION_UNDERRUN:
309 AUDIO_INFO_LOG("Underrun: audioServerBuffer_->GetAvailableDataFrames(): %{public}d",
310 audioServerBuffer_->GetAvailableDataFrames());
311 if (audioServerBuffer_->GetAvailableDataFrames() ==
312 static_cast<int32_t>(DEFAULT_SPAN_SIZE * spanSizeInFrame_)) {
313 AUDIO_INFO_LOG("Buffer is empty");
314 needForceWrite_ = 0;
315 } else {
316 AUDIO_INFO_LOG("Buffer is not empty");
317 WriteData();
318 }
319 break;
320 case OPERATION_UNDERFLOW:
321 if (ClockTime::GetCurNano() - startedTime_ > START_MIN_COST) {
322 underrunCount_++;
323 audioServerBuffer_->SetUnderrunCount(underrunCount_);
324 }
325 StandByCheck(); // if stand by is enbaled here, stream will be paused and not recv UNDERFLOW any more.
326 break;
327 case OPERATION_SET_OFFLOAD_ENABLE:
328 case OPERATION_UNSET_OFFLOAD_ENABLE:
329 offloadEnable_ = operation == OPERATION_SET_OFFLOAD_ENABLE ? true : false;
330 stateListener->OnOperationHandled(SET_OFFLOAD_ENABLE, operation == OPERATION_SET_OFFLOAD_ENABLE ? 1 : 0);
331 break;
332 default:
333 AUDIO_INFO_LOG("Invalid operation %{public}u", operation);
334 status_ = I_STATUS_INVALID;
335 }
336 }
337
StandByCheck()338 void RendererInServer::StandByCheck()
339 {
340 Trace trace(traceTag_ + " StandByCheck:standByCounter_:" + std::to_string(standByCounter_.load()));
341
342 // msdp wait for uncertain time when waiting for bt reply, which may case stream change into standby mode.
343 // if client writes date when stream is changing into standby mode, it would cause drain fail problems.
344 // msdp promises to call api correctly to avoid power problems
345 if (processConfig_.rendererInfo.streamUsage == StreamUsage::STREAM_USAGE_ULTRASONIC) {
346 return;
347 }
348 AUDIO_INFO_LOG("sessionId:%{public}u standByCounter_:%{public}u standByEnable_:%{public}s ", streamIndex_,
349 standByCounter_.load(), (standByEnable_ ? "true" : "false"));
350
351 // direct standBy need not in here
352 if (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) {
353 return;
354 }
355
356 if (standByEnable_) {
357 return;
358 }
359 standByCounter_++;
360 if (!ShouldEnableStandBy()) {
361 return;
362 }
363
364 // call enable stand by
365 standByEnable_ = true;
366 enterStandbyTime_ = ClockTime::GetCurNano();
367 // PaAdapterManager::PauseRender will hold mutex, may cause dead lock with pa_lock
368 if (managerType_ == PLAYBACK) {
369 stream_->Pause(true);
370 }
371
372 if (playerDfx_) {
373 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_BEGIN);
374 }
375 }
376
ShouldEnableStandBy()377 bool RendererInServer::ShouldEnableStandBy()
378 {
379 int64_t timeCost = ClockTime::GetCurNano() - lastWriteTime_;
380 uint32_t maxStandByCounter = 50; // for 20ms, 50 * 20 = 1000ms
381 int64_t timeLimit = 1000000000; // 1s
382 if (offloadEnable_) {
383 maxStandByCounter = 400; // for 20ms, 50 * 400 = 8000ms
384 timeLimit = 8 * AUDIO_NS_PER_SECOND; // for 20ms 8s
385 }
386 if (standByCounter_ >= maxStandByCounter && timeCost >= timeLimit) {
387 AUDIO_INFO_LOG("sessionId:%{public}u reach the limit of stand by: %{public}u time:%{public}" PRId64"ns",
388 streamIndex_, standByCounter_.load(), timeCost);
389 return true;
390 }
391 return false;
392 }
393
GetStandbyStatus(bool & isStandby,int64_t & enterStandbyTime)394 int32_t RendererInServer::GetStandbyStatus(bool &isStandby, int64_t &enterStandbyTime)
395 {
396 Trace trace("RendererInServer::GetStandbyStatus:" + std::to_string(streamIndex_) + (standByEnable_ ? " Enabled" :
397 "Disabled"));
398 isStandby = standByEnable_;
399 if (isStandby) {
400 enterStandbyTime = enterStandbyTime_;
401 } else {
402 enterStandbyTime = 0;
403 }
404 return SUCCESS;
405 }
406
HandleOperationFlushed()407 void RendererInServer::HandleOperationFlushed()
408 {
409 switch (status_) {
410 case I_STATUS_FLUSHING_WHEN_STARTED:
411 status_ = I_STATUS_STARTED;
412 break;
413 case I_STATUS_FLUSHING_WHEN_PAUSED:
414 status_ = I_STATUS_PAUSED;
415 break;
416 case I_STATUS_FLUSHING_WHEN_STOPPED:
417 status_ = I_STATUS_STOPPED;
418 break;
419 default:
420 AUDIO_WARNING_LOG("Invalid status before flusing");
421 }
422 }
423
DequeueBuffer(size_t length)424 BufferDesc RendererInServer::DequeueBuffer(size_t length)
425 {
426 return stream_->DequeueBuffer(length);
427 }
428
DoFadingOut(BufferDesc & bufferDesc)429 void RendererInServer::DoFadingOut(BufferDesc& bufferDesc)
430 {
431 std::lock_guard<std::mutex> lock(fadeoutLock_);
432 if (fadeoutFlag_ == DO_FADINGOUT) {
433 AUDIO_INFO_LOG("enter. format:%{public}u", processConfig_.streamInfo.format);
434 AudioChannel channel = processConfig_.streamInfo.channels;
435 ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, FADINGOUT_BEGIN, FADINGOUT_END);
436 int32_t ret = VolumeTools::Process(bufferDesc, processConfig_.streamInfo.format, mapVols);
437 if (ret != SUCCESS) {
438 AUDIO_WARNING_LOG("VolumeTools::Process failed: %{public}d", ret);
439 }
440 fadeoutFlag_ = FADING_OUT_DONE;
441 AUDIO_INFO_LOG("fadeoutFlag_ = FADING_OUT_DONE");
442 }
443 }
444
IsInvalidBuffer(uint8_t * buffer,size_t bufferSize)445 bool RendererInServer::IsInvalidBuffer(uint8_t *buffer, size_t bufferSize)
446 {
447 bool isInvalid = false;
448 uint8_t ui8Data = 0;
449 int16_t i16Data = 0;
450 switch (processConfig_.streamInfo.format) {
451 case SAMPLE_U8:
452 CHECK_AND_RETURN_RET_LOG(bufferSize > 0, false, "buffer size is too small");
453 ui8Data = *buffer;
454 isInvalid = ui8Data == 0;
455 break;
456 case SAMPLE_S16LE:
457 CHECK_AND_RETURN_RET_LOG(bufferSize > 1, false, "buffer size is too small");
458 i16Data = *(reinterpret_cast<const int16_t*>(buffer));
459 isInvalid = i16Data == 0;
460 break;
461 default:
462 break;
463 }
464 return isInvalid;
465 }
466
WriteMuteDataSysEvent(BufferDesc & bufferDesc)467 void RendererInServer::WriteMuteDataSysEvent(BufferDesc &bufferDesc)
468 {
469 int64_t muteFrameCnt = 0;
470 VolumeTools::CalcMuteFrame(bufferDesc, processConfig_.streamInfo, traceTag_, volumeDataCount_, muteFrameCnt);
471 lastWriteMuteFrame_ += muteFrameCnt;
472 if (silentModeAndMixWithOthers_) {
473 return;
474 }
475 if (IsInvalidBuffer(bufferDesc.buffer, bufferDesc.bufLength)) {
476 if (startMuteTime_ == 0) {
477 startMuteTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
478 }
479 std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
480 if ((currentTime - startMuteTime_ >= ONE_MINUTE) && !isInSilentState_) {
481 isInSilentState_ = true;
482 AUDIO_WARNING_LOG("write invalid data for some time in server");
483
484 std::unordered_map<std::string, std::string> payload;
485 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
486 payload["sessionId"] = std::to_string(streamIndex_);
487 payload["isSilent"] = std::to_string(true);
488 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
489 }
490 } else {
491 if (startMuteTime_ != 0) {
492 startMuteTime_ = 0;
493 }
494 if (isInSilentState_) {
495 AUDIO_WARNING_LOG("begin write valid data in server");
496 isInSilentState_ = false;
497
498 std::unordered_map<std::string, std::string> payload;
499 payload["uid"] = std::to_string(processConfig_.appInfo.appUid);
500 payload["sessionId"] = std::to_string(streamIndex_);
501 payload["isSilent"] = std::to_string(false);
502 ReportDataToResSched(payload, ResourceSchedule::ResType::RES_TYPE_AUDIO_RENDERER_SILENT_PLAYBACK);
503 }
504 }
505 }
506
ReportDataToResSched(std::unordered_map<std::string,std::string> payload,uint32_t type)507 void RendererInServer::ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type)
508 {
509 #ifdef RESSCHE_ENABLE
510 AUDIO_INFO_LOG("report event to ResSched ,event type : %{public}d", type);
511 ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
512 #endif
513 }
514
VolumeHandle(BufferDesc & desc)515 void RendererInServer::VolumeHandle(BufferDesc &desc)
516 {
517 // volume process in server
518 if (audioServerBuffer_ == nullptr) {
519 AUDIO_WARNING_LOG("buffer in not inited");
520 return;
521 }
522 float applyVolume = 0.0f;
523 if (muteFlag_) {
524 applyVolume = 0.0f;
525 } else {
526 applyVolume = audioServerBuffer_->GetStreamVolume();
527 }
528 float duckVolume = audioServerBuffer_->GetDuckFactor();
529 float muteVolume = audioServerBuffer_->GetMuteFactor();
530 if (!IsVolumeSame(MAX_FLOAT_VOLUME, lowPowerVolume_, AUDIO_VOLOMUE_EPSILON)) {
531 applyVolume *= lowPowerVolume_;
532 }
533 if (!IsVolumeSame(MAX_FLOAT_VOLUME, duckVolume, AUDIO_VOLOMUE_EPSILON)) {
534 applyVolume *= duckVolume;
535 }
536 if (!IsVolumeSame(MAX_FLOAT_VOLUME, muteVolume, AUDIO_VOLOMUE_EPSILON)) {
537 applyVolume *= muteVolume;
538 }
539
540 if (silentModeAndMixWithOthers_) {
541 applyVolume = 0.0f;
542 }
543
544 //in plan: put system volume handle here
545 if (!IsVolumeSame(MAX_FLOAT_VOLUME, applyVolume, AUDIO_VOLOMUE_EPSILON) ||
546 !IsVolumeSame(oldAppliedVolume_, applyVolume, AUDIO_VOLOMUE_EPSILON)) {
547 Trace traceVol("RendererInServer::VolumeTools::Process " + std::to_string(oldAppliedVolume_) + "~" +
548 std::to_string(applyVolume));
549 AudioChannel channel = processConfig_.streamInfo.channels;
550 ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(channel, oldAppliedVolume_, applyVolume);
551 int32_t volRet = VolumeTools::Process(desc, processConfig_.streamInfo.format, mapVols);
552 oldAppliedVolume_ = applyVolume;
553 if (volRet != SUCCESS) {
554 AUDIO_WARNING_LOG("VolumeTools::Process error: %{public}d", volRet);
555 }
556 }
557 }
558
WriteData()559 int32_t RendererInServer::WriteData()
560 {
561 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
562 uint64_t currentWriteFrame = audioServerBuffer_->GetCurWriteFrame();
563 Trace trace1(traceTag_ + " WriteData"); // RendererInServer::sessionid:100001 WriteData
564 if (currentReadFrame + spanSizeInFrame_ > currentWriteFrame) {
565 Trace trace2(traceTag_ + " near underrun"); // RendererInServer::sessionid:100001 near underrun
566 FutexTool::FutexWake(audioServerBuffer_->GetFutex());
567 if (!offloadEnable_) {
568 CHECK_AND_RETURN_RET_LOG(currentWriteFrame >= currentReadFrame, ERR_OPERATION_FAILED,
569 "invalid write and read position.");
570 uint64_t dataSize = currentWriteFrame - currentReadFrame;
571 AUDIO_INFO_LOG("sessionId: %{public}u OHAudioBuffer %{public}" PRIu64 "size is not enough",
572 streamIndex_, dataSize);
573 }
574 return ERR_OPERATION_FAILED;
575 }
576
577 BufferDesc bufferDesc = {nullptr, 0, 0}; // will be changed in GetReadbuffer
578 if (audioServerBuffer_->GetReadbuffer(currentReadFrame, bufferDesc) == SUCCESS) {
579 if (bufferDesc.buffer == nullptr) {
580 AUDIO_ERR_LOG("The buffer is null!");
581 return ERR_INVALID_PARAM;
582 }
583 uint64_t durationMs = ((byteSizePerFrame_ * processConfig_.streamInfo.samplingRate) == 0) ? 0
584 : ((MSEC_PER_SEC * processConfig_.rendererInfo.expectedPlaybackDurationBytes) /
585 (byteSizePerFrame_ * processConfig_.streamInfo.samplingRate));
586 if (processConfig_.streamType != STREAM_ULTRASONIC && (GetFadeStrategy(durationMs) == FADE_STRATEGY_DEFAULT)) {
587 if (currentReadFrame + spanSizeInFrame_ == currentWriteFrame) {
588 DoFadingOut(bufferDesc);
589 }
590 }
591 stream_->EnqueueBuffer(bufferDesc);
592 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
593 DumpFileUtil::WriteDumpFile(dumpC2S_, static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
594 AudioCacheMgr::GetInstance().CacheData(dumpFileName_,
595 static_cast<void *>(bufferDesc.buffer), bufferDesc.bufLength);
596 }
597
598 OtherStreamEnqueue(bufferDesc);
599
600 WriteMuteDataSysEvent(bufferDesc);
601 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength); // clear is needed for reuse.
602 // Client may write the buffer immediately after SetCurReadFrame, so put memset_s before it!
603 uint64_t nextReadFrame = currentReadFrame + spanSizeInFrame_;
604 audioServerBuffer_->SetCurReadFrame(nextReadFrame);
605 }
606 FutexTool::FutexWake(audioServerBuffer_->GetFutex());
607 standByCounter_ = 0;
608 lastWriteTime_ = ClockTime::GetCurNano();
609 return SUCCESS;
610 }
611
OtherStreamEnqueue(const BufferDesc & bufferDesc)612 void RendererInServer::OtherStreamEnqueue(const BufferDesc &bufferDesc)
613 {
614 // for inner capture
615 for (auto &capInfo : captureInfos_) {
616 InnerCaptureOtherStream(bufferDesc, capInfo.second);
617 }
618 // for dual tone
619 if (isDualToneEnabled_) {
620 Trace traceDup("RendererInServer::WriteData DualToneSteam write");
621 std::lock_guard<std::mutex> lock(dualToneMutex_);
622 if (dualToneStream_ != nullptr) {
623 dualToneStream_->EnqueueBuffer(bufferDesc); // what if enqueue fail?
624 }
625 }
626 }
627
InnerCaptureOtherStream(const BufferDesc & bufferDesc,CaptureInfo & captureInfo)628 void RendererInServer::InnerCaptureOtherStream(const BufferDesc &bufferDesc, CaptureInfo &captureInfo)
629 {
630 if (captureInfo.isInnerCapEnabled) {
631 Trace traceDup("RendererInServer::WriteData DupSteam write");
632 std::lock_guard<std::mutex> lock(dupMutex_);
633 if (captureInfo.dupStream != nullptr) {
634 if (renderEmptyCountForInnerCap_ > 0) {
635 size_t emptyBufferSize = static_cast<size_t>(renderEmptyCountForInnerCap_) * spanSizeInByte_;
636 auto buffer = std::make_unique<uint8_t []>(emptyBufferSize);
637 BufferDesc emptyBufferDesc = {buffer.get(), emptyBufferSize, emptyBufferSize};
638 memset_s(emptyBufferDesc.buffer, emptyBufferDesc.bufLength, 0, emptyBufferDesc.bufLength);
639 captureInfo.dupStream->EnqueueBuffer(emptyBufferDesc);
640 renderEmptyCountForInnerCap_ = 0;
641 }
642 captureInfo.dupStream->EnqueueBuffer(bufferDesc); // what if enqueue fail?
643 }
644 }
645 }
646
WriteEmptyData()647 void RendererInServer::WriteEmptyData()
648 {
649 Trace trace("RendererInServer::WriteEmptyData");
650 AUDIO_WARNING_LOG("Underrun, write empty data");
651 BufferDesc bufferDesc = stream_->DequeueBuffer(spanSizeInByte_);
652 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
653 stream_->EnqueueBuffer(bufferDesc);
654 return;
655 }
656
OnWriteData(size_t length)657 int32_t RendererInServer::OnWriteData(size_t length)
658 {
659 Trace trace("RendererInServer::OnWriteData length " + std::to_string(length));
660 bool mayNeedForceWrite = false;
661 if (writeLock_.try_lock()) {
662 // length unit is bytes, using spanSizeInByte_
663 for (size_t i = 0; i < length / spanSizeInByte_; i++) {
664 mayNeedForceWrite = WriteData() != SUCCESS || mayNeedForceWrite;
665 }
666 writeLock_.unlock();
667 } else {
668 mayNeedForceWrite = true;
669 }
670
671 size_t maxEmptyCount = 1;
672 size_t writableSize = stream_->GetWritableSize();
673 if (mayNeedForceWrite && writableSize >= spanSizeInByte_ * maxEmptyCount) {
674 AUDIO_DEBUG_LOG("Server need force write to recycle callback");
675 needForceWrite_ =
676 writableSize / spanSizeInByte_ > 3 ? 0 : 3 - writableSize / spanSizeInByte_; // 3 is maxlength - 1
677 }
678
679 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
680 audioServerBuffer_->SetHandleInfo(currentReadFrame, ClockTime::GetCurNano() + MOCK_LATENCY);
681
682 if (mayNeedForceWrite) {
683 return ERR_RENDERER_IN_SERVER_UNDERRUN;
684 }
685
686 return SUCCESS;
687 }
688
689 // Call WriteData will hold mainloop lock in EnqueueBuffer, we should not lock a mutex in WriteData while OnWriteData is
690 // called with mainloop locking.
UpdateWriteIndex()691 int32_t RendererInServer::UpdateWriteIndex()
692 {
693 Trace trace("RendererInServer::UpdateWriteIndex needForceWrite" + std::to_string(needForceWrite_));
694 if (managerType_ != PLAYBACK) {
695 IStreamManager::GetPlaybackManager(managerType_).TriggerStartIfNecessary();
696 }
697 if (needForceWrite_ < 3 && stream_->GetWritableSize() >= spanSizeInByte_) { // 3 is maxlength - 1
698 if (writeLock_.try_lock()) {
699 AUDIO_DEBUG_LOG("Start force write data");
700 int32_t ret = WriteData();
701 if (ret == SUCCESS) {
702 needForceWrite_++;
703 }
704 writeLock_.unlock();
705 }
706 }
707
708 if (afterDrain == true) {
709 if (writeLock_.try_lock()) {
710 afterDrain = false;
711 AUDIO_DEBUG_LOG("After drain, start write data");
712 WriteData();
713 writeLock_.unlock();
714 }
715 }
716 return SUCCESS;
717 }
718
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)719 int32_t RendererInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
720 {
721 buffer = audioServerBuffer_;
722 return SUCCESS;
723 }
724
GetSessionId(uint32_t & sessionId)725 int32_t RendererInServer::GetSessionId(uint32_t &sessionId)
726 {
727 CHECK_AND_RETURN_RET_LOG(stream_ != nullptr, ERR_OPERATION_FAILED, "GetSessionId failed, stream_ is null");
728 sessionId = streamIndex_;
729 CHECK_AND_RETURN_RET_LOG(sessionId < INT32_MAX, ERR_OPERATION_FAILED, "GetSessionId failed, sessionId:%{public}d",
730 sessionId);
731
732 return SUCCESS;
733 }
734
Start()735 int32_t RendererInServer::Start()
736 {
737 int32_t ret = StartInner();
738 RendererStage stage = ret == SUCCESS ? RENDERER_STAGE_START_OK : RENDERER_STAGE_START_FAIL;
739 if (playerDfx_) {
740 playerDfx_->WriteDfxStartMsg(streamIndex_, stage, sourceDuration_, processConfig_);
741 }
742 return ret;
743 }
744
StartInner()745 int32_t RendererInServer::StartInner()
746 {
747 AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_);
748 if (standByEnable_) {
749 AUDIO_INFO_LOG("sessionId: %{public}u call to exit stand by!", streamIndex_);
750 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
751 ERR_OPERATION_FAILED, "stream status is nullptr");
752 standByCounter_ = 0;
753 startedTime_ = ClockTime::GetCurNano();
754 audioServerBuffer_->GetStreamStatus()->store(STREAM_STARTING);
755 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
756 IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
757 return ret;
758 }
759 needForceWrite_ = 0;
760 std::unique_lock<std::mutex> lock(statusLock_);
761 if (status_ != I_STATUS_IDLE && status_ != I_STATUS_PAUSED && status_ != I_STATUS_STOPPED) {
762 AUDIO_ERR_LOG("RendererInServer::Start failed, Illegal state: %{public}u", status_);
763 return ERR_ILLEGAL_STATE;
764 }
765 status_ = I_STATUS_STARTING;
766 {
767 std::lock_guard<std::mutex> lock(fadeoutLock_);
768 AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
769 fadeoutFlag_ = NO_FADING;
770 }
771 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
772 IStreamManager::GetPlaybackManager(managerType_).StartRender(streamIndex_) : stream_->Start();
773 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Start stream failed, reason: %{public}d", ret);
774
775 startedTime_ = ClockTime::GetCurNano();
776 uint64_t currentReadFrame = audioServerBuffer_->GetCurReadFrame();
777 int64_t tempTime = ClockTime::GetCurNano() + MOCK_LATENCY;
778 audioServerBuffer_->SetHandleInfo(currentReadFrame, tempTime);
779 AUDIO_INFO_LOG("Server update position %{public}" PRIu64" time%{public} " PRId64".", currentReadFrame, tempTime);
780 resetTime_ = true;
781
782 {
783 std::lock_guard<std::mutex> lock(dupMutex_);
784 for (auto &capInfo : captureInfos_) {
785 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
786 capInfo.second.dupStream->Start();
787 }
788 }
789 }
790 enterStandbyTime_ = 0;
791
792 dualToneStreamInStart();
793 AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(streamIndex_);
794 return SUCCESS;
795 }
796
dualToneStreamInStart()797 void RendererInServer::dualToneStreamInStart()
798 {
799 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
800 //Joint judgment ensures that there is a double ring and there is a stream to enter.
801 stream_->GetAudioEffectMode(effectModeWhenDual_);
802 stream_->SetAudioEffectMode(EFFECT_NONE);
803 std::lock_guard<std::mutex> lock(dualToneMutex_);
804 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
805 if (dualToneStream_ != nullptr) {
806 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
807 //modified elsewhere, it was decided again after the lock was awarded.
808 dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
809 dualToneStream_->Start();
810 }
811 }
812 }
813
Pause()814 int32_t RendererInServer::Pause()
815 {
816 AUDIO_INFO_LOG("Pause.");
817 std::unique_lock<std::mutex> lock(statusLock_);
818 if (status_ != I_STATUS_STARTED) {
819 AUDIO_ERR_LOG("RendererInServer::Pause failed, Illegal state: %{public}u", status_);
820 return ERR_ILLEGAL_STATE;
821 }
822 status_ = I_STATUS_PAUSING;
823 if (standByEnable_) {
824 AUDIO_INFO_LOG("sessionId: %{public}u call Pause while stand by", streamIndex_);
825 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
826 ERR_OPERATION_FAILED, "stream status is nullptr");
827 standByEnable_ = false;
828 enterStandbyTime_ = 0;
829 audioServerBuffer_->GetStreamStatus()->store(STREAM_PAUSED);
830 if (playerDfx_) {
831 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
832 }
833 }
834 standByCounter_ = 0;
835 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
836 IStreamManager::GetPlaybackManager(managerType_).PauseRender(streamIndex_) : stream_->Pause();
837 {
838 std::lock_guard<std::mutex> lock(dupMutex_);
839 for (auto &capInfo : captureInfos_) {
840 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
841 capInfo.second.dupStream->Pause();
842 }
843 }
844 }
845 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
846 //Joint judgment ensures that there is a double ring and there is a stream to enter.
847 stream_->SetAudioEffectMode(effectModeWhenDual_);
848 std::lock_guard<std::mutex> lock(dualToneMutex_);
849 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
850 if (dualToneStream_ != nullptr) {
851 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
852 //modified elsewhere, it was decided again after the lock was awarded.
853 dualToneStream_->Pause();
854 dualToneStream_->SetAudioEffectMode(effectModeWhenDual_);
855 }
856 }
857 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Pause stream failed, reason: %{public}d", ret);
858
859 return SUCCESS;
860 }
861
Flush()862 int32_t RendererInServer::Flush()
863 {
864 AUDIO_PRERELEASE_LOGI("Flush.");
865 Trace trace(traceTag_ + " Flush");
866 std::unique_lock<std::mutex> lock(statusLock_);
867 if (status_ == I_STATUS_STARTED) {
868 status_ = I_STATUS_FLUSHING_WHEN_STARTED;
869 } else if (status_ == I_STATUS_PAUSED) {
870 status_ = I_STATUS_FLUSHING_WHEN_PAUSED;
871 } else if (status_ == I_STATUS_STOPPED) {
872 status_ = I_STATUS_FLUSHING_WHEN_STOPPED;
873 } else {
874 AUDIO_ERR_LOG("RendererInServer::Flush failed, Illegal state: %{public}u", status_);
875 return ERR_ILLEGAL_STATE;
876 }
877
878 // Flush buffer of audio server
879 uint64_t writeFrame = audioServerBuffer_->GetCurWriteFrame();
880 uint64_t readFrame = audioServerBuffer_->GetCurReadFrame();
881
882 while (readFrame < writeFrame) {
883 BufferDesc bufferDesc = {nullptr, 0, 0};
884 int32_t readResult = audioServerBuffer_->GetReadbuffer(readFrame, bufferDesc);
885 if (readResult != 0) {
886 return ERR_OPERATION_FAILED;
887 }
888 memset_s(bufferDesc.buffer, bufferDesc.bufLength, 0, bufferDesc.bufLength);
889 readFrame += spanSizeInFrame_;
890 AUDIO_INFO_LOG("On flush, read frame: %{public}" PRIu64 ", nextReadFrame: %{public}zu,"
891 "writeFrame: %{public}" PRIu64 "", readFrame, spanSizeInFrame_, writeFrame);
892 audioServerBuffer_->SetCurReadFrame(readFrame);
893 }
894
895 int ret = stream_->Flush();
896 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Flush stream failed, reason: %{public}d", ret);
897 {
898 std::lock_guard<std::mutex> lock(dupMutex_);
899 for (auto &capInfo : captureInfos_) {
900 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
901 capInfo.second.dupStream->Flush();
902 }
903 }
904 }
905 if (isDualToneEnabled_) {
906 std::lock_guard<std::mutex> lock(dualToneMutex_);
907 if (dualToneStream_ != nullptr) {
908 dualToneStream_->Flush();
909 }
910 }
911 return SUCCESS;
912 }
913
DrainAudioBuffer()914 int32_t RendererInServer::DrainAudioBuffer()
915 {
916 return SUCCESS;
917 }
918
Drain(bool stopFlag)919 int32_t RendererInServer::Drain(bool stopFlag)
920 {
921 {
922 std::unique_lock<std::mutex> lock(statusLock_);
923 if (status_ != I_STATUS_STARTED) {
924 AUDIO_ERR_LOG("RendererInServer::Drain failed, Illegal state: %{public}u", status_);
925 return ERR_ILLEGAL_STATE;
926 }
927 status_ = I_STATUS_DRAINING;
928 }
929 AUDIO_INFO_LOG("Start drain. stopFlag:%{public}d", stopFlag);
930 if (stopFlag) {
931 std::lock_guard<std::mutex> lock(fadeoutLock_);
932 AUDIO_INFO_LOG("fadeoutFlag_ = DO_FADINGOUT");
933 fadeoutFlag_ = DO_FADINGOUT;
934 }
935 DrainAudioBuffer();
936 AudioPerformanceMonitor::GetInstance().ClearSilenceMonitor(streamIndex_);
937 int ret = stream_->Drain(stopFlag);
938 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Drain stream failed, reason: %{public}d", ret);
939 {
940 std::lock_guard<std::mutex> lock(dupMutex_);
941 for (auto &capInfo : captureInfos_) {
942 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
943 capInfo.second.dupStream->Drain(stopFlag);
944 }
945 }
946 }
947 if (isDualToneEnabled_) {
948 std::lock_guard<std::mutex> lock(dualToneMutex_);
949 if (dualToneStream_ != nullptr) {
950 dualToneStream_->Drain(stopFlag);
951 }
952 }
953 return SUCCESS;
954 }
955
Stop()956 int32_t RendererInServer::Stop()
957 {
958 AUDIO_INFO_LOG("Stop.");
959 {
960 std::unique_lock<std::mutex> lock(statusLock_);
961 if (status_ != I_STATUS_STARTED && status_ != I_STATUS_PAUSED && status_ != I_STATUS_DRAINING &&
962 status_ != I_STATUS_STARTING) {
963 AUDIO_ERR_LOG("RendererInServer::Stop failed, Illegal state: %{public}u", status_);
964 return ERR_ILLEGAL_STATE;
965 }
966 status_ = I_STATUS_STOPPING;
967 }
968 if (standByEnable_) {
969 AUDIO_INFO_LOG("sessionId: %{public}u call Stop while stand by", streamIndex_);
970 CHECK_AND_RETURN_RET_LOG(audioServerBuffer_->GetStreamStatus() != nullptr,
971 ERR_OPERATION_FAILED, "stream status is nullptr");
972 standByEnable_ = false;
973 enterStandbyTime_ = 0;
974 audioServerBuffer_->GetStreamStatus()->store(STREAM_STOPPED);
975 if (playerDfx_) {
976 playerDfx_->WriteDfxActionMsg(streamIndex_, RENDERER_STAGE_STANDBY_END);
977 }
978 }
979 {
980 std::lock_guard<std::mutex> lock(fadeoutLock_);
981 AUDIO_INFO_LOG("fadeoutFlag_ = NO_FADING");
982 fadeoutFlag_ = NO_FADING;
983 }
984 int32_t ret = (managerType_ == DIRECT_PLAYBACK || managerType_ == VOIP_PLAYBACK) ?
985 IStreamManager::GetPlaybackManager(managerType_).StopRender(streamIndex_) : stream_->Stop();
986 {
987 std::lock_guard<std::mutex> lock(dupMutex_);
988 for (auto &capInfo : captureInfos_) {
989 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
990 capInfo.second.dupStream->Stop();
991 }
992 }
993 }
994 if (isDualToneEnabled_ && dualToneStream_ != nullptr) {
995 //Joint judgment ensures that there is a double ring and there is a stream to enter.
996 stream_->SetAudioEffectMode(effectModeWhenDual_);
997 std::lock_guard<std::mutex> lock(dualToneMutex_);
998 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
999 if (dualToneStream_ != nullptr) {
1000 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1001 //modified elsewhere, it was decided again after the lock was awarded.
1002 dualToneStream_->Stop();
1003 dualToneStream_->SetAudioEffectMode(effectModeWhenDual_);
1004 }
1005 }
1006 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Stop stream failed, reason: %{public}d", ret);
1007 return SUCCESS;
1008 }
1009
Release()1010 int32_t RendererInServer::Release()
1011 {
1012 AUDIO_INFO_LOG("Start release");
1013 AudioXCollie audioXCollie(
1014 "RendererInServer::Release", RELEASE_TIMEOUT_IN_SEC, nullptr, nullptr,
1015 AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1016 {
1017 std::unique_lock<std::mutex> lock(statusLock_);
1018 if (status_ == I_STATUS_RELEASED) {
1019 AUDIO_INFO_LOG("Already released");
1020 return SUCCESS;
1021 }
1022 }
1023
1024 if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1025 AudioService::GetInstance()->SetDecMaxRendererStreamCnt();
1026 AudioService::GetInstance()->CleanAppUseNumMap(processConfig_.appInfo.appUid);
1027 }
1028
1029 int32_t ret = IStreamManager::GetPlaybackManager(managerType_).ReleaseRender(streamIndex_);
1030 AudioVolume::GetInstance()->RemoveStreamVolume(streamIndex_);
1031 AudioService::GetInstance()->RemoveRenderer(streamIndex_);
1032 if (ret < 0) {
1033 AUDIO_ERR_LOG("Release stream failed, reason: %{public}d", ret);
1034 status_ = I_STATUS_INVALID;
1035 return ret;
1036 }
1037 status_ = I_STATUS_RELEASED;
1038 {
1039 std::lock_guard<std::mutex> lock(dupMutex_);
1040 for (auto &capInfo : captureInfos_) {
1041 if (capInfo.second.isInnerCapEnabled) {
1042 DisableInnerCap(capInfo.first);
1043 }
1044 }
1045 captureInfos_.clear();
1046 }
1047 if (isDualToneEnabled_) {
1048 DisableDualTone();
1049 }
1050 return SUCCESS;
1051 }
1052
GetAudioTime(uint64_t & framePos,uint64_t & timestamp)1053 int32_t RendererInServer::GetAudioTime(uint64_t &framePos, uint64_t ×tamp)
1054 {
1055 if (status_ == I_STATUS_STOPPED) {
1056 AUDIO_WARNING_LOG("Current status is stopped");
1057 return ERR_ILLEGAL_STATE;
1058 }
1059 stream_->GetStreamFramesWritten(framePos);
1060 stream_->GetCurrentTimeStamp(timestamp);
1061 if (resetTime_) {
1062 resetTime_ = false;
1063 resetTimestamp_ = timestamp;
1064 }
1065 return SUCCESS;
1066 }
1067
GetAudioPosition(uint64_t & framePos,uint64_t & timestamp,uint64_t & latency)1068 int32_t RendererInServer::GetAudioPosition(uint64_t &framePos, uint64_t ×tamp, uint64_t &latency)
1069 {
1070 if (status_ == I_STATUS_STOPPED) {
1071 AUDIO_PRERELEASE_LOGW("Current status is stopped");
1072 return ERR_ILLEGAL_STATE;
1073 }
1074 stream_->GetCurrentPosition(framePos, timestamp, latency);
1075 return SUCCESS;
1076 }
1077
GetLatency(uint64_t & latency)1078 int32_t RendererInServer::GetLatency(uint64_t &latency)
1079 {
1080 std::unique_lock<std::mutex> lock(statusLock_);
1081 if (managerType_ == DIRECT_PLAYBACK) {
1082 latency = IStreamManager::GetPlaybackManager(managerType_).GetLatency();
1083 return SUCCESS;
1084 }
1085 return stream_->GetLatency(latency);
1086 }
1087
SetRate(int32_t rate)1088 int32_t RendererInServer::SetRate(int32_t rate)
1089 {
1090 return stream_->SetRate(rate);
1091 }
1092
SetLowPowerVolume(float volume)1093 int32_t RendererInServer::SetLowPowerVolume(float volume)
1094 {
1095 if (volume < MIN_FLOAT_VOLUME || volume > MAX_FLOAT_VOLUME) {
1096 AUDIO_ERR_LOG("invalid volume:%{public}f", volume);
1097 return ERR_INVALID_PARAM;
1098 }
1099 lowPowerVolume_ = volume;
1100 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(streamIndex_, volume);
1101 for (auto &capInfo : captureInfos_) {
1102 if (capInfo.second.isInnerCapEnabled) {
1103 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(
1104 capInfo.second.dupStream->GetStreamIndex(), volume);
1105 }
1106 }
1107 if (isDualToneEnabled_) {
1108 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, volume);
1109 }
1110 if (offloadEnable_) {
1111 OffloadSetVolumeInner();
1112 }
1113 return SUCCESS;
1114 }
1115
GetLowPowerVolume(float & volume)1116 int32_t RendererInServer::GetLowPowerVolume(float &volume)
1117 {
1118 volume = lowPowerVolume_;
1119 return SUCCESS;
1120 }
1121
SetAudioEffectMode(int32_t effectMode)1122 int32_t RendererInServer::SetAudioEffectMode(int32_t effectMode)
1123 {
1124 if (isDualToneEnabled_) {
1125 effectModeWhenDual_ = effectMode;
1126 return SUCCESS;
1127 }
1128 return stream_->SetAudioEffectMode(effectMode);
1129 }
1130
GetAudioEffectMode(int32_t & effectMode)1131 int32_t RendererInServer::GetAudioEffectMode(int32_t &effectMode)
1132 {
1133 return stream_->GetAudioEffectMode(effectMode);
1134 }
1135
SetPrivacyType(int32_t privacyType)1136 int32_t RendererInServer::SetPrivacyType(int32_t privacyType)
1137 {
1138 return stream_->SetPrivacyType(privacyType);
1139 }
1140
GetPrivacyType(int32_t & privacyType)1141 int32_t RendererInServer::GetPrivacyType(int32_t &privacyType)
1142 {
1143 return stream_->GetPrivacyType(privacyType);
1144 }
1145
EnableInnerCap(int32_t innerCapId)1146 int32_t RendererInServer::EnableInnerCap(int32_t innerCapId)
1147 {
1148 // in plan
1149 if (captureInfos_.count(innerCapId) && captureInfos_[innerCapId].isInnerCapEnabled) {
1150 AUDIO_INFO_LOG("InnerCap is already enabled,id:%{public}d", innerCapId);
1151 return SUCCESS;
1152 }
1153 int32_t ret = InitDupStream(innerCapId);
1154 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dup stream failed");
1155 return SUCCESS;
1156 }
1157
DisableInnerCap(int32_t innerCapId)1158 int32_t RendererInServer::DisableInnerCap(int32_t innerCapId)
1159 {
1160 if (!captureInfos_.count(innerCapId) || !captureInfos_[innerCapId].isInnerCapEnabled) {
1161 AUDIO_WARNING_LOG("InnerCap is already disabled.capId:%{public}d", innerCapId);
1162 return ERR_INVALID_OPERATION;
1163 }
1164 captureInfos_[innerCapId].isInnerCapEnabled = false;
1165 AUDIO_INFO_LOG("Disable dup renderer %{public}u with status: %{public}d", streamIndex_, status_);
1166 // in plan: call stop?
1167 if (captureInfos_[innerCapId].dupStream != nullptr) {
1168 uint32_t dupStreamIndex = captureInfos_[innerCapId].dupStream->GetStreamIndex();
1169 IStreamManager::GetDupPlaybackManager().ReleaseRender(dupStreamIndex);
1170 AudioVolume::GetInstance()->RemoveStreamVolume(dupStreamIndex);
1171 captureInfos_[innerCapId].dupStream = nullptr;
1172 }
1173 return SUCCESS;
1174 }
1175
InitDupStream(int32_t innerCapId)1176 int32_t RendererInServer::InitDupStream(int32_t innerCapId)
1177 {
1178 std::lock_guard<std::mutex> lock(dupMutex_);
1179 auto &capInfo = captureInfos_[innerCapId];
1180 AudioProcessConfig dupConfig = processConfig_;
1181 dupConfig.innerCapId = innerCapId;
1182 int32_t ret = IStreamManager::GetDupPlaybackManager().CreateRender(dupConfig, capInfo.dupStream);
1183 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && capInfo.dupStream != nullptr,
1184 ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1185 uint32_t dupStreamIndex = capInfo.dupStream->GetStreamIndex();
1186 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1187 AudioVolume::GetInstance()->AddStreamVolume(dupStreamIndex, processConfig_.streamType,
1188 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1189 isSystemApp, processConfig_.rendererInfo.volumeMode);
1190
1191 dupStreamCallback_ = std::make_shared<StreamCallbacks>(dupStreamIndex);
1192 capInfo.dupStream->RegisterStatusCallback(dupStreamCallback_);
1193 capInfo.dupStream->RegisterWriteCallback(dupStreamCallback_);
1194
1195 AUDIO_INFO_LOG("Dup Renderer %{public}u with status: %{public}d", streamIndex_, status_);
1196 capInfo.isInnerCapEnabled = true;
1197
1198 if (audioServerBuffer_ != nullptr) {
1199 float clientVolume = audioServerBuffer_->GetStreamVolume();
1200 float duckFactor = audioServerBuffer_->GetDuckFactor();
1201 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1202 // If some factors are not needed, remove them.
1203 AudioVolume::GetInstance()->SetStreamVolume(dupStreamIndex, clientVolume);
1204 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dupStreamIndex, duckFactor);
1205 AudioVolume::GetInstance()->SetStreamVolumeMute(dupStreamIndex, isMuted);
1206 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dupStreamIndex, lowPowerVolume_);
1207 }
1208 if (status_ == I_STATUS_STARTED) {
1209 AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dup stream", streamIndex_);
1210 capInfo.dupStream->Start();
1211
1212 if (offloadEnable_) {
1213 renderEmptyCountForInnerCap_ = OFFLOAD_INNER_CAP_PREBUF;
1214 }
1215 }
1216 return SUCCESS;
1217 }
1218
EnableDualTone()1219 int32_t RendererInServer::EnableDualTone()
1220 {
1221 if (isDualToneEnabled_) {
1222 AUDIO_INFO_LOG("DualTone is already enabled");
1223 return SUCCESS;
1224 }
1225 int32_t ret = InitDualToneStream();
1226 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dual tone stream failed");
1227 return SUCCESS;
1228 }
1229
DisableDualTone()1230 int32_t RendererInServer::DisableDualTone()
1231 {
1232 std::lock_guard<std::mutex> lock(dualToneMutex_);
1233 if (!isDualToneEnabled_) {
1234 AUDIO_WARNING_LOG("DualTone is already disabled.");
1235 return ERR_INVALID_OPERATION;
1236 }
1237 isDualToneEnabled_ = false;
1238 AUDIO_INFO_LOG("Disable dual tone renderer:[%{public}u] with status: %{public}d", dualToneStreamIndex_, status_);
1239 IStreamManager::GetDualPlaybackManager().ReleaseRender(dualToneStreamIndex_);
1240 AudioVolume::GetInstance()->RemoveStreamVolume(dualToneStreamIndex_);
1241 dualToneStream_ = nullptr;
1242
1243 return ERROR;
1244 }
1245
InitDualToneStream()1246 int32_t RendererInServer::InitDualToneStream()
1247 {
1248 {
1249 std::lock_guard<std::mutex> lock(dualToneMutex_);
1250
1251 int32_t ret = IStreamManager::GetDualPlaybackManager().CreateRender(processConfig_, dualToneStream_);
1252 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && dualToneStream_ != nullptr,
1253 ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
1254 dualToneStreamIndex_ = dualToneStream_->GetStreamIndex();
1255 AUDIO_INFO_LOG("init dual tone renderer:[%{public}u]", dualToneStreamIndex_);
1256 bool isSystemApp = CheckoutSystemAppUtil::CheckoutSystemApp(processConfig_.appInfo.appUid);
1257 AudioVolume::GetInstance()->AddStreamVolume(dualToneStreamIndex_, processConfig_.streamType,
1258 processConfig_.rendererInfo.streamUsage, processConfig_.appInfo.appUid, processConfig_.appInfo.appPid,
1259 isSystemApp, processConfig_.rendererInfo.volumeMode);
1260
1261 isDualToneEnabled_ = true;
1262 }
1263
1264 if (audioServerBuffer_ != nullptr) {
1265 float clientVolume = audioServerBuffer_->GetStreamVolume();
1266 float duckFactor = audioServerBuffer_->GetDuckFactor();
1267 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag_);
1268 // If some factors are not needed, remove them.
1269 AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1270 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1271 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1272 AudioVolume::GetInstance()->SetStreamVolumeLowPowerFactor(dualToneStreamIndex_, lowPowerVolume_);
1273 }
1274 if (status_ == I_STATUS_STARTED) {
1275 AUDIO_INFO_LOG("Renderer %{public}u is already running, let's start the dual stream", dualToneStreamIndex_);
1276 stream_->GetAudioEffectMode(effectModeWhenDual_);
1277 stream_->SetAudioEffectMode(EFFECT_NONE);
1278 std::lock_guard<std::mutex> lock(dualToneMutex_);
1279 //Locking before SetAudioEffectMode/GetAudioEffectMode results in a deadlock.
1280 if (dualToneStream_ != nullptr) {
1281 //Since there was no lock protection before the last time it was awarded dualToneStream_ it was
1282 //modified elsewhere, it was decided again after the lock was awarded.
1283 dualToneStream_->SetAudioEffectMode(EFFECT_NONE);
1284 dualToneStream_->Start();
1285 }
1286 }
1287 return SUCCESS;
1288 }
1289
StreamCallbacks(uint32_t streamIndex)1290 StreamCallbacks::StreamCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex)
1291 {
1292 AUDIO_INFO_LOG("DupStream %{public}u create StreamCallbacks", streamIndex_);
1293 }
1294
OnStatusUpdate(IOperation operation)1295 void StreamCallbacks::OnStatusUpdate(IOperation operation)
1296 {
1297 AUDIO_INFO_LOG("DupStream %{public}u recv operation: %{public}d", streamIndex_, operation);
1298 }
1299
OnWriteData(size_t length)1300 int32_t StreamCallbacks::OnWriteData(size_t length)
1301 {
1302 Trace trace("DupStream::OnWriteData length " + std::to_string(length));
1303 return SUCCESS;
1304 }
1305
SetOffloadMode(int32_t state,bool isAppBack)1306 int32_t RendererInServer::SetOffloadMode(int32_t state, bool isAppBack)
1307 {
1308 int32_t ret = stream_->SetOffloadMode(state, isAppBack);
1309 {
1310 std::lock_guard<std::mutex> lock(dupMutex_);
1311 for (auto &capInfo : captureInfos_) {
1312 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1313 capInfo.second.dupStream->UpdateMaxLength(350); // 350 for cover offload
1314 }
1315 }
1316 }
1317 if (isDualToneEnabled_) {
1318 std::lock_guard<std::mutex> lock(dualToneMutex_);
1319 if (dualToneStream_ != nullptr) {
1320 dualToneStream_->UpdateMaxLength(350); // 350 for cover offload
1321 }
1322 }
1323 return ret;
1324 }
1325
UnsetOffloadMode()1326 int32_t RendererInServer::UnsetOffloadMode()
1327 {
1328 int32_t ret = stream_->UnsetOffloadMode();
1329 {
1330 std::lock_guard<std::mutex> lock(dupMutex_);
1331 for (auto &capInfo : captureInfos_) {
1332 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1333 capInfo.second.dupStream->UpdateMaxLength(20); // 20 for unset offload
1334 }
1335 }
1336 }
1337 if (isDualToneEnabled_) {
1338 std::lock_guard<std::mutex> lock(dualToneMutex_);
1339 if (dualToneStream_ != nullptr) {
1340 dualToneStream_->UpdateMaxLength(20); // 20 for cover offload
1341 }
1342 }
1343 return ret;
1344 }
1345
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)1346 int32_t RendererInServer::GetOffloadApproximatelyCacheTime(uint64_t ×tamp, uint64_t &paWriteIndex,
1347 uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
1348 {
1349 return stream_->GetOffloadApproximatelyCacheTime(timestamp, paWriteIndex, cacheTimeDsp, cacheTimePa);
1350 }
1351
OffloadSetVolumeInner()1352 int32_t RendererInServer::OffloadSetVolumeInner()
1353 {
1354 AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(processConfig_.streamType);
1355 float volume = AudioVolume::GetInstance()->GetVolume(streamIndex_, volumeType, "offload");
1356 AUDIO_INFO_LOG("sessionID %{public}u [volumeType:%{public}d volume: %{public}f]",
1357 streamIndex_, volumeType, volume);
1358 float volumeHistory = AudioVolume::GetInstance()->GetHistoryVolume(streamIndex_);
1359 if (!IsVolumeSame(volumeHistory, volume, AUDIO_VOLOMUE_EPSILON)) {
1360 AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, volume);
1361 AudioVolume::GetInstance()->Monitor(streamIndex_, true);
1362 }
1363 return stream_->OffloadSetVolume(volume);
1364 }
1365
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)1366 int32_t RendererInServer::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
1367 {
1368 return stream_->UpdateSpatializationState(spatializationEnabled, headTrackingEnabled);
1369 }
1370
GetStreamManagerType() const1371 int32_t RendererInServer::GetStreamManagerType() const noexcept
1372 {
1373 return managerType_ == DIRECT_PLAYBACK ? AUDIO_DIRECT_MANAGER_TYPE : AUDIO_NORMAL_MANAGER_TYPE;
1374 }
1375
IsHighResolution() const1376 bool RendererInServer::IsHighResolution() const noexcept
1377 {
1378 Trace trace("CheckHighResolution");
1379 if (processConfig_.deviceType != DEVICE_TYPE_WIRED_HEADSET &&
1380 processConfig_.deviceType != DEVICE_TYPE_USB_HEADSET) {
1381 AUDIO_INFO_LOG("normal stream,device type:%{public}d", processConfig_.deviceType);
1382 return false;
1383 }
1384 if (processConfig_.streamType != STREAM_MUSIC || processConfig_.streamInfo.samplingRate < SAMPLE_RATE_48000 ||
1385 processConfig_.streamInfo.format < SAMPLE_S24LE ||
1386 processConfig_.rendererInfo.pipeType != PIPE_TYPE_DIRECT_MUSIC) {
1387 AUDIO_INFO_LOG("normal stream because stream info");
1388 return false;
1389 }
1390 if (processConfig_.streamInfo.samplingRate > SAMPLE_RATE_192000) {
1391 AUDIO_INFO_LOG("sample rate over 192k");
1392 return false;
1393 }
1394 if (IStreamManager::GetPlaybackManager(DIRECT_PLAYBACK).GetStreamCount() > 0) {
1395 AUDIO_INFO_LOG("high resolution exist.");
1396 return false;
1397 }
1398 return true;
1399 }
1400
SetSilentModeAndMixWithOthers(bool on)1401 int32_t RendererInServer::SetSilentModeAndMixWithOthers(bool on)
1402 {
1403 silentModeAndMixWithOthers_ = on;
1404 AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", on);
1405 bool isMuted = (isMuted_ || on || muteFlag_);
1406 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1407 for (auto &capInfo : captureInfos_) {
1408 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1409 AudioVolume::GetInstance()->SetStreamVolumeMute(
1410 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1411 }
1412 }
1413 if (isDualToneEnabled_) {
1414 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1415 }
1416 if (offloadEnable_) {
1417 OffloadSetVolumeInner();
1418 }
1419 return SUCCESS;
1420 }
1421
SetClientVolume()1422 int32_t RendererInServer::SetClientVolume()
1423 {
1424 if (audioServerBuffer_ == nullptr || playerDfx_ == nullptr) {
1425 AUDIO_WARNING_LOG("buffer in not inited");
1426 return ERROR;
1427 }
1428 float clientVolume = audioServerBuffer_->GetStreamVolume();
1429 int32_t ret = stream_->SetClientVolume(clientVolume);
1430 SetStreamVolumeInfoForEnhanceChain();
1431 AudioVolume::GetInstance()->SetStreamVolume(streamIndex_, clientVolume);
1432 for (auto &capInfo : captureInfos_) {
1433 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1434 AudioVolume::GetInstance()->SetStreamVolume(
1435 capInfo.second.dupStream->GetStreamIndex(), clientVolume);
1436 }
1437 }
1438 if (isDualToneEnabled_) {
1439 AudioVolume::GetInstance()->SetStreamVolume(dualToneStreamIndex_, clientVolume);
1440 }
1441 if (offloadEnable_) {
1442 OffloadSetVolumeInner();
1443 }
1444
1445 RendererStage stage = clientVolume == 0 ? RENDERER_STAGE_SET_VOLUME_ZERO : RENDERER_STAGE_SET_VOLUME_NONZERO;
1446 playerDfx_->WriteDfxActionMsg(streamIndex_, stage);
1447 return ret;
1448 }
1449
SetMute(bool isMute)1450 int32_t RendererInServer::SetMute(bool isMute)
1451 {
1452 isMuted_ = isMute;
1453 AUDIO_INFO_LOG("SetStreamVolumeMute:%{public}d", isMute);
1454 bool isMuted = (isMute || silentModeAndMixWithOthers_ || muteFlag_);
1455 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1456 for (auto &capInfo : captureInfos_) {
1457 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1458 AudioVolume::GetInstance()->SetStreamVolumeMute(
1459 capInfo.second.dupStream->GetStreamIndex(), isMuted);
1460 }
1461 }
1462 if (isDualToneEnabled_) {
1463 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1464 }
1465 if (offloadEnable_) {
1466 OffloadSetVolumeInner();
1467 }
1468 return SUCCESS;
1469 }
1470
SetDuckFactor(float duckFactor)1471 int32_t RendererInServer::SetDuckFactor(float duckFactor)
1472 {
1473 if (duckFactor < MIN_FLOAT_VOLUME || duckFactor > MAX_FLOAT_VOLUME) {
1474 AUDIO_ERR_LOG("invalid duck volume:%{public}f", duckFactor);
1475 return ERR_INVALID_PARAM;
1476 }
1477 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(streamIndex_, duckFactor);
1478 for (auto &capInfo : captureInfos_) {
1479 if (capInfo.second.isInnerCapEnabled && capInfo.second.dupStream != nullptr) {
1480 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(
1481 capInfo.second.dupStream->GetStreamIndex(), duckFactor);
1482 }
1483 }
1484 if (isDualToneEnabled_) {
1485 AudioVolume::GetInstance()->SetStreamVolumeDuckFactor(dualToneStreamIndex_, duckFactor);
1486 }
1487 if (offloadEnable_) {
1488 OffloadSetVolumeInner();
1489 }
1490 return SUCCESS;
1491 }
1492
SetStreamVolumeInfoForEnhanceChain()1493 int32_t RendererInServer::SetStreamVolumeInfoForEnhanceChain()
1494 {
1495 uint32_t sessionId = streamIndex_;
1496 float streamVolume = audioServerBuffer_->GetStreamVolume();
1497 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
1498 CHECK_AND_RETURN_RET_LOG(audioEnhanceChainManager != nullptr, ERROR, "audioEnhanceChainManager is nullptr");
1499 int32_t ret = audioEnhanceChainManager->SetStreamVolumeInfo(sessionId, streamVolume);
1500 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetStreamVolumeInfo failed");
1501 return ret;
1502 }
1503
OnDataLinkConnectionUpdate(IOperation operation)1504 void RendererInServer::OnDataLinkConnectionUpdate(IOperation operation)
1505 {
1506 std::shared_ptr<IStreamListener> stateListener = streamListener_.lock();
1507 CHECK_AND_RETURN_LOG(stateListener != nullptr, "StreamListener is nullptr");
1508 switch (operation) {
1509 case OPERATION_DATA_LINK_CONNECTING:
1510 AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTING received");
1511 stateListener->OnOperationHandled(DATA_LINK_CONNECTING, 0);
1512 break;
1513 case OPERATION_DATA_LINK_CONNECTED:
1514 AUDIO_DEBUG_LOG("OPERATION_DATA_LINK_CONNECTED received");
1515 stateListener->OnOperationHandled(DATA_LINK_CONNECTED, 0);
1516 break;
1517 default:
1518 return;
1519 }
1520 }
1521
GetActualStreamManagerType() const1522 int32_t RendererInServer::GetActualStreamManagerType() const noexcept
1523 {
1524 return managerType_;
1525 }
1526
GetStatusStr(IStatus status)1527 static std::string GetStatusStr(IStatus status)
1528 {
1529 switch (status) {
1530 case I_STATUS_INVALID:
1531 return "INVALID";
1532 case I_STATUS_IDLE:
1533 return "IDEL";
1534 case I_STATUS_STARTING:
1535 return "STARTING";
1536 case I_STATUS_STARTED:
1537 return "STARTED";
1538 case I_STATUS_PAUSING:
1539 return "PAUSING";
1540 case I_STATUS_PAUSED:
1541 return "PAUSED";
1542 case I_STATUS_FLUSHING_WHEN_STARTED:
1543 return "FLUSHING_WHEN_STARTED";
1544 case I_STATUS_FLUSHING_WHEN_PAUSED:
1545 return "FLUSHING_WHEN_PAUSED";
1546 case I_STATUS_FLUSHING_WHEN_STOPPED:
1547 return "FLUSHING_WHEN_STOPPED";
1548 case I_STATUS_DRAINING:
1549 return "DRAINING";
1550 case I_STATUS_DRAINED:
1551 return "DRAINED";
1552 case I_STATUS_STOPPING:
1553 return "STOPPING";
1554 case I_STATUS_STOPPED:
1555 return "STOPPED";
1556 case I_STATUS_RELEASING:
1557 return "RELEASING";
1558 case I_STATUS_RELEASED:
1559 return "RELEASED";
1560 default:
1561 break;
1562 }
1563 return "NO_SUCH_STATUS";
1564 }
1565
GetManagerTypeStr(ManagerType type)1566 static std::string GetManagerTypeStr(ManagerType type)
1567 {
1568 switch (type) {
1569 case PLAYBACK:
1570 return "Normal";
1571 case DUP_PLAYBACK:
1572 return "Dup Playback";
1573 case DUAL_PLAYBACK:
1574 return "DUAL Playback";
1575 case DIRECT_PLAYBACK:
1576 return "Direct";
1577 case VOIP_PLAYBACK:
1578 return "Voip";
1579 case RECORDER:
1580 return "Recorder";
1581 default:
1582 break;
1583 }
1584 return "NO_SUCH_TYPE";
1585 }
1586
Dump(std::string & dumpString)1587 bool RendererInServer::Dump(std::string &dumpString)
1588 {
1589 if (managerType_ != DIRECT_PLAYBACK && managerType_ != VOIP_PLAYBACK) {
1590 return false;
1591 }
1592 // dump audio stream info
1593 dumpString += "audio stream info:\n";
1594 AppendFormat(dumpString, " - session id:%u\n", streamIndex_);
1595 AppendFormat(dumpString, " - appid:%d\n", processConfig_.appInfo.appPid);
1596 AppendFormat(dumpString, " - stream type:%d\n", processConfig_.streamType);
1597
1598 AppendFormat(dumpString, " - samplingRate: %d\n", processConfig_.streamInfo.samplingRate);
1599 AppendFormat(dumpString, " - channels: %u\n", processConfig_.streamInfo.channels);
1600 AppendFormat(dumpString, " - format: %u\n", processConfig_.streamInfo.format);
1601 AppendFormat(dumpString, " - device type: %u\n", processConfig_.deviceType);
1602 AppendFormat(dumpString, " - sink type: %s\n", GetManagerTypeStr(managerType_).c_str());
1603
1604 // dump status info
1605 AppendFormat(dumpString, " - Current stream status: %s\n", GetStatusStr(status_).c_str());
1606 if (audioServerBuffer_ != nullptr) {
1607 AppendFormat(dumpString, " - Current read position: %u\n", audioServerBuffer_->GetCurReadFrame());
1608 AppendFormat(dumpString, " - Current write position: %u\n", audioServerBuffer_->GetCurWriteFrame());
1609 }
1610
1611 dumpString += "\n";
1612 return true;
1613 }
1614
SetNonInterruptMute(const bool muteFlag)1615 void RendererInServer::SetNonInterruptMute(const bool muteFlag)
1616 {
1617 AUDIO_INFO_LOG("mute flag %{public}d", muteFlag);
1618 muteFlag_ = muteFlag;
1619 AudioService::GetInstance()->UpdateMuteControlSet(streamIndex_, muteFlag);
1620
1621 bool isMuted = (isMuted_ || silentModeAndMixWithOthers_ || muteFlag);
1622 AudioVolume::GetInstance()->SetStreamVolumeMute(streamIndex_, isMuted);
1623 for (auto &captureInfo : captureInfos_) {
1624 if (captureInfo.second.isInnerCapEnabled && captureInfo.second.dupStream != nullptr) {
1625 AudioVolume::GetInstance()->SetStreamVolumeMute(
1626 captureInfo.second.dupStream->GetStreamIndex(), isMuted);
1627 }
1628 }
1629 if (isDualToneEnabled_) {
1630 AudioVolume::GetInstance()->SetStreamVolumeMute(dualToneStreamIndex_, isMuted);
1631 }
1632 if (offloadEnable_) {
1633 OffloadSetVolumeInner();
1634 }
1635 }
1636
RestoreSession(RestoreInfo restoreInfo)1637 RestoreStatus RendererInServer::RestoreSession(RestoreInfo restoreInfo)
1638 {
1639 RestoreStatus restoreStatus = audioServerBuffer_->SetRestoreStatus(NEED_RESTORE);
1640 if (restoreStatus == NEED_RESTORE) {
1641 audioServerBuffer_->SetRestoreInfo(restoreInfo);
1642 }
1643 return restoreStatus;
1644 }
1645
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)1646 int32_t RendererInServer::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
1647 {
1648 return PolicyHandler::GetInstance().SetDefaultOutputDevice(defaultOutputDevice, streamIndex_,
1649 processConfig_.rendererInfo.streamUsage, status_ == I_STATUS_STARTED);
1650 }
1651
SetSourceDuration(int64_t duration)1652 int32_t RendererInServer::SetSourceDuration(int64_t duration)
1653 {
1654 sourceDuration_ = duration;
1655 return SUCCESS;
1656 }
1657
1658 } // namespace AudioStandard
1659 } // namespace OHOS
1660