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