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
16 #include "audio_sink.h"
17 #include "syspara/parameters.h"
18 #include "plugin/plugin_manager_v2.h"
19 #include "common/log.h"
20 #include "calc_max_amplitude.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "AudioSink" };
24 constexpr int64_t MAX_BUFFER_DURATION_US = 200000; // Max buffer duration is 200 ms
25 constexpr int64_t US_TO_MS = 1000; // 1000 us per ms
26 constexpr int64_t ANCHOR_UPDATE_PERIOD_US = 200000; // Update time anchor every 200 ms
27 constexpr int64_t DRAIN_TIME_DIFF_WARN_MS = 40;
28 constexpr int64_t DRAIN_TIME_DIFF_INFO_MS = 20;
29 constexpr int64_t AUDIO_SAMPLE_8_BIT = 1;
30 constexpr int64_t AUDIO_SAMPLE_16_BIT = 2;
31 constexpr int64_t AUDIO_SAMPLE_24_BIT = 3;
32 constexpr int64_t AUDIO_SAMPLE_32_BIT = 4;
33 constexpr int64_t SEC_TO_US = 1000 * 1000;
34 constexpr int64_t EOS_CALLBACK_WAIT_MS = 500;
35 constexpr int32_t BOOT_APP_UID = 1003;
36 }
37
38 namespace OHOS {
39 namespace Media {
40
41 const int32_t DEFAULT_BUFFER_QUEUE_SIZE = 8;
42 const int32_t APE_BUFFER_QUEUE_SIZE = 30;
43 const int64_t DEFAULT_PLAY_RANGE_VALUE = -1;
44 const int64_t MICROSECONDS_CONVERT_UNITS = 1000;
45
GetAudioLatencyFixDelay()46 int64_t GetAudioLatencyFixDelay()
47 {
48 constexpr uint64_t defaultValue = 120 * HST_USECOND;
49 static uint64_t fixDelay = OHOS::system::GetUintParameter("debug.media_service.audio_sync_fix_delay", defaultValue);
50 MEDIA_LOG_I("audio_sync_fix_delay, pid:%{public}d, fixdelay: " PUBLIC_LOG_U64, getprocpid(), fixDelay);
51 return static_cast<int64_t>(fixDelay);
52 }
53
AudioSink()54 AudioSink::AudioSink()
55 {
56 MEDIA_LOG_I("Tips AudioSink ctor");
57 syncerPriority_ = IMediaSynchronizer::AUDIO_SINK;
58 fixDelay_ = GetAudioLatencyFixDelay();
59 plugin_ = CreatePlugin();
60 }
61
~AudioSink()62 AudioSink::~AudioSink()
63 {
64 MEDIA_LOG_D("AudioSink dtor");
65 }
66
AudioSinkDataCallbackImpl(std::shared_ptr<AudioSink> sink)67 AudioSink::AudioSinkDataCallbackImpl::AudioSinkDataCallbackImpl(std::shared_ptr<AudioSink> sink): audioSink_(sink) {}
68
OnWriteData(int32_t size,bool isAudioVivid)69 void AudioSink::AudioSinkDataCallbackImpl::OnWriteData(int32_t size, bool isAudioVivid)
70 {
71 auto sink = audioSink_.lock();
72 FALSE_RETURN_MSG(sink != nullptr, "audioSink_ is nullptr");
73 AudioStandard::BufferDesc bufferDesc;
74 Status ret = sink->GetBufferDesc(bufferDesc);
75 FALSE_RETURN_MSG(ret == Status::OK, "GetBufferDesc fail, ret=" PUBLIC_LOG_D32, ret);
76 bufferDesc.dataLength = 0;
77
78 if (sink->IsInputBufferDataEnough(size, isAudioVivid)) {
79 bool isCopySucess = sink->HandleAudioRenderRequest(static_cast<size_t>(size),
80 isAudioVivid, bufferDesc);
81 bufferDesc.dataLength = isCopySucess ? bufferDesc.dataLength : 0;
82 }
83 ret = sink->EnqueueBufferDesc(bufferDesc);
84 sink->HandleAudioRenderRequestPost();
85 FALSE_RETURN_MSG(ret == Status::OK, "enqueue failed, ret=" PUBLIC_LOG_D32, ret);
86 }
87
HandleAudioRenderRequest(size_t size,bool isAudioVivid,AudioStandard::BufferDesc & bufferDesc)88 bool AudioSink::HandleAudioRenderRequest(size_t size, bool isAudioVivid, AudioStandard::BufferDesc &bufferDesc)
89 {
90 FALSE_RETURN_V(!eosDraining_, false);
91 bool isCopySucess = CopyDataToBufferDesc(static_cast<size_t>(size), isAudioVivid, bufferDesc);
92 FALSE_RETURN_V_MSG_D(isCopySucess, false, "CopyDataToBufferDesc failed");
93 UpdateAudioWriteTimeMayWait();
94 SyncWriteByRenderInfo();
95 UpdateAmplitude();
96 return true;
97 }
98
HandleAudioRenderRequestPost()99 void AudioSink::HandleAudioRenderRequestPost()
100 {
101 std::lock_guard<std::mutex> lock(availBufferMutex_);
102 if (appUid_ == BOOT_APP_UID && isEosBuffer_ && availOutputBuffers_.empty()) {
103 std::unique_lock<std::mutex> eosCbLock(eosCbMutex_);
104 hangeOnEosCb_ = true;
105 eosCbCond_.wait_for(eosCbLock, std::chrono::milliseconds(EOS_CALLBACK_WAIT_MS),
106 [this] () { return !hangeOnEosCb_; });
107 }
108 FALSE_RETURN_NOLOG(isEosBuffer_);
109 FALSE_RETURN_NOLOG(!availOutputBuffers_.empty());
110 auto cacheBuffer = availOutputBuffers_.front();
111 FALSE_RETURN(cacheBuffer != nullptr);
112 FALSE_RETURN(IsEosBuffer(cacheBuffer));
113 availOutputBuffers_.pop();
114 HandleEosBuffer(cacheBuffer);
115 }
116
GetBufferDesc(AudioStandard::BufferDesc & bufferDesc)117 Status AudioSink::GetBufferDesc(AudioStandard::BufferDesc &bufferDesc)
118 {
119 FALSE_RETURN_V_MSG(plugin_ != nullptr, Status::ERROR_UNKNOWN, "GetBufferDesc audioSinkPlugin is nullptr");
120 return plugin_->GetBufferDesc(bufferDesc);
121 }
122
EnqueueBufferDesc(const AudioStandard::BufferDesc & bufferDesc)123 Status AudioSink::EnqueueBufferDesc(const AudioStandard::BufferDesc &bufferDesc)
124 {
125 FALSE_RETURN_V_MSG(plugin_ != nullptr, Status::ERROR_UNKNOWN, "Enqueue audioSinkPlugin is nullptr");
126 return plugin_->EnqueueBufferDesc(bufferDesc);
127 }
128
IsInputBufferDataEnough(int32_t size,bool isAudioVivid)129 bool AudioSink::IsInputBufferDataEnough(int32_t size, bool isAudioVivid)
130 {
131 std::lock_guard<std::mutex> lock(availBufferMutex_);
132 if (!isAudioVivid) {
133 maxCbDataSize_ = std::max(maxCbDataSize_, size);
134 } else {
135 // audioVivid use min(size, availDataSize) as maxDataSize to ensure that audioVivid dont use swapBuffers
136 size_t availDataSize = availDataSize_.load();
137 int32_t availDataSizeInt32 = availDataSize <= static_cast<size_t>(INT32_MAX) ?
138 static_cast<int32_t>(availDataSize): INT32_MAX;
139 maxCbDataSize_ = std::min(size, availDataSizeInt32);
140 }
141 DriveBufferCircle();
142 return availDataSize_.load() >= static_cast<size_t>(size) || isEosBuffer_;
143 }
144
Init(std::shared_ptr<Meta> & meta,const std::shared_ptr<Pipeline::EventReceiver> & receiver)145 Status AudioSink::Init(std::shared_ptr<Meta>& meta, const std::shared_ptr<Pipeline::EventReceiver>& receiver)
146 {
147 state_ = Pipeline::FilterState::INITIALIZED;
148 Status ret = InitAudioSinkPlugin(meta, receiver);
149 FALSE_RETURN_V(ret == Status::OK, ret);
150 ret = InitAudioSinkInfo(meta);
151 FALSE_RETURN_V(ret == Status::OK, ret);
152 return Status::OK;
153 }
154
InitAudioSinkPlugin(std::shared_ptr<Meta> & meta,const std::shared_ptr<Pipeline::EventReceiver> & receiver)155 Status AudioSink::InitAudioSinkPlugin(std::shared_ptr<Meta>& meta,
156 const std::shared_ptr<Pipeline::EventReceiver>& receiver)
157 {
158 FALSE_RETURN_V(plugin_ != nullptr, Status::ERROR_NULL_POINTER);
159 FALSE_RETURN_V(meta != nullptr, Status::ERROR_NULL_POINTER);
160 meta->SetData(Tag::APP_PID, appPid_);
161 meta->SetData(Tag::APP_UID, appUid_);
162 plugin_->SetEventReceiver(receiver);
163 plugin_->SetParameter(meta);
164 plugin_->Init();
165 if (isCallbackMode_) {
166 audioSinkDataCallback_ = std::make_shared<AudioSinkDataCallbackImpl>(shared_from_this());
167 Status ret = plugin_->SetRequestDataCallback(audioSinkDataCallback_);
168 isCallbackMode_ = ret == Status::OK ? true : false;
169 }
170 plugin_->Prepare();
171 plugin_->SetMuted(isMuted_);
172 return Status::OK;
173 }
174
InitAudioSinkInfo(std::shared_ptr<Meta> & meta)175 Status AudioSink::InitAudioSinkInfo(std::shared_ptr<Meta>& meta)
176 {
177 FALSE_RETURN_V(meta != nullptr, Status::ERROR_NULL_POINTER);
178 meta->GetData(Tag::AUDIO_SAMPLE_RATE, sampleRate_);
179 meta->GetData(Tag::AUDIO_SAMPLE_PER_FRAME, samplePerFrame_);
180 meta->GetData(Tag::AUDIO_CHANNEL_COUNT, audioChannelCount_);
181 if (samplePerFrame_ > 0 && sampleRate_ > 0) {
182 playingBufferDurationUs_ = static_cast<int64_t>(samplePerFrame_) * SEC_TO_US / sampleRate_;
183 }
184 MEDIA_LOG_I("Audiosink playingBufferDurationUs_ = " PUBLIC_LOG_D64, playingBufferDurationUs_);
185 std::string mime;
186 bool mimeGetRes = meta->Get<Tag::MIME_TYPE>(mime);
187 if (mimeGetRes && mime == "audio/x-ape") {
188 isApe_ = true;
189 MEDIA_LOG_I("AudioSink::Init is ape");
190 }
191 if (mimeGetRes && mime == "audio/flac") {
192 isFlac_ = true;
193 MEDIA_LOG_I("AudioSink::Init is flac");
194 }
195
196 return Status::OK;
197 }
198
NeedImmediateRender()199 bool AudioSink::NeedImmediateRender()
200 {
201 return isApe_ || isFlac_;
202 }
203
GetBufferQueueProducer()204 sptr<AVBufferQueueProducer> AudioSink::GetBufferQueueProducer()
205 {
206 if (state_ != Pipeline::FilterState::READY) {
207 return nullptr;
208 }
209 return inputBufferQueueProducer_;
210 }
211
GetBufferQueueConsumer()212 sptr<AVBufferQueueConsumer> AudioSink::GetBufferQueueConsumer()
213 {
214 if (state_ != Pipeline::FilterState::READY) {
215 return nullptr;
216 }
217 return inputBufferQueueConsumer_;
218 }
219
SetParameter(const std::shared_ptr<Meta> & meta)220 Status AudioSink::SetParameter(const std::shared_ptr<Meta>& meta)
221 {
222 UpdateMediaTimeRange(meta);
223 FALSE_RETURN_V(meta != nullptr, Status::ERROR_NULL_POINTER);
224 meta->GetData(Tag::APP_PID, appPid_);
225 meta->GetData(Tag::APP_UID, appUid_);
226 FALSE_RETURN_V(plugin_ != nullptr, Status::ERROR_NULL_POINTER);
227 plugin_->SetParameter(meta);
228 return Status::OK;
229 }
230
GetParameter(std::shared_ptr<Meta> & meta)231 Status AudioSink::GetParameter(std::shared_ptr<Meta>& meta)
232 {
233 return plugin_->GetParameter(meta);
234 }
235
Prepare()236 Status AudioSink::Prepare()
237 {
238 state_ = Pipeline::FilterState::PREPARING;
239 Status ret = PrepareInputBufferQueue();
240 if (ret != Status::OK) {
241 state_ = Pipeline::FilterState::INITIALIZED;
242 return ret;
243 }
244 state_ = Pipeline::FilterState::READY;
245 {
246 AutoLock lock(eosMutex_);
247 eosInterruptType_ = EosInterruptState::NONE;
248 eosDraining_ = false;
249 }
250 return ret;
251 }
252
Start()253 Status AudioSink::Start()
254 {
255 Status ret = plugin_->Start();
256 if (ret != Status::OK) {
257 MEDIA_LOG_I("AudioSink start error " PUBLIC_LOG_D32, ret);
258 return ret;
259 }
260 isEos_ = false;
261 state_ = Pipeline::FilterState::RUNNING;
262 return ret;
263 }
264
Stop()265 Status AudioSink::Stop()
266 {
267 std::lock_guard<std::mutex> lockPlugin(pluginMutex_);
268 playRangeStartTime_ = DEFAULT_PLAY_RANGE_VALUE;
269 playRangeEndTime_ = DEFAULT_PLAY_RANGE_VALUE;
270 Status ret = plugin_->Stop();
271 underrunDetector_.Reset();
272 lagDetector_.Reset();
273 ResetInfo();
274 if (ret != Status::OK) {
275 return ret;
276 }
277 state_ = Pipeline::FilterState::INITIALIZED;
278 AutoLock lock(eosMutex_);
279 if (eosInterruptType_ != EosInterruptState::NONE) {
280 eosInterruptType_ = EosInterruptState::STOP;
281 }
282 return ret;
283 }
284
Pause()285 Status AudioSink::Pause()
286 {
287 Status ret = Status::OK;
288 underrunDetector_.Reset();
289 lagDetector_.Reset();
290 if (appUid_ == BOOT_APP_UID) {
291 if (eosTask_ != nullptr) {
292 eosTask_->SubmitJobOnce([this] {
293 {
294 std::unique_lock<std::mutex> eosCbLock(eosCbMutex_);
295 hangeOnEosCb_ = false;
296 eosCbCond_.notify_all();
297 }
298 plugin_->PauseTransitent();
299 });
300 }
301 } else if (isTransitent_ || (isEos_ && (isCalledBySystemApp_ || isLoop_))) {
302 ret = plugin_->PauseTransitent();
303 } else {
304 ret = plugin_->Pause();
305 }
306 forceUpdateTimeAnchorNextTime_ = true;
307 if (ret != Status::OK) {
308 return ret;
309 }
310 state_ = Pipeline::FilterState::PAUSED;
311 AutoLock lock(eosMutex_);
312 if (eosInterruptType_ == EosInterruptState::INITIAL || eosInterruptType_ == EosInterruptState::RESUME) {
313 eosInterruptType_ = EosInterruptState::PAUSE;
314 }
315 return ret;
316 }
317
Resume()318 Status AudioSink::Resume()
319 {
320 lagDetector_.Reset();
321 Status ret = plugin_->Resume();
322 if (ret != Status::OK) {
323 MEDIA_LOG_I("AudioSink resume error " PUBLIC_LOG_D32, ret);
324 return ret;
325 }
326 state_ = Pipeline::FilterState::RUNNING;
327 AutoLock lock(eosMutex_);
328 if (eosInterruptType_ == EosInterruptState::PAUSE) {
329 eosInterruptType_ = EosInterruptState::RESUME;
330 if (!eosDraining_ && eosTask_ != nullptr) {
331 eosTask_->SubmitJobOnce([this] {
332 HandleEosInner(false);
333 });
334 }
335 }
336 return ret;
337 }
338
Flush()339 Status AudioSink::Flush()
340 {
341 std::lock_guard<std::mutex> lockPlugin(pluginMutex_);
342 MEDIA_LOG_D("do audioSink flush");
343 underrunDetector_.Reset();
344 lagDetector_.Reset();
345
346 {
347 AutoLock lock(eosMutex_);
348 eosInterruptType_ = EosInterruptState::NONE;
349 eosDraining_ = false;
350 }
351 Status ret = Status::OK;
352 ret = plugin_->Flush();
353 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "plugin flush failed");
354 ResetInfo();
355 return Status::OK;
356 }
357
Release()358 Status AudioSink::Release()
359 {
360 underrunDetector_.Reset();
361 lagDetector_.Reset();
362 ResetInfo();
363 return plugin_->Deinit();
364 }
365
SetPlayRange(int64_t start,int64_t end)366 Status AudioSink::SetPlayRange(int64_t start, int64_t end)
367 {
368 MEDIA_LOG_I("SetPlayRange enter.");
369 playRangeStartTime_ = start;
370 playRangeEndTime_ = end;
371 return Status::OK;
372 }
373
SetVolumeMode(int32_t mode)374 Status AudioSink::SetVolumeMode(int32_t mode)
375 {
376 if (plugin_ == nullptr) {
377 return Status::ERROR_NULL_POINTER;
378 }
379 return plugin_->SetVolumeMode(mode);
380 }
381
SetVolume(float volume)382 Status AudioSink::SetVolume(float volume)
383 {
384 if (plugin_ == nullptr) {
385 return Status::ERROR_NULL_POINTER;
386 }
387 if (volume < 0) {
388 return Status::ERROR_INVALID_PARAMETER;
389 }
390 volume_ = volume;
391 return plugin_->SetVolume(volume);
392 }
393
SetVolumeWithRamp(float targetVolume,int32_t duration)394 int32_t AudioSink::SetVolumeWithRamp(float targetVolume, int32_t duration)
395 {
396 MEDIA_LOG_I("SetVolumeWithRamp");
397 return plugin_->SetVolumeWithRamp(targetVolume, duration);
398 }
399
SetIsTransitent(bool isTransitent)400 Status AudioSink::SetIsTransitent(bool isTransitent)
401 {
402 MEDIA_LOG_I("SetIsTransitent");
403 isTransitent_ = isTransitent;
404 return Status::OK;
405 }
406
PrepareInputBufferQueue()407 Status AudioSink::PrepareInputBufferQueue()
408 {
409 if (inputBufferQueue_ != nullptr && inputBufferQueue_-> GetQueueSize() > 0) {
410 MEDIA_LOG_I("InputBufferQueue already create");
411 return Status::ERROR_INVALID_OPERATION;
412 }
413 int32_t inputBufferSize = isApe_ ? APE_BUFFER_QUEUE_SIZE : DEFAULT_BUFFER_QUEUE_SIZE;
414 MemoryType memoryType = MemoryType::SHARED_MEMORY;
415 #ifndef MEDIA_OHOS
416 memoryType = MemoryType::VIRTUAL_MEMORY;
417 #endif
418 bufferMemoryType_ = memoryType;
419 MEDIA_LOG_I("PrepareInputBufferQueue ");
420 inputBufferQueue_ = AVBufferQueue::Create(inputBufferSize, memoryType, INPUT_BUFFER_QUEUE_NAME);
421 inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
422 inputBufferQueueConsumer_ = inputBufferQueue_->GetConsumer();
423 return Status::OK;
424 }
425
CreatePlugin()426 std::shared_ptr<Plugins::AudioSinkPlugin> AudioSink::CreatePlugin()
427 {
428 auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(Plugins::PluginType::AUDIO_SINK, "audio/raw");
429 if (plugin == nullptr) {
430 return nullptr;
431 }
432 return std::reinterpret_pointer_cast<Plugins::AudioSinkPlugin>(plugin);
433 }
434
UpdateAudioWriteTimeMayWait()435 void AudioSink::UpdateAudioWriteTimeMayWait()
436 {
437 if (latestBufferDuration_ <= 0) {
438 return;
439 }
440 if (latestBufferDuration_ > MAX_BUFFER_DURATION_US) {
441 latestBufferDuration_ = MAX_BUFFER_DURATION_US; // wait at most MAX_DURATION
442 }
443 int64_t timeNow = Plugins::HstTime2Us(SteadyClock::GetCurrentTimeNanoSec());
444 if (!lastBufferWriteSuccess_) {
445 int64_t writeSleepTime = latestBufferDuration_ - (timeNow - lastBufferWriteTime_);
446 MEDIA_LOG_W("Last buffer write fail, sleep time is " PUBLIC_LOG_D64 "us", writeSleepTime);
447 if (writeSleepTime > 0) {
448 usleep(writeSleepTime);
449 timeNow = Plugins::HstTime2Us(SteadyClock::GetCurrentTimeNanoSec());
450 }
451 }
452 lastBufferWriteTime_ = timeNow;
453 }
454
SetThreadGroupId(const std::string & groupId)455 void AudioSink::SetThreadGroupId(const std::string& groupId)
456 {
457 eosTask_ = std::make_unique<Task>("OS_EOSa", groupId, TaskType::AUDIO, TaskPriority::HIGH, false);
458 }
459
HandleEosInner(bool drain)460 void AudioSink::HandleEosInner(bool drain)
461 {
462 AutoLock lock(eosMutex_);
463 eosDraining_ = true; // start draining task
464 switch (eosInterruptType_) {
465 case EosInterruptState::INITIAL: // No user operation during EOS drain, complete drain normally
466 break;
467 case EosInterruptState::RESUME: // EOS drain is resumed after pause, do necessary changes
468 if (drain) {
469 // pause and resume happened before this task, audiosink latency should be updated
470 drain = false;
471 }
472 eosInterruptType_ = EosInterruptState::INITIAL; // Reset EOS draining state
473 break;
474 default: // EOS drain is interrupted by pause or stop, and not resumed
475 MEDIA_LOG_W("Drain audiosink interrupted");
476 eosDraining_ = false; // abort draining task
477 return;
478 }
479 if (drain || !plugin_->IsOffloading()) {
480 MEDIA_LOG_I("Drain audiosink and report EOS");
481 DrainAndReportEosEvent();
482 return;
483 }
484 uint64_t latency = 0;
485 if (plugin_->GetLatency(latency) != Status::OK) {
486 MEDIA_LOG_W("Failed to get latency, drain audiosink directly");
487 DrainAndReportEosEvent();
488 return;
489 }
490 if (eosTask_ == nullptr) {
491 MEDIA_LOG_W("Drain audiosink, eosTask_ is nullptr");
492 DrainAndReportEosEvent();
493 return;
494 }
495 MEDIA_LOG_I("Drain audiosink wait latency = " PUBLIC_LOG_U64, latency);
496 eosTask_->SubmitJobOnce([this] {
497 HandleEosInner(true);
498 }, latency, false);
499 }
500
DrainAndReportEosEvent()501 void AudioSink::DrainAndReportEosEvent()
502 {
503 plugin_->Drain();
504 if (appUid_ != BOOT_APP_UID) {
505 plugin_->PauseTransitent();
506 }
507 eosInterruptType_ = EosInterruptState::NONE;
508 eosDraining_ = false; // finish draining task
509 isEos_ = true;
510 auto syncCenter = syncCenter_.lock();
511 if (syncCenter) {
512 syncCenter->ReportEos(this);
513 }
514 Event event {
515 .srcFilter = "AudioSink",
516 .type = EventType::EVENT_COMPLETE,
517 };
518 FALSE_RETURN(playerEventReceiver_ != nullptr);
519 playerEventReceiver_->OnEvent(event);
520 }
521
CheckUpdateState(char * frame,uint64_t replyBytes,int32_t format)522 void AudioSink::CheckUpdateState(char *frame, uint64_t replyBytes, int32_t format)
523 {
524 FALSE_RETURN(frame != nullptr && replyBytes != 0);
525 auto currentMaxAmplitude = OHOS::Media::CalcMaxAmplitude::UpdateMaxAmplitude(frame, replyBytes, format);
526 currentMaxAmplitude_ = currentMaxAmplitude_ > currentMaxAmplitude ? currentMaxAmplitude_ : currentMaxAmplitude;
527 }
528
UpdateAmplitude()529 void AudioSink::UpdateAmplitude()
530 {
531 AutoLock amplitudeLock(amplitudeMutex_);
532 maxAmplitude_ = currentMaxAmplitude_ > maxAmplitude_ ? currentMaxAmplitude_ : maxAmplitude_;
533 }
534
GetMaxAmplitude()535 float AudioSink::GetMaxAmplitude()
536 {
537 AutoLock amplitudeLock(amplitudeMutex_);
538 auto ret = maxAmplitude_;
539 maxAmplitude_ = 0;
540 return ret;
541 }
542
CalcMaxAmplitude(std::shared_ptr<AVBuffer> filledOutputBuffer)543 void AudioSink::CalcMaxAmplitude(std::shared_ptr<AVBuffer> filledOutputBuffer)
544 {
545 FALSE_RETURN(filledOutputBuffer != nullptr);
546 auto mem = filledOutputBuffer->memory_;
547 FALSE_RETURN(mem != nullptr);
548 auto srcBuffer = mem->GetAddr();
549 auto destBuffer = const_cast<uint8_t *>(srcBuffer);
550 auto srcLength = mem->GetSize();
551 size_t destLength = static_cast<size_t>(srcLength);
552 int32_t format = plugin_->GetSampleFormat();
553 CheckUpdateState(reinterpret_cast<char *>(destBuffer), destLength, format);
554 }
555
DropApeBuffer(std::shared_ptr<AVBuffer> filledOutputBuffer)556 bool AudioSink::DropApeBuffer(std::shared_ptr<AVBuffer> filledOutputBuffer)
557 {
558 if (!isApe_ || seekTimeUs_ == HST_TIME_NONE) {
559 return false;
560 }
561 if (filledOutputBuffer->pts_ < seekTimeUs_) {
562 MEDIA_LOG_D("Drop ape buffer pts = " PUBLIC_LOG_D64, filledOutputBuffer->pts_);
563 inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer);
564 return true;
565 } else {
566 seekTimeUs_ = HST_TIME_NONE;
567 }
568 return false;
569 }
570
ClearInputBuffer()571 void AudioSink::ClearInputBuffer()
572 {
573 MEDIA_LOG_D("AudioSink::ClearInputBuffer enter");
574 if (!inputBufferQueueConsumer_) {
575 return;
576 }
577 std::shared_ptr<AVBuffer> filledInputBuffer;
578 Status ret = Status::OK;
579 while (ret == Status::OK) {
580 ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
581 if (ret != Status::OK) {
582 MEDIA_LOG_I("AudioSink::ClearInputBuffer clear input Buffer");
583 return;
584 }
585 inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
586 }
587 }
588
GetSampleFormatBytes()589 int32_t AudioSink::GetSampleFormatBytes()
590 {
591 int32_t format = 0;
592 switch (plugin_->GetSampleFormat()) {
593 case AudioSampleFormat::SAMPLE_U8:
594 format = AUDIO_SAMPLE_8_BIT;
595 break;
596 case AudioSampleFormat::SAMPLE_S16LE:
597 format = AUDIO_SAMPLE_16_BIT;
598 break;
599 case AudioSampleFormat::SAMPLE_S24LE:
600 format = AUDIO_SAMPLE_24_BIT;
601 break;
602 case AudioSampleFormat::SAMPLE_S32LE:
603 case AudioSampleFormat::SAMPLE_F32LE:
604 format = AUDIO_SAMPLE_32_BIT;
605 break;
606 default:
607 break;
608 }
609 return format;
610 }
611
IsBufferAvailable(std::shared_ptr<AVBuffer> & buffer,size_t & cacheBufferSize)612 bool AudioSink::IsBufferAvailable(std::shared_ptr<AVBuffer> &buffer, size_t &cacheBufferSize)
613 {
614 FALSE_RETURN_V_MSG_D(buffer != nullptr && buffer->memory_ != nullptr, false, "buffer is null.");
615 int32_t bufferSize = buffer->memory_->GetSize();
616 FALSE_RETURN_V_MSG_D(bufferSize >= currentQueuedBufferOffset_, false, "buffer is empty, skip this buffer.");
617 cacheBufferSize = static_cast<size_t>(bufferSize - currentQueuedBufferOffset_);
618 return true;
619 }
620
CopyBufferData(AudioStandard::BufferDesc & bufferDesc,std::shared_ptr<AVBuffer> & buffer,size_t & size,size_t & cacheBufferSize,int64_t & bufferPts)621 bool AudioSink::CopyBufferData(AudioStandard::BufferDesc &bufferDesc, std::shared_ptr<AVBuffer> &buffer,
622 size_t &size, size_t &cacheBufferSize, int64_t &bufferPts)
623 {
624 size_t availableSize = cacheBufferSize > size ? size : cacheBufferSize;
625 auto ret = memcpy_s(bufferDesc.buffer + bufferDesc.dataLength, availableSize,
626 buffer->memory_->GetAddr() + currentQueuedBufferOffset_, availableSize);
627 FALSE_RETURN_V_MSG(ret == 0, false, "copy from cache buffer may fail.");
628 bufferPts = (bufferPts == HST_TIME_NONE) ? buffer->pts_ : bufferPts;
629 bufferDesc.dataLength += availableSize;
630 availDataSize_.fetch_sub(availableSize);
631 if (cacheBufferSize > size) {
632 currentQueuedBufferOffset_ += static_cast<int32_t>(size);
633 size = 0;
634 return false;
635 }
636 currentQueuedBufferOffset_ = 0;
637 size -= cacheBufferSize;
638 return true;
639 }
640
CopyAudioVividBufferData(AudioStandard::BufferDesc & bufferDesc,std::shared_ptr<AVBuffer> & buffer,size_t & size,size_t & cacheBufferSize,int64_t & bufferPts)641 bool AudioSink::CopyAudioVividBufferData(AudioStandard::BufferDesc &bufferDesc, std::shared_ptr<AVBuffer> &buffer,
642 size_t &size, size_t &cacheBufferSize, int64_t &bufferPts)
643 {
644 auto ret = memcpy_s(bufferDesc.buffer + bufferDesc.dataLength, cacheBufferSize,
645 buffer->memory_->GetAddr() + currentQueuedBufferOffset_, cacheBufferSize);
646 FALSE_RETURN_V_MSG(ret == 0, false, "copy from cache buffer may fail.");
647 bufferPts = (bufferPts == HST_TIME_NONE) ? buffer->pts_ : bufferPts;
648 bufferDesc.dataLength += cacheBufferSize;
649 size -= cacheBufferSize;
650 availDataSize_.fetch_sub(cacheBufferSize);
651 currentQueuedBufferOffset_ = 0;
652 auto meta = buffer->meta_;
653 std::vector<uint8_t> metaData;
654 meta->GetData(Tag::OH_MD_KEY_AUDIO_VIVID_METADATA, metaData);
655 if (metaData.size() == bufferDesc.metaLength && bufferDesc.metaLength > 0) {
656 ret = memcpy_s(bufferDesc.metaBuffer, bufferDesc.metaLength,
657 metaData.data(), bufferDesc.metaLength);
658 FALSE_RETURN_V_MSG(ret == 0, false, "copy from cache buffer may fail.");
659 }
660 return true;
661 }
662
IsBufferDataDrained(AudioStandard::BufferDesc & bufferDesc,std::shared_ptr<AVBuffer> & buffer,size_t & size,size_t & cacheBufferSize,bool isAudioVivid,int64_t & bufferPts)663 bool AudioSink::IsBufferDataDrained(AudioStandard::BufferDesc &bufferDesc, std::shared_ptr<AVBuffer> &buffer,
664 size_t &size, size_t &cacheBufferSize, bool isAudioVivid, int64_t &bufferPts)
665 {
666 FALSE_RETURN_V_MSG(cacheBufferSize <= size || !isAudioVivid, false, "copy from cache buffer may fail.");
667 bool ret = isAudioVivid ? CopyAudioVividBufferData(bufferDesc, buffer, size, cacheBufferSize, bufferPts) :
668 CopyBufferData(bufferDesc, buffer, size, cacheBufferSize, bufferPts);
669 return ret;
670 }
671
CopyDataToBufferDesc(size_t size,bool isAudioVivid,AudioStandard::BufferDesc & bufferDesc)672 bool AudioSink::CopyDataToBufferDesc(size_t size, bool isAudioVivid, AudioStandard::BufferDesc &bufferDesc)
673 {
674 FALSE_RETURN_V_MSG(size != 0 && size == bufferDesc.bufLength, false,
675 "bufferDesc or request size is unavailable");
676 std::lock_guard<std::mutex> lock(availBufferMutex_);
677 int64_t bufferPts = HST_TIME_NONE;
678 do {
679 bool isSwapBuffer = false;
680 FALSE_RETURN_V_MSG(!swapOutputBuffers_.empty() || !availOutputBuffers_.empty(), false, "buffer queue is empty");
681 std::shared_ptr<AVBuffer> cacheBuffer;
682 if (!swapOutputBuffers_.empty()) {
683 cacheBuffer = swapOutputBuffers_.front();
684 isSwapBuffer = true;
685 } else {
686 cacheBuffer = availOutputBuffers_.front();
687 }
688 if (IsEosBuffer(cacheBuffer)) {
689 MEDIA_LOG_I("AudioSink Recv EOS size: " PUBLIC_LOG_D32 " dataLength: " PUBLIC_LOG_D32
690 " bufferlength: " PUBLIC_LOG_D32, static_cast<int32_t>(size),
691 static_cast<int32_t>(bufferDesc.dataLength), static_cast<int32_t>(bufferDesc.bufLength));
692 if (plugin_ && size > 0) {
693 (void)plugin_->MuteAudioBuffer(bufferDesc.buffer, bufferDesc.dataLength, size);
694 }
695 break;
696 }
697 size_t cacheBufferSize = 0;
698 if (IsBufferAvailable(cacheBuffer, cacheBufferSize)) {
699 if (!IsBufferDataDrained(bufferDesc, cacheBuffer, size, cacheBufferSize, isAudioVivid, bufferPts)) {
700 break;
701 }
702 CalcMaxAmplitude(cacheBuffer);
703 }
704 ReleaseCacheBuffer(isSwapBuffer);
705 } while (size > 0 && !isAudioVivid);
706 if (bufferPts >= 0) {
707 int64_t bufferDuration = CalculateBufferDuration(bufferDesc.dataLength);
708 innerSynchroizer_->UpdateCurrentBufferInfo(bufferPts, bufferDuration);
709 return true;
710 }
711 return false;
712 }
713
CalculateBufferDuration(int64_t writeDataSize)714 int64_t AudioSink::CalculateBufferDuration(int64_t writeDataSize)
715 {
716 int32_t format = GetSampleFormatBytes();
717 FALSE_RETURN_V(format > 0 && audioChannelCount_ > 0, 0);
718 int64_t sampleDataNums = writeDataSize / format / audioChannelCount_;
719 FALSE_RETURN_V(sampleRate_ > 0, 0);
720 int64_t sampleDataDuration = sampleDataNums * SEC_TO_US / sampleRate_;
721 return sampleDataDuration;
722 }
723
UpdateCurrentBufferInfo(int64_t bufferPts,int64_t bufferDuration)724 void AudioSink::AudioDataSynchroizer::UpdateCurrentBufferInfo(int64_t bufferPts, int64_t bufferDuration)
725 {
726 bufferDuration_ = bufferDuration;
727 startPTS_ = startPTS_ == HST_TIME_NONE ? bufferPts : startPTS_;
728 lastBufferPTS_ = lastBufferPTS_ == HST_TIME_NONE ? bufferPts : lastBufferPTS_;
729 curBufferPTS_ = bufferPts;
730 }
731
UpdateLastBufferPTS(int64_t bufferOffset,float speed)732 void AudioSink::AudioDataSynchroizer::UpdateLastBufferPTS(int64_t bufferOffset, float speed)
733 {
734 MEDIA_LOG_D("lastBuffer Info: lastBufferPTS_ is " PUBLIC_LOG_D64 " lastBufferOffset_ is " PUBLIC_LOG_D64
735 " and compensateDuration_ is " PUBLIC_LOG_D64, lastBufferPTS_, lastBufferOffset_, compensateDuration_);
736 curBufferPTS_ = curBufferPTS_ == HST_TIME_NONE ? 0 : curBufferPTS_;
737 lastBufferPTS_ = curBufferPTS_ + lastBufferOffset_ + bufferDuration_;
738 lastBufferOffset_ = bufferOffset;
739 sumDuration_ += bufferDuration_;
740 FALSE_RETURN_MSG(speed != 0, "speed is 0");
741 compensateDuration_ += bufferDuration_ - bufferDuration_ / speed;
742 }
743
UpdateRenderInfo()744 void AudioSink::UpdateRenderInfo()
745 {
746 timespec time;
747 uint32_t position;
748 FALSE_RETURN_MSG(plugin_->GetAudioPosition(time, position), "GetAudioPosition from audioRender failed");
749 int64_t currentRenderClockTime = time.tv_sec * SEC_TO_US + time.tv_nsec / US_TO_MS; // convert to us
750 FALSE_RETURN(sampleRate_ > 0);
751 int64_t currentRenderPTS = static_cast<int64_t>(position) * SEC_TO_US / sampleRate_;
752 MEDIA_LOG_D("currentRenderPTS is " PUBLIC_LOG_D64 " and currentRenderClockTime is " PUBLIC_LOG_D64,
753 currentRenderPTS, currentRenderClockTime);
754 innerSynchroizer_->OnRenderPositionUpdated(currentRenderPTS, currentRenderClockTime);
755 }
756
OnRenderPositionUpdated(int64_t currentRenderPTS,int64_t currentRenderClockTime)757 void AudioSink::AudioDataSynchroizer::OnRenderPositionUpdated(int64_t currentRenderPTS, int64_t currentRenderClockTime)
758 {
759 currentRenderClockTime_ = currentRenderClockTime;
760 currentRenderPTS_ = currentRenderPTS;
761 }
762
CalculateAudioLatency()763 int64_t AudioSink::AudioDataSynchroizer::CalculateAudioLatency()
764 {
765 int64_t latency = 0;
766 if (lastBufferPTS_ == startPTS_) {
767 return latency;
768 }
769 int64_t nowClockTime = Plugins::HstTime2Us(SteadyClock::GetCurrentTimeNanoSec());
770 MEDIA_LOG_D("PTS diff is " PUBLIC_LOG_D64, ((sumDuration_ - compensateDuration_) -
771 currentRenderPTS_));
772 latency = ((sumDuration_ - compensateDuration_) - currentRenderPTS_) -
773 (nowClockTime - currentRenderClockTime_);
774 FALSE_RETURN_V_MSG(latency >= 0, 0, "calculate latency failed");
775 return latency;
776 }
777
GetLastBufferPTS() const778 int64_t AudioSink::AudioDataSynchroizer::GetLastBufferPTS() const
779 {
780 return lastBufferPTS_;
781 }
782
GetLastReportedClockTime() const783 int64_t AudioSink::AudioDataSynchroizer::GetLastReportedClockTime() const
784 {
785 return lastReportedClockTime_;
786 }
787
GetBufferDuration() const788 int64_t AudioSink::AudioDataSynchroizer::GetBufferDuration() const
789 {
790 return bufferDuration_;
791 }
792
UpdateReportTime(int64_t nowClockTime)793 void AudioSink::AudioDataSynchroizer::UpdateReportTime(int64_t nowClockTime)
794 {
795 lastReportedClockTime_ = nowClockTime;
796 }
797
Reset()798 void AudioSink::AudioDataSynchroizer::Reset()
799 {
800 lastBufferPTS_ = HST_TIME_NONE;
801 bufferDuration_ = 0;
802 currentRenderClockTime_ = 0;
803 currentRenderPTS_ = 0;
804 lastReportedClockTime_ = HST_TIME_NONE;
805 startPTS_ = HST_TIME_NONE;
806 curBufferPTS_ = HST_TIME_NONE;
807 lastBufferOffset_ = 0;
808 compensateDuration_ = 0;
809 sumDuration_ = 0;
810 }
811
IsTimeAnchorNeedUpdate()812 bool AudioSink::IsTimeAnchorNeedUpdate()
813 {
814 auto syncCenter = syncCenter_.lock();
815 FALSE_RETURN_V(syncCenter != nullptr, false);
816 int64_t lastAnchorClockTime = innerSynchroizer_->GetLastReportedClockTime();
817 int64_t nowCt = syncCenter->GetClockTimeNow();
818 bool needUpdate = forceUpdateTimeAnchorNextTime_ ||
819 (lastAnchorClockTime == HST_TIME_NONE) ||
820 (nowCt - lastAnchorClockTime >= ANCHOR_UPDATE_PERIOD_US);
821 FALSE_RETURN_V_MSG_D(needUpdate, false, "No need to update time anchor this time.");
822 UpdateRenderInfo();
823 int64_t latency = innerSynchroizer_->CalculateAudioLatency();
824 MEDIA_LOG_D("Calculate latency = " PUBLIC_LOG_U64, latency);
825 int64_t lastBufferPTS = innerSynchroizer_->GetLastBufferPTS();
826 int64_t lastBufferDuration = innerSynchroizer_->GetBufferDuration();
827 Pipeline::IMediaSyncCenter::IMediaTime iMediaTime = {lastBufferPTS - firstPts_, lastBufferPTS,
828 lastBufferDuration};
829 syncCenter->UpdateTimeAnchor(nowCt, latency + fixDelay_, iMediaTime, this);
830 MEDIA_LOG_I("AudioSink fixDelay_: " PUBLIC_LOG_D64
831 " us, latency: " PUBLIC_LOG_D64
832 " us, pts-f: " PUBLIC_LOG_D64
833 " us, nowCt: " PUBLIC_LOG_D64 " us",
834 fixDelay_, latency, lastBufferPTS - firstPts_, nowCt);
835 forceUpdateTimeAnchorNextTime_ = false;
836 innerSynchroizer_->UpdateReportTime(nowCt);
837 return true;
838 }
839
SyncWriteByRenderInfo()840 void AudioSink::SyncWriteByRenderInfo()
841 {
842 auto syncCenter = syncCenter_.lock();
843 if (firstPts_ == HST_TIME_NONE) {
844 if (syncCenter && syncCenter->GetMediaStartPts() != HST_TIME_NONE) {
845 firstPts_ = syncCenter->GetMediaStartPts();
846 } else {
847 firstPts_ = innerSynchroizer_->GetLastBufferPTS();
848 }
849 }
850 bool anchorUpdated = IsTimeAnchorNeedUpdate();
851 innerSynchroizer_->UpdateLastBufferPTS(CalculateBufferDuration(currentQueuedBufferOffset_), speed_);
852 latestBufferDuration_ = innerSynchroizer_->GetBufferDuration() / speed_;
853 if (anchorUpdated) {
854 bufferDurationSinceLastAnchor_ = latestBufferDuration_;
855 } else {
856 bufferDurationSinceLastAnchor_ += latestBufferDuration_;
857 }
858 underrunDetector_.SetLastAudioBufferDuration(bufferDurationSinceLastAnchor_);
859 if (syncCenter) {
860 syncCenter->SetLastAudioBufferDuration(bufferDurationSinceLastAnchor_);
861 }
862 }
863
ReleaseCacheBuffer(bool isSwapBuffer)864 void AudioSink::ReleaseCacheBuffer(bool isSwapBuffer)
865 {
866 if (isSwapBuffer) {
867 FALSE_RETURN_MSG(!swapOutputBuffers_.empty(), "swapOutputBuffers_ has no buffer");
868 swapOutputBuffers_.pop();
869 return;
870 }
871 auto buffer = availOutputBuffers_.front();
872 availOutputBuffers_.pop();
873 FALSE_RETURN_MSG(buffer != nullptr, "release buffer, but buffer is null");
874 MEDIA_LOG_D("the pts is " PUBLIC_LOG_D64 " buffer is release", buffer->pts_);
875 Status ret = inputBufferQueueConsumer_->ReleaseBuffer(buffer);
876 FALSE_RETURN_MSG(ret == Status::OK, "release avbuffer failed");
877 return;
878 }
879
ResetInfo()880 void AudioSink::ResetInfo()
881 {
882 if (appUid_ == BOOT_APP_UID) {
883 std::unique_lock<std::mutex> eosCbLock(eosCbMutex_);
884 hangeOnEosCb_ = false;
885 eosCbCond_.notify_all();
886 }
887 innerSynchroizer_->Reset();
888 maxAmplitude_ = 0;
889 currentMaxAmplitude_ = 0;
890 currentQueuedBufferOffset_ = 0;
891 forceUpdateTimeAnchorNextTime_ = true;
892 isEosBuffer_ = false;
893 availDataSize_.store(0);
894 ClearAvailableOutputBuffers();
895 ClearInputBuffer();
896 }
897
ClearAvailableOutputBuffers()898 void AudioSink::ClearAvailableOutputBuffers()
899 {
900 FALSE_RETURN(inputBufferQueueConsumer_ != nullptr);
901 std::lock_guard<std::mutex> lock(availBufferMutex_);
902 while (!swapOutputBuffers_.empty()) {
903 swapOutputBuffers_.pop();
904 }
905 while (!availOutputBuffers_.empty()) {
906 ReleaseCacheBuffer();
907 }
908 }
909
GetAvailableOutputBuffers()910 void AudioSink::GetAvailableOutputBuffers()
911 {
912 FALSE_RETURN(inputBufferQueueConsumer_ != nullptr);
913 std::lock_guard<std::mutex> lock(availBufferMutex_);
914 std::shared_ptr<AVBuffer> filledInputBuffer;
915 Status ret = Status::OK;
916 while (ret == Status::OK) {
917 ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
918 if (ret != Status::OK || filledInputBuffer == nullptr) {
919 break;
920 }
921 if (filledInputBuffer->memory_ == nullptr || filledInputBuffer->pts_ < 0) {
922 inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
923 continue;
924 }
925 if (DropApeBuffer(filledInputBuffer)) {
926 break;
927 }
928 if (IsEosBuffer(filledInputBuffer)) {
929 MEDIA_LOG_I("AudioSink Recv EOS");
930 isEosBuffer_ = true;
931 }
932 availOutputBuffers_.push(filledInputBuffer);
933 MEDIA_LOG_D("the pts is " PUBLIC_LOG_D64 " buffer is push", filledInputBuffer->pts_);
934 availDataSize_.fetch_add(filledInputBuffer->memory_->GetSize());
935 }
936 DriveBufferCircle();
937 return;
938 }
939
DriveBufferCircle()940 void AudioSink::DriveBufferCircle()
941 {
942 FALSE_RETURN_NOLOG(!isEosBuffer_);
943 FALSE_RETURN_NOLOG(!availOutputBuffers_.empty() && inputBufferQueue_ != nullptr);
944 FALSE_RETURN_NOLOG(availOutputBuffers_.size() >= inputBufferQueue_->GetQueueSize());
945 size_t availDataSize = availDataSize_.load();
946 int32_t availDataSizeInt32 = availDataSize <= static_cast<size_t>(INT32_MAX) ?
947 static_cast<int32_t>(availDataSize): INT32_MAX;
948 FALSE_RETURN_NOLOG(availDataSizeInt32 < maxCbDataSize_);
949 std::shared_ptr<AVBuffer> oldestBuffer = availOutputBuffers_.front();
950 FALSE_RETURN_MSG(oldestBuffer != nullptr && oldestBuffer->memory_->GetSize() > 0, "buffer or memory is nullptr");
951 std::shared_ptr<AVBuffer> swapBuffer = CopyBuffer(oldestBuffer);
952 FALSE_RETURN_MSG(swapBuffer != nullptr, "CopyBuffer failed, swapBuffer is nullptr");
953 availOutputBuffers_.pop();
954 swapOutputBuffers_.push(swapBuffer);
955 FALSE_RETURN_MSG(inputBufferQueueConsumer_ != nullptr, "bufferQueue consumer is nullptr");
956 inputBufferQueueConsumer_->ReleaseBuffer(oldestBuffer);
957 }
958
CopyBuffer(const std::shared_ptr<AVBuffer> buffer)959 std::shared_ptr<AVBuffer> AudioSink::CopyBuffer(const std::shared_ptr<AVBuffer> buffer)
960 {
961 FALSE_RETURN_V_MSG_E(buffer != nullptr && buffer->memory_->GetSize() > 0, nullptr, "buffer or memory is nullptr");
962 std::shared_ptr<Meta> meta = buffer->meta_;
963 std::vector<uint8_t> metaData;
964 FALSE_RETURN_V_MSG_W(meta == nullptr || !meta->GetData(Tag::OH_MD_KEY_AUDIO_VIVID_METADATA, metaData), nullptr,
965 "copy buffer not support for audiovivid");
966 AVBufferConfig avBufferConfig;
967 avBufferConfig.capacity = static_cast<int32_t>(buffer->memory_->GetSize());
968 avBufferConfig.memoryType = bufferMemoryType_;
969 std::shared_ptr<AVBuffer> swapBuffer = AVBuffer::CreateAVBuffer(avBufferConfig);
970 FALSE_RETURN_V_MSG_E(swapBuffer != nullptr && swapBuffer->memory_ != nullptr, nullptr, "create swapBuffer failed");
971 swapBuffer->pts_ = buffer->pts_;
972 swapBuffer->dts_ = buffer->dts_;
973 swapBuffer->duration_ = buffer->duration_;
974 swapBuffer->flag_ = buffer->flag_;
975 FALSE_RETURN_V_MSG_E(swapBuffer->memory_->GetCapacity() >= buffer->memory_->GetSize(), nullptr, "no enough memory");
976 errno_t res = memcpy_s(swapBuffer->memory_->GetAddr(),
977 swapBuffer->memory_->GetCapacity(),
978 buffer->memory_->GetAddr(),
979 buffer->memory_->GetSize());
980 FALSE_RETURN_V_MSG_E(res == EOK, nullptr, "copy data failed");
981 swapBuffer->memory_->SetSize(buffer->memory_->GetSize());
982 return swapBuffer;
983 }
984
WriteDataToRender(std::shared_ptr<AVBuffer> & filledOutputBuffer)985 void AudioSink::WriteDataToRender(std::shared_ptr<AVBuffer> &filledOutputBuffer)
986 {
987 FALSE_RETURN(DropApeBuffer(filledOutputBuffer) == false);
988 if (IsEosBuffer(filledOutputBuffer)) {
989 HandleEosBuffer(filledOutputBuffer);
990 return;
991 }
992 FALSE_RETURN(plugin_ != nullptr);
993 UpdateAudioWriteTimeMayWait();
994 DoSyncWrite(filledOutputBuffer);
995 if (calMaxAmplitudeCbStatus_) {
996 CalcMaxAmplitude(filledOutputBuffer);
997 UpdateAmplitude();
998 } else {
999 maxAmplitude_ = 0.0f;
1000 }
1001 lastBufferWriteSuccess_ = (plugin_->Write(filledOutputBuffer) == Status::OK);
1002 int64_t nowClockTime = 0;
1003 GetSyncCenterClockTime(nowClockTime);
1004 auto audioWriteMs = plugin_->GetWriteDurationMs();
1005 lagDetector_.UpdateDrainTimeGroup(
1006 { lastAnchorClockTime_, bufferDurationSinceLastAnchor_, audioWriteMs, nowClockTime });
1007 PerfRecord(audioWriteMs);
1008 lagDetector_.CalcLag(filledOutputBuffer);
1009 MEDIA_LOG_D("audio DrainOutputBuffer pts = " PUBLIC_LOG_D64, filledOutputBuffer->pts_);
1010 numFramesWritten_++;
1011 inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer);
1012 }
1013
IsEosBuffer(std::shared_ptr<AVBuffer> & filledOutputBuffer)1014 bool AudioSink::IsEosBuffer(std::shared_ptr<AVBuffer> &filledOutputBuffer)
1015 {
1016 return (filledOutputBuffer->flag_ & BUFFER_FLAG_EOS) ||
1017 ((playRangeEndTime_ != DEFAULT_PLAY_RANGE_VALUE) &&
1018 (filledOutputBuffer->pts_ > playRangeEndTime_ * MICROSECONDS_CONVERT_UNITS));
1019 }
1020
HandleEosBuffer(std::shared_ptr<AVBuffer> & filledOutputBuffer)1021 void AudioSink::HandleEosBuffer(std::shared_ptr<AVBuffer> &filledOutputBuffer)
1022 {
1023 inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer);
1024 AutoLock eosLock(eosMutex_);
1025 // avoid submit handle eos task multiple times
1026 FALSE_RETURN(!eosDraining_);
1027 eosInterruptType_ = EosInterruptState::INITIAL;
1028 if (eosTask_ == nullptr) {
1029 DrainAndReportEosEvent();
1030 return;
1031 }
1032 MEDIA_LOG_I("DrainOutputBuffer Recv EOS PTS");
1033 eosTask_->SubmitJobOnce([this] {
1034 HandleEosInner(false);
1035 });
1036 return;
1037 }
1038
DrainOutputBuffer(bool flushed)1039 void AudioSink::DrainOutputBuffer(bool flushed)
1040 {
1041 std::lock_guard<std::mutex> lock(pluginMutex_);
1042 FALSE_RETURN(plugin_ != nullptr && inputBufferQueueConsumer_ != nullptr);
1043 if (state_ == Pipeline::FilterState::PAUSED || state_ == Pipeline::FilterState::READY ||
1044 state_ == Pipeline::FilterState::STOPPED) {
1045 MEDIA_LOG_I("DrainOutputBuffer ignore for PAUSE/READY, state = " PUBLIC_LOG_D32, state_.load());
1046 return;
1047 }
1048 if (isCallbackMode_) {
1049 GetAvailableOutputBuffers();
1050 } else {
1051 std::shared_ptr<AVBuffer> filledOutputBuffer = nullptr;
1052 Status ret = inputBufferQueueConsumer_->AcquireBuffer(filledOutputBuffer);
1053 FALSE_RETURN(ret == Status::OK && filledOutputBuffer != nullptr);
1054 if (state_ != Pipeline::FilterState::RUNNING || flushed) {
1055 MEDIA_LOG_E("Drop buffer pts = " PUBLIC_LOG_D64, filledOutputBuffer->pts_);
1056 inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer);
1057 return;
1058 }
1059 WriteDataToRender(filledOutputBuffer);
1060 }
1061 }
1062
SetPerfRecEnabled(bool isPerfRecEnabled)1063 Status AudioSink::SetPerfRecEnabled(bool isPerfRecEnabled)
1064 {
1065 isPerfRecEnabled_ = isPerfRecEnabled;
1066 return Status::OK;
1067 }
1068
PerfRecord(int64_t audioWriteMs)1069 void AudioSink::PerfRecord(int64_t audioWriteMs)
1070 {
1071 FALSE_RETURN_NOLOG(isPerfRecEnabled_);
1072 FALSE_RETURN_MSG(playerEventReceiver_ != nullptr, "Report perf failed, event receiver is nullptr");
1073 FALSE_RETURN_NOLOG(perfRecorder_.Record(audioWriteMs) == PerfRecorder::FULL);
1074 playerEventReceiver_->OnDfxEvent(
1075 { "ASINK", DfxEventType::DFX_INFO_PERF_REPORT, perfRecorder_.GetMainPerfData() });
1076 perfRecorder_.Reset();
1077 }
1078
ResetSyncInfo()1079 void AudioSink::ResetSyncInfo()
1080 {
1081 lastAnchorClockTime_ = HST_TIME_NONE;
1082 forceUpdateTimeAnchorNextTime_ = true;
1083 }
1084
Reset()1085 void AudioSink::UnderrunDetector::Reset()
1086 {
1087 AutoLock lock(mutex_);
1088 lastClkTime_ = HST_TIME_NONE;
1089 lastLatency_ = HST_TIME_NONE;
1090 lastBufferDuration_ = HST_TIME_NONE;
1091 }
1092
SetEventReceiver(std::weak_ptr<Pipeline::EventReceiver> eventReceiver)1093 void AudioSink::UnderrunDetector::SetEventReceiver(std::weak_ptr<Pipeline::EventReceiver> eventReceiver)
1094 {
1095 eventReceiver_ = eventReceiver;
1096 }
1097
UpdateBufferTimeNoLock(int64_t clkTime,int64_t latency)1098 void AudioSink::UnderrunDetector::UpdateBufferTimeNoLock(int64_t clkTime, int64_t latency)
1099 {
1100 lastClkTime_ = clkTime;
1101 lastLatency_ = latency;
1102 }
1103
SetLastAudioBufferDuration(int64_t durationUs)1104 void AudioSink::UnderrunDetector::SetLastAudioBufferDuration(int64_t durationUs)
1105 {
1106 AutoLock lock(mutex_);
1107 lastBufferDuration_ = durationUs;
1108 }
1109
DetectAudioUnderrun(int64_t clkTime,int64_t latency)1110 void AudioSink::UnderrunDetector::DetectAudioUnderrun(int64_t clkTime, int64_t latency)
1111 {
1112 if (lastClkTime_ == HST_TIME_NONE) {
1113 AutoLock lock(mutex_);
1114 UpdateBufferTimeNoLock(clkTime, latency);
1115 return;
1116 }
1117 int64_t underrunTimeUs = 0;
1118 {
1119 AutoLock lock(mutex_);
1120 int64_t elapsedClk = clkTime - lastClkTime_;
1121 underrunTimeUs = elapsedClk - (lastLatency_ + lastBufferDuration_);
1122 UpdateBufferTimeNoLock(clkTime, latency);
1123 }
1124 if (underrunTimeUs > 0) {
1125 MEDIA_LOG_D("AudioSink maybe underrun, underrunTimeUs=" PUBLIC_LOG_D64, underrunTimeUs);
1126 auto eventReceiver = eventReceiver_.lock();
1127 FALSE_RETURN(eventReceiver != nullptr);
1128 eventReceiver->OnDfxEvent({"AudioSink", DfxEventType::DFX_INFO_PLAYER_AUDIO_LAG, underrunTimeUs / US_TO_MS});
1129 }
1130 }
1131
CalcLag(std::shared_ptr<AVBuffer> buffer)1132 bool AudioSink::AudioLagDetector::CalcLag(std::shared_ptr<AVBuffer> buffer)
1133 {
1134 (void)buffer;
1135 int64_t maxMediaTime = lastDrainTimeGroup_.anchorDuration + lastDrainTimeGroup_.lastAnchorPts + latency_;
1136 auto currentMediaTime = lastDrainTimeGroup_.nowClockTime;
1137 auto writeTimeMs = lastDrainTimeGroup_.writeDuration;
1138
1139 MEDIA_LOG_D("maxMediaTime " PUBLIC_LOG_D64 " currentMediaTime " PUBLIC_LOG_D64 " latency_ " PUBLIC_LOG_D64,
1140 maxMediaTime, currentMediaTime, latency_);
1141
1142 if (maxMediaTime < currentMediaTime) {
1143 MEDIA_LOG_W("renderer write cost " PUBLIC_LOG_D64, writeTimeMs);
1144 }
1145
1146 // Calc time delays except plugin write
1147 auto currentTimeMs = Plugins::GetCurrentMillisecond();
1148 auto totalTimeDiff = lastDrainTimeMs_ == 0 ? 0 : currentTimeMs - lastDrainTimeMs_;
1149 lastDrainTimeMs_ = currentTimeMs;
1150 auto drainTimeDiff = totalTimeDiff - writeTimeMs;
1151 if (drainTimeDiff > DRAIN_TIME_DIFF_WARN_MS) {
1152 MEDIA_LOG_W("Audio drain cost " PUBLIC_LOG_D64, drainTimeDiff);
1153 } else if (drainTimeDiff > DRAIN_TIME_DIFF_INFO_MS) {
1154 MEDIA_LOG_I("Audio drain cost " PUBLIC_LOG_D64, drainTimeDiff);
1155 } else {
1156 MEDIA_LOG_D("Audio drain cost " PUBLIC_LOG_D64, drainTimeDiff);
1157 }
1158
1159 return maxMediaTime < currentMediaTime;
1160 }
1161
Reset()1162 void AudioSink::AudioLagDetector::Reset()
1163 {
1164 latency_ = 0;
1165 lastDrainTimeMs_ = 0;
1166 lastDrainTimeGroup_.lastAnchorPts = 0;
1167 lastDrainTimeGroup_.anchorDuration = 0;
1168 lastDrainTimeGroup_.writeDuration = 0;
1169 lastDrainTimeGroup_.nowClockTime = 0;
1170 }
1171
GetSyncCenterClockTime(int64_t & clockTime)1172 bool AudioSink::GetSyncCenterClockTime(int64_t &clockTime)
1173 {
1174 auto syncCenter = syncCenter_.lock();
1175 FALSE_RETURN_V(syncCenter != nullptr, false);
1176 clockTime = syncCenter->GetClockTimeNow();
1177 return true;
1178 }
1179
UpdateDrainTimeGroup(AudioDrainTimeGroup group)1180 void AudioSink::AudioLagDetector::UpdateDrainTimeGroup(AudioDrainTimeGroup group)
1181 {
1182 lastDrainTimeGroup_.lastAnchorPts = group.lastAnchorPts;
1183 lastDrainTimeGroup_.anchorDuration = group.anchorDuration;
1184 lastDrainTimeGroup_.writeDuration = group.writeDuration;
1185 lastDrainTimeGroup_.nowClockTime = group.nowClockTime;
1186 }
1187
UpdateTimeAnchorIfNeeded(const std::shared_ptr<OHOS::Media::AVBuffer> & buffer)1188 bool AudioSink::UpdateTimeAnchorIfNeeded(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer)
1189 {
1190 auto syncCenter = syncCenter_.lock();
1191 FALSE_RETURN_V(syncCenter != nullptr, false);
1192 int64_t nowCt = syncCenter->GetClockTimeNow();
1193 bool needUpdate = forceUpdateTimeAnchorNextTime_ ||
1194 (lastAnchorClockTime_ == HST_TIME_NONE) ||
1195 (nowCt - lastAnchorClockTime_ >= ANCHOR_UPDATE_PERIOD_US);
1196 if (!needUpdate) {
1197 MEDIA_LOG_D("No need to update time anchor this time.");
1198 return false;
1199 }
1200 uint64_t latency = 0;
1201 FALSE_LOG_MSG(plugin_->GetLatency(latency) == Status::OK, "failed to get latency");
1202 Pipeline::IMediaSyncCenter::IMediaTime iMediaTime = {buffer->pts_ - firstPts_, buffer->pts_, buffer->duration_};
1203 syncCenter->UpdateTimeAnchor(nowCt, latency + fixDelay_, iMediaTime, this);
1204 lagDetector_.SetLatency(latency + fixDelay_);
1205 MEDIA_LOG_I("AudioSink fixDelay_: " PUBLIC_LOG_D64
1206 " us, latency: " PUBLIC_LOG_D64
1207 " us, pts-f: " PUBLIC_LOG_D64
1208 " us, pts: " PUBLIC_LOG_D64
1209 " us, nowCt: " PUBLIC_LOG_D64 " us",
1210 fixDelay_, latency, buffer->pts_ - firstPts_, buffer->pts_, nowCt);
1211 forceUpdateTimeAnchorNextTime_ = false;
1212 lastAnchorClockTime_ = nowCt;
1213 return true;
1214 }
1215
DoSyncWrite(const std::shared_ptr<OHOS::Media::AVBuffer> & buffer)1216 int64_t AudioSink::DoSyncWrite(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer)
1217 {
1218 bool render = true; // audio sink always report time anchor and do not drop
1219 auto syncCenter = syncCenter_.lock();
1220 if (firstPts_ == HST_TIME_NONE) {
1221 if (syncCenter && syncCenter->GetMediaStartPts() != HST_TIME_NONE) {
1222 firstPts_ = syncCenter->GetMediaStartPts();
1223 } else {
1224 firstPts_ = buffer->pts_;
1225 }
1226 MEDIA_LOG_I("audio DoSyncWrite set firstPts = " PUBLIC_LOG_D64, firstPts_);
1227 }
1228 bool anchorUpdated = UpdateTimeAnchorIfNeeded(buffer);
1229 latestBufferDuration_ = CalcBufferDuration(buffer) / speed_;
1230 if (anchorUpdated) {
1231 bufferDurationSinceLastAnchor_ = latestBufferDuration_;
1232 } else {
1233 bufferDurationSinceLastAnchor_ += latestBufferDuration_;
1234 }
1235 underrunDetector_.SetLastAudioBufferDuration(bufferDurationSinceLastAnchor_);
1236 if (syncCenter) {
1237 syncCenter->SetLastAudioBufferDuration(bufferDurationSinceLastAnchor_);
1238 }
1239 return render ? 0 : -1;
1240 }
1241
CalcBufferDuration(const std::shared_ptr<OHOS::Media::AVBuffer> & buffer)1242 int64_t AudioSink::CalcBufferDuration(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer)
1243 {
1244 FALSE_RETURN_V(buffer != nullptr && buffer->memory_ != nullptr && sampleRate_ != 0 && audioChannelCount_ != 0, 0);
1245 int64_t size = static_cast<int64_t>(buffer->memory_->GetSize());
1246 int32_t format = GetSampleFormatBytes();
1247 FALSE_RETURN_V(format > 0 && audioChannelCount_ > 0, 0);
1248 return SEC_TO_US * size / format / sampleRate_ / audioChannelCount_;
1249 }
1250
SetSpeed(float speed)1251 Status AudioSink::SetSpeed(float speed)
1252 {
1253 if (plugin_ == nullptr) {
1254 return Status::ERROR_NULL_POINTER;
1255 }
1256 if (speed <= 0) {
1257 return Status::ERROR_INVALID_PARAMETER;
1258 }
1259 auto ret = plugin_->SetSpeed(speed);
1260 if (ret == Status::OK) {
1261 speed_ = speed;
1262 }
1263 forceUpdateTimeAnchorNextTime_ = true;
1264 return ret;
1265 }
1266
SetAudioEffectMode(int32_t effectMode)1267 Status AudioSink::SetAudioEffectMode(int32_t effectMode)
1268 {
1269 MEDIA_LOG_I("SetAudioEffectMode");
1270 if (plugin_ == nullptr) {
1271 return Status::ERROR_NULL_POINTER;
1272 }
1273 effectMode_ = effectMode;
1274 return plugin_->SetAudioEffectMode(effectMode);
1275 }
1276
GetAudioEffectMode(int32_t & effectMode)1277 Status AudioSink::GetAudioEffectMode(int32_t &effectMode)
1278 {
1279 MEDIA_LOG_I("GetAudioEffectMode");
1280 if (plugin_ == nullptr) {
1281 return Status::ERROR_NULL_POINTER;
1282 }
1283 return plugin_->GetAudioEffectMode(effectMode);
1284 }
1285
OnNewAudioMediaTime(int64_t mediaTimeUs)1286 bool AudioSink::OnNewAudioMediaTime(int64_t mediaTimeUs)
1287 {
1288 bool render = true;
1289 if (firstAudioAnchorTimeMediaUs_ == Plugins::HST_TIME_NONE) {
1290 firstAudioAnchorTimeMediaUs_ = mediaTimeUs;
1291 }
1292 int64_t nowUs = 0;
1293 auto syncCenter = syncCenter_.lock();
1294 if (syncCenter) {
1295 nowUs = syncCenter->GetClockTimeNow();
1296 }
1297 int64_t pendingTimeUs = getPendingAudioPlayoutDurationUs(nowUs);
1298 render = syncCenter->UpdateTimeAnchor(nowUs, pendingTimeUs, {mediaTimeUs, mediaTimeUs, mediaTimeUs}, this);
1299 return render;
1300 }
1301
getPendingAudioPlayoutDurationUs(int64_t nowUs)1302 int64_t AudioSink::getPendingAudioPlayoutDurationUs(int64_t nowUs)
1303 {
1304 int64_t writtenSamples = numFramesWritten_ * samplePerFrame_;
1305 const int64_t numFramesPlayed = plugin_->GetPlayedOutDurationUs(nowUs);
1306 FALSE_RETURN_V(sampleRate_ > 0, 0);
1307 int64_t pendingUs = (writtenSamples - numFramesPlayed) * HST_MSECOND / sampleRate_;
1308 MEDIA_LOG_D("pendingUs: " PUBLIC_LOG_D64, pendingUs);
1309 if (pendingUs < 0) {
1310 pendingUs = 0;
1311 }
1312 return pendingUs;
1313 }
1314
getDurationUsPlayedAtSampleRate(uint32_t numFrames)1315 int64_t AudioSink::getDurationUsPlayedAtSampleRate(uint32_t numFrames)
1316 {
1317 std::shared_ptr<Meta> parameter;
1318 plugin_->GetParameter(parameter);
1319 int32_t sampleRate = 0;
1320 if (parameter) {
1321 parameter->GetData(Tag::AUDIO_SAMPLE_RATE, sampleRate);
1322 }
1323 if (sampleRate == 0) {
1324 MEDIA_LOG_W("cannot get sampleRate");
1325 return 0;
1326 }
1327 return (int64_t)(static_cast<int32_t>(numFrames) * HST_MSECOND / sampleRate);
1328 }
1329
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)1330 void AudioSink::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver>& receiver)
1331 {
1332 FALSE_RETURN(receiver != nullptr);
1333 playerEventReceiver_ = receiver;
1334 FALSE_RETURN(plugin_ != nullptr);
1335 plugin_->SetEventReceiver(receiver);
1336 }
1337
SetSyncCenter(std::shared_ptr<Pipeline::MediaSyncManager> syncCenter)1338 void AudioSink::SetSyncCenter(std::shared_ptr<Pipeline::MediaSyncManager> syncCenter)
1339 {
1340 syncCenter_ = syncCenter;
1341 MediaSynchronousSink::Init();
1342 }
1343
ChangeTrack(std::shared_ptr<Meta> & meta,const std::shared_ptr<Pipeline::EventReceiver> & receiver)1344 Status AudioSink::ChangeTrack(std::shared_ptr<Meta>& meta, const std::shared_ptr<Pipeline::EventReceiver>& receiver)
1345 {
1346 MEDIA_LOG_I("GetAudioEffectMode ChangeTrack. ");
1347 std::lock_guard<std::mutex> lock(pluginMutex_);
1348 if (plugin_) {
1349 plugin_->Stop();
1350 plugin_->Deinit();
1351 plugin_ = nullptr;
1352 }
1353 plugin_ = CreatePlugin();
1354 FALSE_RETURN_V(plugin_ != nullptr, Status::ERROR_NULL_POINTER);
1355 Status ret = Status::OK;
1356 ret = InitAudioSinkPlugin(meta, receiver);
1357 FALSE_RETURN_V(ret == Status::OK, ret);
1358
1359 ret = InitAudioSinkInfo(meta);
1360 FALSE_RETURN_V(ret == Status::OK, ret);
1361
1362 ret = SetAudioSinkPluginParameters();
1363 FALSE_RETURN_V(ret == Status::OK, ret);
1364
1365 forceUpdateTimeAnchorNextTime_ = true;
1366
1367 return Status::OK;
1368 }
1369
SetAudioSinkPluginParameters()1370 Status AudioSink::SetAudioSinkPluginParameters()
1371 {
1372 FALSE_RETURN_V(plugin_ != nullptr, Status::ERROR_NULL_POINTER);
1373 Status ret = Status::OK;
1374 if (volume_ >= 0) {
1375 plugin_->SetVolume(volume_);
1376 }
1377 if (speed_ >= 0) {
1378 plugin_->SetSpeed(speed_);
1379 }
1380 if (effectMode_ >= 0) {
1381 plugin_->SetAudioEffectMode(effectMode_);
1382 }
1383 if (state_ == Pipeline::FilterState::RUNNING) {
1384 ret = plugin_->Start();
1385 }
1386 return ret;
1387 }
1388
SetMuted(bool isMuted)1389 Status AudioSink::SetMuted(bool isMuted)
1390 {
1391 isMuted_ = isMuted;
1392 FALSE_RETURN_V(plugin_ != nullptr, Status::ERROR_NULL_POINTER);
1393 return plugin_->SetMuted(isMuted);
1394 }
1395
SetMaxAmplitudeCbStatus(bool status)1396 int32_t AudioSink::SetMaxAmplitudeCbStatus(bool status)
1397 {
1398 calMaxAmplitudeCbStatus_ = status;
1399 MEDIA_LOG_I("audio SetMaxAmplitudeCbStatus = " PUBLIC_LOG_D32, calMaxAmplitudeCbStatus_);
1400 return 0;
1401 }
1402
SetSeekTime(int64_t seekTime)1403 Status AudioSink::SetSeekTime(int64_t seekTime)
1404 {
1405 MEDIA_LOG_I("AudioSink SetSeekTime pts = " PUBLIC_LOG_D64, seekTime);
1406 seekTimeUs_ = seekTime;
1407 return Status::OK;
1408 }
1409
OnInterrupted(bool isInterruptNeeded)1410 void AudioSink::OnInterrupted(bool isInterruptNeeded)
1411 {
1412 MEDIA_LOG_D("OnInterrupted %{public}d", isInterruptNeeded);
1413 isInterruptNeeded_ = isInterruptNeeded;
1414 if (plugin_ != nullptr) {
1415 plugin_->SetInterruptState(isInterruptNeeded);
1416 }
1417 }
1418
SetIsCalledBySystemApp(bool isCalledBySystemApp)1419 Status AudioSink::SetIsCalledBySystemApp(bool isCalledBySystemApp)
1420 {
1421 MEDIA_LOG_I("AudioSink isCalledBySystemApp = " PUBLIC_LOG_D32, isCalledBySystemApp);
1422 isCalledBySystemApp_ = isCalledBySystemApp;
1423 return Status::OK;
1424 }
1425
SetLooping(bool loop)1426 Status AudioSink::SetLooping(bool loop)
1427 {
1428 isLoop_ = loop;
1429 MEDIA_LOG_I("AudioSink SetLooping isLoop_ = " PUBLIC_LOG_D32, isLoop_);
1430 return Status::OK;
1431 }
1432 } // namespace MEDIA
1433 } // namespace OHOS
1434