1  /*
2   * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   *     http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #define MEDIA_PLUGIN
17  #define HST_LOG_TAG "ASSP"
18  
19  #include "audio_server_sink_plugin.h"
20  #include <functional>
21  #include "audio_errors.h"
22  #include "avcodec_trace.h"
23  #include "common/log.h"
24  #include "common/media_core.h"
25  #include "meta/meta_key.h"
26  #include "osal/task/autolock.h"
27  #include "osal/task/jobutils.h"
28  #include "common/status.h"
29  #include "common/media_core.h"
30  #include "audio_info.h"
31  #include "cpp_ext/algorithm_ext.h"
32  #include "osal/utils/steady_clock.h"
33  #include "plugin/plugin_time.h"
34  #include "param_wrapper.h"
35  
36  namespace {
37  constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "HiStreamer" };
38  using namespace OHOS::Media::Plugins;
39  constexpr int TUPLE_SECOND_ITEM_INDEX = 2;
40  constexpr int32_t DEFAULT_BUFFER_NUM = 8;
41  
42  const std::pair<AudioInterruptMode, OHOS::AudioStandard::InterruptMode> g_auInterruptMap[] = {
43      {AudioInterruptMode::SHARE_MODE, OHOS::AudioStandard::InterruptMode::SHARE_MODE},
44      {AudioInterruptMode::INDEPENDENT_MODE, OHOS::AudioStandard::InterruptMode::INDEPENDENT_MODE},
45  };
46  
47  const std::vector<std::tuple<AudioSampleFormat, OHOS::AudioStandard::AudioSampleFormat, AVSampleFormat>> g_aduFmtMap = {
48      {AudioSampleFormat::SAMPLE_S8, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
49      {AudioSampleFormat::SAMPLE_U8, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_U8, AV_SAMPLE_FMT_U8},
50      {AudioSampleFormat::SAMPLE_S8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
51      {AudioSampleFormat::SAMPLE_U8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_U8P},
52      {AudioSampleFormat::SAMPLE_S16LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE, AV_SAMPLE_FMT_S16},
53      {AudioSampleFormat::SAMPLE_U16, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
54      {AudioSampleFormat::SAMPLE_S16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S16P},
55      {AudioSampleFormat::SAMPLE_U16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
56      {AudioSampleFormat::SAMPLE_S24LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S24LE, AV_SAMPLE_FMT_NONE},
57      {AudioSampleFormat::SAMPLE_U24, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
58      {AudioSampleFormat::SAMPLE_S24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
59      {AudioSampleFormat::SAMPLE_U24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
60      {AudioSampleFormat::SAMPLE_S32LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S32LE, AV_SAMPLE_FMT_S32},
61      {AudioSampleFormat::SAMPLE_U32, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
62      {AudioSampleFormat::SAMPLE_S32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S32P},
63      {AudioSampleFormat::SAMPLE_U32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
64      {AudioSampleFormat::SAMPLE_F32LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_F32LE, AV_SAMPLE_FMT_NONE},
65      {AudioSampleFormat::SAMPLE_F32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_FLTP},
66      {AudioSampleFormat::SAMPLE_F64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBL},
67      {AudioSampleFormat::SAMPLE_F64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBLP},
68      {AudioSampleFormat::SAMPLE_S64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64},
69      {AudioSampleFormat::SAMPLE_U64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
70      {AudioSampleFormat::SAMPLE_S64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64P},
71      {AudioSampleFormat::SAMPLE_U64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
72  };
73  
AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,OHOS::AudioStandard::InterruptMode & interruptMode)74  void AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,
75      OHOS::AudioStandard::InterruptMode &interruptMode)
76  {
77      for (const auto &item : g_auInterruptMap) {
78          if (item.first == audioInterruptMode) {
79              interruptMode = item.second;
80          }
81      }
82  }
83  
UpdateSupportedSampleRate(Capability & inCaps)84  void UpdateSupportedSampleRate(Capability &inCaps)
85  {
86      auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
87      if (!supportedSampleRateList.empty()) {
88          DiscreteCapability<uint32_t> values;
89          for (const auto &rate : supportedSampleRateList) {
90              values.push_back(static_cast<uint32_t>(rate));
91          }
92          if (!values.empty()) {
93              inCaps.AppendDiscreteKeys<uint32_t>(OHOS::Media::Tag::AUDIO_SAMPLE_RATE, values);
94          }
95      }
96  }
97  
UpdateSupportedSampleFormat(Capability & inCaps)98  void UpdateSupportedSampleFormat(Capability &inCaps)
99  {
100      DiscreteCapability<AudioSampleFormat> values(g_aduFmtMap.size());
101      for (const auto &item : g_aduFmtMap) {
102          if (std::get<1>(item) != OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH ||
103              std::get<TUPLE_SECOND_ITEM_INDEX>(item) != AV_SAMPLE_FMT_NONE) {
104              values.emplace_back(std::get<0>(item));
105          }
106      }
107      inCaps.AppendDiscreteKeys(OHOS::Media::Tag::AUDIO_SAMPLE_FORMAT, values);
108  }
109  
AudioServerSinkRegister(const std::shared_ptr<Register> & reg)110  OHOS::Media::Status AudioServerSinkRegister(const std::shared_ptr<Register> &reg)
111  {
112      AudioSinkPluginDef definition;
113      definition.name = "AudioServerSink";
114      definition.description = "Audio sink for audio server of media standard";
115      definition.rank = 100; // 100: max rank
116      auto func = [](const std::string &name) -> std::shared_ptr<AudioSinkPlugin> {
117          return std::make_shared<OHOS::Media::Plugins::AudioServerSinkPlugin>(name);
118      };
119      definition.SetCreator(func);
120      Capability inCaps(MimeType::AUDIO_RAW);
121      UpdateSupportedSampleRate(inCaps);
122      UpdateSupportedSampleFormat(inCaps);
123      definition.AddInCaps(inCaps);
124      return reg->AddPlugin(definition);
125  }
126  
__anonb92ec06b0302null127  PLUGIN_DEFINITION(AudioServerSink, LicenseType::APACHE_V2, AudioServerSinkRegister, [] {});
128  
ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams & param)129  inline void ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams &param)
130  {
131      using namespace OHOS::AudioStandard;
132      param.sampleFormat = OHOS::AudioStandard::INVALID_WIDTH;
133      param.sampleRate = SAMPLE_RATE_8000;
134      param.channelCount = OHOS::AudioStandard::MONO;
135      param.encodingType = ENCODING_INVALID;
136  }
137  } // namespace
138  
139  namespace OHOS {
140  namespace Media {
141  namespace Plugins {
142  using namespace OHOS::Media::Plugins;
143  
AudioRendererCallbackImpl(const std::shared_ptr<Pipeline::EventReceiver> & receiver,const bool & isPaused)144  AudioServerSinkPlugin::AudioRendererCallbackImpl::AudioRendererCallbackImpl(
145      const std::shared_ptr<Pipeline::EventReceiver> &receiver, const bool &isPaused) : playerEventReceiver_(receiver),
146      isPaused_(isPaused)
147  {
148  }
149  
AudioServiceDiedCallbackImpl(std::shared_ptr<Pipeline::EventReceiver> & receiver)150  AudioServerSinkPlugin::AudioServiceDiedCallbackImpl::AudioServiceDiedCallbackImpl(
151      std::shared_ptr<Pipeline::EventReceiver> &receiver) : playerEventReceiver_(receiver)
152  {
153  }
154  
AudioFirstFrameCallbackImpl(std::shared_ptr<Pipeline::EventReceiver> & receiver)155  AudioServerSinkPlugin::AudioFirstFrameCallbackImpl::AudioFirstFrameCallbackImpl(
156      std::shared_ptr<Pipeline::EventReceiver> &receiver)
157  {
158      FALSE_RETURN(receiver != nullptr);
159      playerEventReceiver_ = receiver;
160  }
161  
OnInterrupt(const OHOS::AudioStandard::InterruptEvent & interruptEvent)162  void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnInterrupt(
163      const OHOS::AudioStandard::InterruptEvent &interruptEvent)
164  {
165      MEDIA_LOG_D_T("OnInterrupt forceType is " PUBLIC_LOG_U32, static_cast<uint32_t>(interruptEvent.forceType));
166      if (interruptEvent.forceType == OHOS::AudioStandard::INTERRUPT_FORCE) {
167          switch (interruptEvent.hintType) {
168              case OHOS::AudioStandard::INTERRUPT_HINT_PAUSE:
169                  isPaused_ = true;
170                  break;
171              default:
172                  isPaused_ = false;
173                  break;
174          }
175      }
176      Event event {
177          .srcFilter = "Audio interrupt event",
178          .type = EventType::EVENT_AUDIO_INTERRUPT,
179          .param = interruptEvent
180      };
181      FALSE_RETURN(playerEventReceiver_ != nullptr);
182      MEDIA_LOG_D_T("OnInterrupt event upload ");
183      playerEventReceiver_->OnEvent(event);
184  }
185  
OnStateChange(const OHOS::AudioStandard::RendererState state,const OHOS::AudioStandard::StateChangeCmdType cmdType)186  void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnStateChange(
187      const OHOS::AudioStandard::RendererState state, const OHOS::AudioStandard::StateChangeCmdType cmdType)
188  {
189      MEDIA_LOG_D_T("RenderState is " PUBLIC_LOG_U32, static_cast<uint32_t>(state));
190      if (cmdType == AudioStandard::StateChangeCmdType::CMD_FROM_SYSTEM) {
191          Event event {
192              .srcFilter = "Audio state change event",
193              .type = EventType::EVENT_AUDIO_STATE_CHANGE,
194              .param = state
195          };
196          FALSE_RETURN(playerEventReceiver_ != nullptr);
197          playerEventReceiver_->OnEvent(event);
198      }
199  }
200  
OnOutputDeviceChange(const AudioStandard::DeviceInfo & deviceInfo,const AudioStandard::AudioStreamDeviceChangeReason reason)201  void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnOutputDeviceChange(
202      const AudioStandard::DeviceInfo &deviceInfo, const AudioStandard::AudioStreamDeviceChangeReason reason)
203  {
204      MEDIA_LOG_D_T("DeviceChange reason is " PUBLIC_LOG_D32, static_cast<int32_t>(reason));
205      auto param = std::make_pair(deviceInfo, reason);
206      Event event {
207          .srcFilter = "Audio deviceChange change event",
208          .type = EventType::EVENT_AUDIO_DEVICE_CHANGE,
209          .param = param
210      };
211      FALSE_RETURN(playerEventReceiver_ != nullptr);
212      playerEventReceiver_->OnEvent(event);
213  }
214  
OnFirstFrameWriting(uint64_t latency)215  void AudioServerSinkPlugin::AudioFirstFrameCallbackImpl::OnFirstFrameWriting(uint64_t latency)
216  {
217      MEDIA_LOG_I_T("OnFirstFrameWriting latency: " PUBLIC_LOG_U64, latency);
218      Event event {
219          .srcFilter = "Audio render first frame writing event",
220          .type = EventType::EVENT_AUDIO_FIRST_FRAME,
221          .param = latency
222      };
223      FALSE_RETURN(playerEventReceiver_ != nullptr);
224      playerEventReceiver_->OnEvent(event);
225      MEDIA_LOG_I_T("OnFirstFrameWriting event upload ");
226  }
227  
OnAudioPolicyServiceDied()228  void AudioServerSinkPlugin::AudioServiceDiedCallbackImpl::OnAudioPolicyServiceDied()
229  {
230      MEDIA_LOG_I_T("OnAudioPolicyServiceDied enter");
231      Event event {
232          .srcFilter = "Audio service died event",
233          .type = EventType::EVENT_AUDIO_SERVICE_DIED
234      };
235      FALSE_RETURN(playerEventReceiver_ != nullptr);
236      playerEventReceiver_->OnEvent(event);
237      MEDIA_LOG_I_T("OnAudioPolicyServiceDied end");
238  }
239  
AudioServerSinkPlugin(std::string name)240  AudioServerSinkPlugin::AudioServerSinkPlugin(std::string name)
241      : Plugins::AudioSinkPlugin(std::move(name)), audioRenderer_(nullptr)
242  {
243      SetUpParamsSetterMap();
244      SetAudioDumpBySysParam();
245  }
246  
~AudioServerSinkPlugin()247  AudioServerSinkPlugin::~AudioServerSinkPlugin()
248  {
249      MEDIA_LOG_I_T("~AudioServerSinkPlugin() entered.");
250      ReleaseRender();
251      ReleaseFile();
252  }
253  
Init()254  Status AudioServerSinkPlugin::Init()
255  {
256      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Init");
257      MEDIA_LOG_I_T("Init entered.");
258      FALSE_RETURN_V_MSG(audioRenderer_ == nullptr, Status::OK, "audio renderer already create ");
259      AudioStandard::AppInfo appInfo;
260      appInfo.appPid = appPid_;
261      appInfo.appUid = appUid_;
262      MEDIA_LOG_I_T("Create audio renderer for apppid_ " PUBLIC_LOG_D32 " appuid_ " PUBLIC_LOG_D32
263                  " contentType " PUBLIC_LOG_D32 " streamUsage " PUBLIC_LOG_D32 " rendererFlags " PUBLIC_LOG_D32
264                  " audioInterruptMode_ " PUBLIC_LOG_U32,
265                  appPid_, appUid_, audioRenderInfo_.contentType, audioRenderInfo_.streamUsage,
266                  audioRenderInfo_.rendererFlags, static_cast<uint32_t>(audioInterruptMode_));
267      rendererOptions_.rendererInfo.contentType = static_cast<AudioStandard::ContentType>(audioRenderInfo_.contentType);
268      rendererOptions_.rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(audioRenderInfo_.streamUsage);
269      rendererOptions_.rendererInfo.rendererFlags = audioRenderInfo_.rendererFlags;
270      rendererOptions_.streamInfo.samplingRate = rendererParams_.sampleRate;
271      rendererOptions_.streamInfo.encoding =
272          mimeType_ == MimeType::AUDIO_AVS3DA ? AudioStandard::ENCODING_AUDIOVIVID : AudioStandard::ENCODING_PCM;
273      rendererOptions_.streamInfo.format = rendererParams_.sampleFormat;
274      rendererOptions_.streamInfo.channels = rendererParams_.channelCount;
275      MEDIA_LOG_I_T("Create audio renderer for samplingRate " PUBLIC_LOG_D32 " encoding " PUBLIC_LOG_D32
276                  " sampleFormat " PUBLIC_LOG_D32 " channels " PUBLIC_LOG_D32,
277                  rendererOptions_.streamInfo.samplingRate, rendererOptions_.streamInfo.encoding,
278                  rendererOptions_.streamInfo.format, rendererOptions_.streamInfo.channels);
279      audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions_, appInfo);
280      if (audioRenderer_ == nullptr && playerEventReceiver_ != nullptr) {
281          playerEventReceiver_->OnEvent({"audioSinkPlugin", EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_SAMPLE_RATE});
282      }
283      FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
284      if (audioRenderSetFlag_ && (audioRenderInfo_.streamUsage == AudioStandard::STREAM_USAGE_MUSIC ||
285          audioRenderInfo_.streamUsage == AudioStandard::STREAM_USAGE_AUDIOBOOK)) {
286          audioRenderer_->SetOffloadAllowed(true);
287      } else {
288          audioRenderer_->SetOffloadAllowed(false);
289      }
290      audioRenderer_->SetInterruptMode(audioInterruptMode_);
291      return Status::OK;
292  }
293  
GetSampleFormat()294  AudioSampleFormat AudioServerSinkPlugin::GetSampleFormat()
295  {
296      return static_cast<AudioSampleFormat>(rendererOptions_.streamInfo.format);
297  }
298  
ReleaseRender()299  void AudioServerSinkPlugin::ReleaseRender()
300  {
301      if (audioRenderer_ != nullptr && audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_RELEASED) {
302          MEDIA_LOG_I_T("AudioRenderer::Release start");
303          FALSE_RETURN_MSG(audioRenderer_->Release(), "AudioRenderer::Release failed");
304          MEDIA_LOG_I_T("AudioRenderer::Release end");
305      }
306      audioRenderer_.reset();
307  }
308  
ReleaseFile()309  void AudioServerSinkPlugin::ReleaseFile()
310  {
311      if (entireDumpFile_ != nullptr) {
312          (void)fclose(entireDumpFile_);
313          entireDumpFile_ = nullptr;
314      }
315      if (sliceDumpFile_ != nullptr) {
316          (void)fclose(sliceDumpFile_);
317          sliceDumpFile_ = nullptr;
318      }
319  }
320  
Deinit()321  Status AudioServerSinkPlugin::Deinit()
322  {
323      MEDIA_LOG_D_T("Deinit entered");
324      ReleaseRender();
325      ReleaseFile();
326      return Status::OK;
327  }
328  
Prepare()329  Status AudioServerSinkPlugin::Prepare()
330  {
331      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Prepare");
332      MEDIA_LOG_D_T("Prepare >>");
333      auto types = AudioStandard::AudioRenderer::GetSupportedEncodingTypes();
334      bool ret = CppExt::AnyOf(types.begin(), types.end(), [](AudioStandard::AudioEncodingType tmp) -> bool {
335          return tmp == AudioStandard::ENCODING_PCM;
336      });
337      FALSE_RETURN_V_MSG(ret, Status::ERROR_INVALID_PARAMETER, "audio renderer do not support pcm encoding");
338      {
339          FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
340          if (audioRendererCallback_ == nullptr) {
341              audioRendererCallback_ = std::make_shared<AudioRendererCallbackImpl>(playerEventReceiver_, isForcePaused_);
342              audioRenderer_->SetRendererCallback(audioRendererCallback_);
343              audioRenderer_->RegisterOutputDeviceChangeWithInfoCallback(audioRendererCallback_);
344          }
345          if (audioFirstFrameCallback_ == nullptr) {
346              audioFirstFrameCallback_ = std::make_shared<AudioFirstFrameCallbackImpl>(playerEventReceiver_);
347              audioRenderer_->SetRendererFirstFrameWritingCallback(audioFirstFrameCallback_);
348          }
349          if (audioServiceDiedCallback_ == nullptr) {
350              audioServiceDiedCallback_ = std::make_shared<AudioServiceDiedCallbackImpl>(playerEventReceiver_);
351              audioRenderer_->RegisterAudioPolicyServerDiedCb(getprocpid(), audioServiceDiedCallback_);
352          }
353      }
354      MEDIA_LOG_I_T("Prepare <<");
355      return Status::OK;
356  }
357  
StopRender()358  bool AudioServerSinkPlugin::StopRender()
359  {
360      if (audioRenderer_) {
361          //The audio stop interface cannot be quickly stopped.
362          if (audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING) {
363              MEDIA_LOG_I_T("pause entered.");
364              return audioRenderer_->Pause();
365          }
366          FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_STOPPED,
367              true, "AudioRenderer is already in stopped state.");
368          sliceCount_++;
369          return audioRenderer_->Stop();
370      }
371      return true;
372  }
373  
Reset()374  Status AudioServerSinkPlugin::Reset()
375  {
376      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Reset");
377      MEDIA_LOG_I_T("Reset entered.");
378      FALSE_RETURN_V_MSG(StopRender(), Status::ERROR_UNKNOWN, "stop render error");
379      ResetAudioRendererParams(rendererParams_);
380      fmtSupported_ = false;
381      reSrcFfFmt_ = AV_SAMPLE_FMT_NONE;
382      channels_ = 0;
383      bitRate_ = 0;
384      sampleRate_ = 0;
385      samplesPerFrame_ = 0;
386      needReformat_ = false;
387      if (resample_) {
388          resample_.reset();
389      }
390      return Status::OK;
391  }
392  
Start()393  Status AudioServerSinkPlugin::Start()
394  {
395      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Start");
396      MEDIA_LOG_D_T("Start entered.");
397      if (audioRenderer_ == nullptr) {
398          return Status::ERROR_WRONG_STATE;
399      }
400      bool ret = audioRenderer_->Start();
401      FALSE_RETURN_V_MSG(ret, Status::ERROR_UNKNOWN, "AudioRenderer::Start failed");
402      MEDIA_LOG_I_T("AudioRenderer::Start end");
403      return Status::OK;
404  }
405  
Stop()406  Status AudioServerSinkPlugin::Stop()
407  {
408      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Stop");
409      MEDIA_LOG_D_T("Stop entered.");
410      FALSE_RETURN_V_MSG(StopRender(), Status::ERROR_UNKNOWN, "stop render failed");
411      MEDIA_LOG_I_T("stop render success");
412      return Status::OK;
413  }
414  
SetVolumeWithRamp(float targetVolume,int32_t duration)415  int32_t AudioServerSinkPlugin::SetVolumeWithRamp(float targetVolume, int32_t duration)
416  {
417      MEDIA_LOG_D_T("SetVolumeWithRamp entered.");
418      int32_t ret = 0;
419      {
420          if (audioRenderer_ == nullptr) {
421              return 0;
422          }
423          if (duration == 0) {
424              ret = audioRenderer_->SetVolume(targetVolume);
425          } else {
426              MEDIA_LOG_I_T("plugin set vol AudioRenderer::SetVolumeWithRamp start");
427              ret = audioRenderer_->SetVolumeWithRamp(targetVolume, duration);
428              MEDIA_LOG_I_T("plugin set vol AudioRenderer::SetVolumeWithRamp end");
429          }
430      }
431      OHOS::Media::SleepInJob(duration + 40); // fade out sleep more 40 ms
432      MEDIA_LOG_I_T("SetVolumeWithRamp end.");
433      return ret;
434  }
435  
GetParameter(std::shared_ptr<Meta> & meta)436  Status AudioServerSinkPlugin::GetParameter(std::shared_ptr<Meta> &meta)
437  {
438      AudioStandard::AudioRendererParams params;
439      meta->Set<Tag::MEDIA_BITRATE>(bitRate_);
440      if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
441          MEDIA_LOG_I_T("get param with fmt " PUBLIC_LOG_D32 " sampleRate " PUBLIC_LOG_D32 " channel " PUBLIC_LOG_D32
442                      " encode type " PUBLIC_LOG_D32,
443                      params.sampleFormat, params.sampleRate, params.channelCount, params.encodingType);
444          if (params.sampleRate != rendererParams_.sampleRate) {
445              MEDIA_LOG_W("samplingRate has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
446                          rendererParams_.sampleRate, params.sampleRate);
447          }
448          meta->Set<Tag::AUDIO_SAMPLE_RATE>(params.sampleRate);
449          if (params.sampleFormat != rendererParams_.sampleFormat) {
450              MEDIA_LOG_W("sampleFormat has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
451                          rendererParams_.sampleFormat, params.sampleFormat);
452          }
453          for (const auto &item : g_aduFmtMap) {
454              if (std::get<1>(item) == params.sampleFormat) {
455                  meta->Set<Tag::AUDIO_SAMPLE_FORMAT>(std::get<0>(item));
456              }
457          }
458      }
459      return Status::OK;
460  }
461  
AssignSampleRateIfSupported(uint32_t sampleRate)462  bool AudioServerSinkPlugin::AssignSampleRateIfSupported(uint32_t sampleRate)
463  {
464      sampleRate_ = sampleRate;
465      auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
466      FALSE_RETURN_V_MSG(!supportedSampleRateList.empty(), false, "GetSupportedSamplingRates fail");
467      for (const auto &rate : supportedSampleRateList) {
468          if (static_cast<uint32_t>(rate) == sampleRate) {
469              rendererParams_.sampleRate = rate;
470              MEDIA_LOG_D_T("sampleRate: " PUBLIC_LOG_U32, rendererParams_.sampleRate);
471              return true;
472          }
473      }
474      MEDIA_LOG_E_T("sample rate " PUBLIC_LOG_U32 "not supported", sampleRate);
475      return false;
476  }
477  
AssignChannelNumIfSupported(uint32_t channelNum)478  bool AudioServerSinkPlugin::AssignChannelNumIfSupported(uint32_t channelNum)
479  {
480      auto supportedChannelsList = OHOS::AudioStandard::AudioRenderer::GetSupportedChannels();
481      FALSE_RETURN_V_MSG(!supportedChannelsList.empty(), false, "GetSupportedChannels fail");
482      for (const auto &channel : supportedChannelsList) {
483          if (static_cast<uint32_t>(channel) == channelNum) {
484              rendererParams_.channelCount = channel;
485              MEDIA_LOG_D_T("channelCount: " PUBLIC_LOG_U32, rendererParams_.channelCount);
486              return true;
487          }
488      }
489      MEDIA_LOG_E_T("channel num " PUBLIC_LOG_U32 "not supported", channelNum);
490      return false;
491  }
492  
AssignSampleFmtIfSupported(Plugins::AudioSampleFormat sampleFormat)493  bool AudioServerSinkPlugin::AssignSampleFmtIfSupported(Plugins::AudioSampleFormat sampleFormat)
494  {
495      MEDIA_LOG_I_T("AssignSampleFmtIfSupported AudioSampleFormat " PUBLIC_LOG_D32, sampleFormat);
496      const auto &item = std::find_if(g_aduFmtMap.begin(), g_aduFmtMap.end(), [&sampleFormat](const auto &tmp) -> bool {
497          return std::get<0>(tmp) == sampleFormat;
498      });
499      auto stdFmt = std::get<1>(*item);
500      if (stdFmt == OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH) {
501          if (std::get<2>(*item) == AV_SAMPLE_FMT_NONE) { // 2
502              MEDIA_LOG_I_T("AssignSampleFmtIfSupported AV_SAMPLE_FMT_NONE");
503              fmtSupported_ = false;
504          } else {
505              MEDIA_LOG_I_T("AssignSampleFmtIfSupported needReformat_");
506              fmtSupported_ = true;
507              needReformat_ = true;
508              reSrcFfFmt_ = std::get<2>(*item); // 2
509              rendererParams_.sampleFormat = reStdDestFmt_;
510          }
511      } else {
512          auto supportedFmts = OHOS::AudioStandard::AudioRenderer::GetSupportedFormats();
513          if (CppExt::AnyOf(supportedFmts.begin(), supportedFmts.end(),
514                            [&stdFmt](const auto &tmp) -> bool { return tmp == stdFmt; })) {
515              MEDIA_LOG_I_T("AssignSampleFmtIfSupported needReformat_ false");
516              fmtSupported_ = true;
517              needReformat_ = false;
518          } else {
519              fmtSupported_ = false;
520              needReformat_ = false;
521          }
522          rendererParams_.sampleFormat = stdFmt;
523      }
524      return fmtSupported_;
525  }
526  
SetInterruptMode(AudioStandard::InterruptMode interruptMode)527  void AudioServerSinkPlugin::SetInterruptMode(AudioStandard::InterruptMode interruptMode)
528  {
529      if (audioRenderer_) {
530          audioRenderer_->SetInterruptMode(interruptMode);
531      }
532  }
533  
SetUpParamsSetterMap()534  void AudioServerSinkPlugin::SetUpParamsSetterMap()
535  {
536      SetUpMimeTypeSetter();
537      SetUpSampleRateSetter();
538      SetUpAudioOutputChannelsSetter();
539      SetUpMediaBitRateSetter();
540      SetUpAudioSampleFormatSetter();
541      SetUpAudioOutputChannelLayoutSetter();
542      SetUpAudioSamplePerFrameSetter();
543      SetUpBitsPerCodedSampleSetter();
544      SetUpMediaSeekableSetter();
545      SetUpAppPidSetter();
546      SetUpAppUidSetter();
547      SetUpAudioRenderInfoSetter();
548      SetUpAudioRenderSetFlagSetter();
549      SetUpAudioInterruptModeSetter();
550  }
551  
SetUpMimeTypeSetter()552  void AudioServerSinkPlugin::SetUpMimeTypeSetter()
553  {
554      paramsSetterMap_[Tag::MIME_TYPE] = [this](const ValueType &para) {
555          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<std::string>(para), Status::ERROR_MISMATCHED_TYPE,
556                               "mimeType type should be string");
557          mimeType_ = AnyCast<std::string>(para);
558          MEDIA_LOG_I_T("Set mimeType: " PUBLIC_LOG_S, mimeType_.c_str());
559          return Status::OK;
560      };
561  }
562  
SetUpSampleRateSetter()563  void AudioServerSinkPlugin::SetUpSampleRateSetter()
564  {
565      paramsSetterMap_[Tag::AUDIO_SAMPLE_RATE] = [this](const ValueType &para) {
566          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
567                               "sample rate type should be int32_t");
568          if (!AssignSampleRateIfSupported(AnyCast<int32_t>(para))) {
569              MEDIA_LOG_E_T("sampleRate isn't supported");
570              playerEventReceiver_->OnEvent({"sampleRate isn't supported",
571                  EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_SAMPLE_RATE});
572              return Status::ERROR_INVALID_PARAMETER;
573          }
574          return Status::OK;
575      };
576  }
577  
SetUpAudioOutputChannelsSetter()578  void AudioServerSinkPlugin::SetUpAudioOutputChannelsSetter()
579  {
580      paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNELS] = [this](const ValueType &para) {
581          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
582                               "channels type should be int32_t");
583          channels_ = AnyCast<uint32_t>(para);
584          MEDIA_LOG_I_T("Set outputChannels: " PUBLIC_LOG_U32, channels_);
585          if (!AssignChannelNumIfSupported(channels_)) {
586              MEDIA_LOG_E_T("channel isn't supported");
587              playerEventReceiver_->OnEvent({"channel isn't supported",
588                  EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_CHANNEL_NUM});
589              return Status::ERROR_INVALID_PARAMETER;
590          }
591          return Status::OK;
592      };
593  }
594  
SetUpMediaBitRateSetter()595  void AudioServerSinkPlugin::SetUpMediaBitRateSetter()
596  {
597      paramsSetterMap_[Tag::MEDIA_BITRATE] = [this](const ValueType &para) {
598          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int64_t>(para), Status::ERROR_MISMATCHED_TYPE,
599                               "bit rate type should be int64_t");
600          bitRate_ = AnyCast<int64_t>(para);
601          return Status::OK;
602      };
603  }
SetUpAudioSampleFormatSetter()604  void AudioServerSinkPlugin::SetUpAudioSampleFormatSetter()
605  {
606      paramsSetterMap_[Tag::AUDIO_SAMPLE_FORMAT] = [this](const ValueType &para) {
607          MEDIA_LOG_I_T("SetUpAudioSampleFormat");
608          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioSampleFormat>(para), Status::ERROR_MISMATCHED_TYPE,
609                               "AudioSampleFormat type should be AudioSampleFormat");
610          if (!AssignSampleFmtIfSupported(AnyCast<AudioSampleFormat>(para))) {
611              MEDIA_LOG_E_T("sampleFmt isn't supported by audio renderer or resample lib");
612              playerEventReceiver_->OnEvent({"sampleFmt isn't supported",
613                  EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_PARAMS});
614              return Status::ERROR_INVALID_PARAMETER;
615          }
616          return Status::OK;
617      };
618  }
SetUpAudioOutputChannelLayoutSetter()619  void AudioServerSinkPlugin::SetUpAudioOutputChannelLayoutSetter()
620  {
621      paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT] = [this](const ValueType &para) {
622          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioChannelLayout>(para), Status::ERROR_MISMATCHED_TYPE,
623                               "channel layout type should be AudioChannelLayout");
624          channelLayout_ = AnyCast<AudioChannelLayout>(para);
625          MEDIA_LOG_I_T("Set outputChannelLayout: " PUBLIC_LOG_U64, channelLayout_);
626          return Status::OK;
627      };
628  }
SetUpAudioSamplePerFrameSetter()629  void AudioServerSinkPlugin::SetUpAudioSamplePerFrameSetter()
630  {
631      paramsSetterMap_[Tag::AUDIO_SAMPLE_PER_FRAME] = [this](const ValueType &para) {
632          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
633                               "SAMPLE_PER_FRAME type should be int32_t");
634          samplesPerFrame_ = AnyCast<uint32_t>(para);
635          return Status::OK;
636      };
637  }
SetUpBitsPerCodedSampleSetter()638  void AudioServerSinkPlugin::SetUpBitsPerCodedSampleSetter()
639  {
640      paramsSetterMap_[Tag::AUDIO_BITS_PER_CODED_SAMPLE] = [this](const ValueType &para) {
641          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
642                               "BITS_PER_CODED_SAMPLE type should be int32_t");
643          bitsPerSample_ = AnyCast<uint32_t>(para);
644          return Status::OK;
645      };
646  }
SetUpMediaSeekableSetter()647  void AudioServerSinkPlugin::SetUpMediaSeekableSetter()
648  {
649      paramsSetterMap_[Tag::MEDIA_SEEKABLE] = [this](const ValueType &para) {
650          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<Seekable>(para), Status::ERROR_MISMATCHED_TYPE,
651                               "MEDIA_SEEKABLE type should be Seekable");
652          seekable_ = AnyCast<Plugins::Seekable>(para);
653          return Status::OK;
654      };
655  }
SetUpAppPidSetter()656  void AudioServerSinkPlugin::SetUpAppPidSetter()
657  {
658      paramsSetterMap_[Tag::APP_PID] = [this](const ValueType &para) {
659          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
660                               "APP_PID type should be int32_t");
661          appPid_ = AnyCast<int32_t>(para);
662          return Status::OK;
663      };
664  }
SetUpAppUidSetter()665  void AudioServerSinkPlugin::SetUpAppUidSetter()
666  {
667      paramsSetterMap_[Tag::APP_UID] = [this](const ValueType &para) {
668          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
669                               "APP_UID type should be int32_t");
670          appUid_ = AnyCast<int32_t>(para);
671          return Status::OK;
672      };
673  }
SetUpAudioRenderInfoSetter()674  void AudioServerSinkPlugin::SetUpAudioRenderInfoSetter()
675  {
676      paramsSetterMap_[Tag::AUDIO_RENDER_INFO] = [this](const ValueType &para) {
677          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioRenderInfo>(para), Status::ERROR_MISMATCHED_TYPE,
678                               "AUDIO_RENDER_INFO type should be AudioRenderInfo");
679          audioRenderInfo_ = AnyCast<AudioRenderInfo>(para);
680          return Status::OK;
681      };
682  }
683  
SetUpAudioRenderSetFlagSetter()684  void AudioServerSinkPlugin::SetUpAudioRenderSetFlagSetter()
685  {
686      paramsSetterMap_[Tag::AUDIO_RENDER_SET_FLAG] = [this](const ValueType &para) {
687          if (!Any::IsSameTypeWith<bool>(para)) {
688              MEDIA_LOG_E_T("AUDIO_RENDER_SET_FLAG type should be bool");
689              playerEventReceiver_->OnEvent({"AUDIO_RENDER_SET_FLAG type is not bool",
690                  EventType::EVENT_ERROR, MSERR_EXT_API9_INVALID_PARAMETER});
691              return Status::ERROR_MISMATCHED_TYPE;
692          }
693          audioRenderSetFlag_ = AnyCast<bool>(para);
694          return Status::OK;
695      };
696  }
697  
SetUpAudioInterruptModeSetter()698  void AudioServerSinkPlugin::SetUpAudioInterruptModeSetter()
699  {
700      paramsSetterMap_[Tag::AUDIO_INTERRUPT_MODE] = [this](const ValueType &para) {
701          FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
702              "AUDIO_INTERRUPT_MODE type should be int32_t");
703          AudioInterruptMode2InterruptMode(AnyCast<AudioInterruptMode>(para), audioInterruptMode_);
704          SetInterruptMode(audioInterruptMode_);
705          return Status::OK;
706      };
707  }
708  
SetParameter(const std::shared_ptr<Meta> & meta)709  Status AudioServerSinkPlugin::SetParameter(const std::shared_ptr<Meta> &meta)
710  {
711      for (MapIt iter = meta->begin(); iter != meta->end(); iter++) {
712          MEDIA_LOG_D_T("SetParameter iter->first " PUBLIC_LOG_S, iter->first.c_str());
713          if (paramsSetterMap_.find(iter->first) == paramsSetterMap_.end()) {
714              continue;
715          }
716          std::function<Status(const ValueType &para)> paramSetter = paramsSetterMap_[iter->first];
717          paramSetter(iter->second);
718      }
719      return Status::OK;
720  }
721  
GetVolume(float & volume)722  Status AudioServerSinkPlugin::GetVolume(float &volume)
723  {
724      MEDIA_LOG_I_T("GetVolume entered.");
725      if (audioRenderer_ != nullptr) {
726          volume = audioRenderer_->GetVolume();
727          return Status::OK;
728      }
729      return Status::ERROR_WRONG_STATE;
730  }
731  
SetVolume(float volume)732  Status AudioServerSinkPlugin::SetVolume(float volume)
733  {
734      MEDIA_LOG_D("SetVolume entered.");
735      if (audioRenderer_ != nullptr) {
736          int32_t ret = audioRenderer_->SetVolume(volume);
737          FALSE_RETURN_V_MSG_E(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
738              "set volume failed with code " PUBLIC_LOG_D32, ret);
739          MEDIA_LOG_D("SetVolume succ");
740          audioRendererVolume_ = volume;
741          return Status::OK;
742      }
743      return Status::ERROR_WRONG_STATE;
744  }
745  
GetAudioEffectMode(int32_t & effectMode)746  Status AudioServerSinkPlugin::GetAudioEffectMode(int32_t &effectMode)
747  {
748      MEDIA_LOG_I_T("GetAudioEffectMode entered.");
749      if (audioRenderer_ != nullptr) {
750          effectMode = audioRenderer_->GetAudioEffectMode();
751          MEDIA_LOG_I_T("GetAudioEffectMode %{public}d", effectMode);
752          return Status::OK;
753      }
754      return Status::ERROR_WRONG_STATE;
755  }
756  
SetAudioEffectMode(int32_t effectMode)757  Status AudioServerSinkPlugin::SetAudioEffectMode(int32_t effectMode)
758  {
759      MEDIA_LOG_I_T("SetAudioEffectMode %{public}d", effectMode);
760      if (audioRenderer_ != nullptr) {
761          int32_t ret = audioRenderer_->SetAudioEffectMode(static_cast<OHOS::AudioStandard::AudioEffectMode>(effectMode));
762          FALSE_RETURN_V_MSG(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
763              "set AudioEffectMode failed with code " PUBLIC_LOG_D32, ret);
764          return Status::OK;
765      }
766      return Status::ERROR_WRONG_STATE;
767  }
768  
GetSpeed(float & speed)769  Status AudioServerSinkPlugin::GetSpeed(float &speed)
770  {
771      MEDIA_LOG_I_T("GetSpeed entered.");
772      if (audioRenderer_ != nullptr) {
773          speed = audioRenderer_->GetSpeed();
774          return Status::OK;
775      }
776      return Status::ERROR_WRONG_STATE;
777  }
778  
SetSpeed(float speed)779  Status AudioServerSinkPlugin::SetSpeed(float speed)
780  {
781      MEDIA_LOG_I_T("SetSpeed entered.");
782      if (audioRenderer_ != nullptr) {
783          int32_t ret = audioRenderer_->SetSpeed(speed);
784          FALSE_RETURN_V_MSG(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
785              "set speed failed with code " PUBLIC_LOG_D32, ret);
786          return Status::OK;
787      }
788      return Status::ERROR_WRONG_STATE;
789  }
790  
Resume()791  Status AudioServerSinkPlugin::Resume()
792  {
793      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Resume");
794      MEDIA_LOG_D_T("Resume entered");
795      return Start();
796  }
797  
Pause()798  Status AudioServerSinkPlugin::Pause()
799  {
800      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Pause");
801      MEDIA_LOG_I_T("Pause entered");
802      FALSE_RETURN_V_MSG(audioRenderer_ != nullptr, Status::ERROR_UNKNOWN, "audio renderer pause fail");
803      FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING,
804          Status::OK, "audio renderer no need pause");
805      sliceCount_++;
806      FALSE_RETURN_V_MSG_W(audioRenderer_->Pause(), Status::ERROR_UNKNOWN, "renderer pause fail.");
807      MEDIA_LOG_I_T("audio renderer pause success");
808      return Status::OK;
809  }
810  
PauseTransitent()811  Status AudioServerSinkPlugin::PauseTransitent()
812  {
813      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::PauseTransitent");
814      MEDIA_LOG_I_T("PauseTransitent entered.");
815      FALSE_RETURN_V_MSG(audioRenderer_ != nullptr, Status::ERROR_UNKNOWN, "audio renderer pauseTransitent fail");
816      FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING,
817          Status::OK, "audio renderer no need pauseTransitent");
818      sliceCount_++;
819      FALSE_RETURN_V_MSG_W(audioRenderer_->PauseTransitent(), Status::ERROR_UNKNOWN, "renderer pauseTransitent fail.");
820      MEDIA_LOG_I_T("audio renderer pauseTransitent success");
821      return Status::OK;
822  }
823  
GetLatency(uint64_t & hstTime)824  Status AudioServerSinkPlugin::GetLatency(uint64_t &hstTime)
825  {
826      FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
827      audioRenderer_->GetLatency(hstTime); // audioRender->getLatency lack accuracy
828      return Status::OK;
829  }
830  
DrainCacheData(bool render)831  Status AudioServerSinkPlugin::DrainCacheData(bool render)
832  {
833      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::DrainCacheData " + std::to_string(render));
834      if (!render) {
835          MEDIA_LOG_D("Drop cache buffer because render=false");
836          cachedBuffers_.clear();
837          return Status::OK;
838      }
839      if (cachedBuffers_.empty()) {
840          return Status::OK;
841      }
842      AudioStandard::RendererState rendererState = (audioRenderer_ != nullptr) ?
843          audioRenderer_->GetStatus() : AudioStandard::RendererState::RENDERER_INVALID;
844      FALSE_RETURN_V_MSG(rendererState != AudioStandard::RendererState::RENDERER_PAUSED,
845          Status::ERROR_AGAIN, "audioRenderer_ is still paused, try again later");
846      if (rendererState != AudioStandard::RendererState::RENDERER_RUNNING) {
847          cachedBuffers_.clear();
848          MEDIA_LOG_W("Drop cache buffer because audioRenderer_ state invalid");
849          return Status::ERROR_UNKNOWN;
850      }
851      while (cachedBuffers_.size() > 0) { // do drain cache buffers
852          auto currBuffer = cachedBuffers_.front();
853          uint8_t* destBuffer = currBuffer.data();
854          size_t destLength = currBuffer.size();
855          bool shouldDrop = false;
856          size_t remained = WriteAudioBuffer(destBuffer, destLength, shouldDrop);
857          if (remained == 0) { // write ok
858              cachedBuffers_.pop_front();
859              continue;
860          }
861          if (shouldDrop) { // write error and drop buffer
862              cachedBuffers_.clear();
863              MEDIA_LOG_W("Drop cache buffer, error happens during drain");
864              return Status::ERROR_UNKNOWN;
865          }
866          if (remained < destLength) { // some data written, then audioRender paused again, update cache
867              std::vector<uint8_t> tmpBuffer(destBuffer + destLength - remained, destBuffer + destLength);
868              cachedBuffers_.pop_front();
869              cachedBuffers_.emplace_front(std::move(tmpBuffer));
870          } // else no data written, no need to update front cache
871          MEDIA_LOG_W("Audiorender pause again during drain cache buffers");
872          return Status::ERROR_AGAIN;
873      }
874      MEDIA_LOG_I("Drain cache buffer success");
875      return Status::OK;
876  }
877  
CacheData(uint8_t * inputBuffer,size_t bufferSize)878  void AudioServerSinkPlugin::CacheData(uint8_t* inputBuffer, size_t bufferSize)
879  {
880      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::CacheData " + std::to_string(bufferSize));
881      std::vector<uint8_t> tmpBuffer(inputBuffer, inputBuffer + bufferSize);
882      cachedBuffers_.emplace_back(std::move(tmpBuffer));
883      MEDIA_LOG_I("Cache one audio buffer, data size is " PUBLIC_LOG_U64, bufferSize);
884      while (cachedBuffers_.size() > DEFAULT_BUFFER_NUM) {
885          auto dropSize = cachedBuffers_.front().size();
886          MEDIA_LOG_W("Drop one cached buffer size " PUBLIC_LOG_U64 " because max cache size reached.", dropSize);
887          cachedBuffers_.pop_front();
888      }
889  }
890  
WriteAudioBuffer(uint8_t * inputBuffer,size_t bufferSize,bool & shouldDrop)891  size_t AudioServerSinkPlugin::WriteAudioBuffer(uint8_t* inputBuffer, size_t bufferSize, bool& shouldDrop)
892  {
893      uint8_t* destBuffer = inputBuffer;
894      size_t destLength = bufferSize;
895      while (destLength > 0) {
896          MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::WriteAudioBuffer: " + std::to_string(destLength));
897          auto systemTimeBeforeWriteMs = Plugins::GetCurrentMillisecond();
898          int32_t ret = audioRenderer_->Write(destBuffer, destLength);
899          writeDuration_ = std::max(Plugins::GetCurrentMillisecond() - systemTimeBeforeWriteMs, writeDuration_);
900          if (ret < 0) {
901              if (audioRenderer_->GetStatus() == AudioStandard::RendererState::RENDERER_PAUSED) {
902                  MEDIA_LOG_W("WriteAudioBuffer error because audioRenderer_ paused, cache data.");
903                  shouldDrop = false;
904              } else {
905                  MEDIA_LOG_W("WriteAudioBuffer error because audioRenderer_ error, drop data.");
906                  shouldDrop = true;
907              }
908              break;
909          } else if (static_cast<size_t>(ret) < destLength) {
910              OHOS::Media::SleepInJob(5); // 5ms
911          }
912          if (static_cast<size_t>(ret) > destLength) {
913              MEDIA_LOG_W("audioRenderer_ return ret " PUBLIC_LOG_D32 "> destLength " PUBLIC_LOG_U64,
914                  ret, destLength);
915              ret = static_cast<int32_t>(destLength);
916          }
917          destBuffer += ret;
918          destLength -= static_cast<size_t>(ret);
919          MEDIA_LOG_D("Written data size " PUBLIC_LOG_D32 ", bufferSize " PUBLIC_LOG_U64, ret, bufferSize);
920      }
921      return destLength;
922  }
923  
Write(const std::shared_ptr<OHOS::Media::AVBuffer> & inputBuffer)924  Status AudioServerSinkPlugin::Write(const std::shared_ptr<OHOS::Media::AVBuffer> &inputBuffer)
925  {
926      MEDIA_LOG_D_T("Write buffer to audio framework");
927      FALSE_RETURN_V_MSG_W(inputBuffer != nullptr && inputBuffer->memory_->GetSize() != 0, Status::OK,
928                           "Receive empty buffer."); // return ok
929      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Write, bufferSize: "
930          + std::to_string(inputBuffer->memory_->GetSize()));
931      int32_t ret = 0;
932      if (mimeType_ == MimeType::AUDIO_AVS3DA) {
933          ret = WriteAudioVivid(inputBuffer);
934          return ret >= 0 ? Status::OK : Status::ERROR_UNKNOWN;
935      }
936      auto mem = inputBuffer->memory_;
937      auto srcBuffer = mem->GetAddr();
938      auto destBuffer = const_cast<uint8_t *>(srcBuffer);
939      auto srcLength = mem->GetSize();
940      size_t destLength = static_cast<size_t>(srcLength);
941      while (isForcePaused_ && seekable_ == Seekable::SEEKABLE) {
942          OHOS::Media::SleepInJob(5); // 5ms
943      }
944      if (audioRenderer_ == nullptr) {
945          DrainCacheData(false);
946          return Status::ERROR_NULL_POINTER;
947      }
948      auto drainCacheRet = DrainCacheData(true);
949      if (drainCacheRet != Status::OK) {
950          if (drainCacheRet == Status::ERROR_AGAIN) {
951              CacheData(destBuffer, destLength);
952          }
953          return Status::ERROR_UNKNOWN;
954      }
955      bool shouldDrop = false;
956      size_t remained = WriteAudioBuffer(destBuffer, destLength, shouldDrop);
957      if (remained == 0) {
958          return Status::OK;
959      }
960      if (!shouldDrop) {
961          CacheData(destBuffer + destLength - remained, remained);
962      }
963      return Status::ERROR_UNKNOWN;
964  }
965  
WriteAudioVivid(const std::shared_ptr<OHOS::Media::AVBuffer> & inputBuffer)966  int32_t AudioServerSinkPlugin::WriteAudioVivid(const std::shared_ptr<OHOS::Media::AVBuffer> &inputBuffer)
967  {
968      MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::WriteAudioVivid");
969      auto mem = inputBuffer->memory_;
970      auto pcmBuffer = mem->GetAddr();
971      auto pcmBufferSize = mem->GetSize();
972      auto meta = inputBuffer->meta_;
973      std::vector<uint8_t> metaData;
974      meta->GetData(Tag::OH_MD_KEY_AUDIO_VIVID_METADATA, metaData);
975      FALSE_RETURN_V(audioRenderer_ != nullptr, -1);
976      return audioRenderer_->Write(pcmBuffer, pcmBufferSize, metaData.data(), metaData.size());
977  }
978  
Flush()979  Status AudioServerSinkPlugin::Flush()
980  {
981      MEDIA_LOG_I_T("Flush entered.");
982      DrainCacheData(false);
983      if (audioRenderer_ == nullptr) {
984          return Status::ERROR_WRONG_STATE;
985      }
986      if (audioRenderer_->Flush()) {
987          MEDIA_LOG_D_T("flush renderer success");
988          return Status::OK;
989      }
990      MEDIA_LOG_E_T("flush renderer fail");
991      return Status::ERROR_UNKNOWN;
992  }
993  
Drain()994  Status AudioServerSinkPlugin::Drain()
995  {
996      MEDIA_LOG_I_T("Drain entered.");
997      if (audioRenderer_ == nullptr) {
998          DrainCacheData(false);
999          return Status::ERROR_WRONG_STATE;
1000      }
1001      DrainCacheData(true); // try to drain
1002      cachedBuffers_.clear(); // force clear cached data, no matter drain success or not
1003      if (!audioRenderer_->Drain()) {
1004          uint64_t latency = 0;
1005          audioRenderer_->GetLatency(latency);
1006          latency /= 1000;    // 1000 cast into ms
1007          if (latency > 50) { // 50 latency too large
1008              MEDIA_LOG_W("Drain failed and latency is too large, will sleep " PUBLIC_LOG_U64 " ms, aka. latency.",
1009                          latency);
1010              OHOS::Media::SleepInJob(latency);
1011          }
1012      }
1013      MEDIA_LOG_I_T("drain renderer success");
1014      return Status::OK;
1015  }
1016  
GetPlayedOutDurationUs(int64_t nowUs)1017  int64_t AudioServerSinkPlugin::GetPlayedOutDurationUs(int64_t nowUs)
1018  {
1019      FALSE_RETURN_V(audioRenderer_ != nullptr && rendererParams_.sampleRate != 0, -1);
1020      uint32_t numFramesPlayed = 0;
1021      AudioStandard::Timestamp ts;
1022      bool res = audioRenderer_->GetAudioTime(ts, AudioStandard::Timestamp::Timestampbase::MONOTONIC);
1023      if (res) {
1024          numFramesPlayed = ts.framePosition;
1025      }
1026      return numFramesPlayed;
1027  }
1028  
GetFramePosition(int32_t & framePosition)1029  Status AudioServerSinkPlugin::GetFramePosition(int32_t &framePosition)
1030  {
1031      AudioStandard::Timestamp ts;
1032      if (audioRenderer_ == nullptr) {
1033          return Status::ERROR_WRONG_STATE;
1034      }
1035      bool res = audioRenderer_->GetAudioTime(ts, AudioStandard::Timestamp::Timestampbase::MONOTONIC);
1036      if (!res) {
1037          return Status::ERROR_UNKNOWN;
1038      }
1039      framePosition = static_cast<int32_t>(ts.framePosition);
1040      return Status::OK;
1041  }
1042  
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)1043  void AudioServerSinkPlugin::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver>& receiver)
1044  {
1045      FALSE_RETURN(receiver != nullptr);
1046      playerEventReceiver_ = receiver;
1047  }
1048  
SetAudioDumpBySysParam()1049  void AudioServerSinkPlugin::SetAudioDumpBySysParam()
1050  {
1051      std::string dumpAllEnable;
1052      enableEntireDump_ = false;
1053      int32_t dumpAllRes = OHOS::system::GetStringParameter("sys.media.sink.entiredump.enable", dumpAllEnable, "");
1054      if (dumpAllRes == 0 && !dumpAllEnable.empty() && dumpAllEnable == "true") {
1055          enableEntireDump_ = true;
1056      }
1057      std::string dumpSliceEnable;
1058      enableDumpSlice_ = false;
1059      int32_t sliceDumpRes = OHOS::system::GetStringParameter("sys.media.sink.slicedump.enable", dumpSliceEnable, "");
1060      if (sliceDumpRes == 0 && !dumpSliceEnable.empty() && dumpSliceEnable == "true") {
1061          enableDumpSlice_ = true;
1062      }
1063      MEDIA_LOG_D_T("sys.media.sink.entiredump.enable: " PUBLIC_LOG_S ", sys.media.sink.slicedump.enable: "
1064          PUBLIC_LOG_S, dumpAllEnable.c_str(), dumpSliceEnable.c_str());
1065  }
1066  
DumpEntireAudioBuffer(uint8_t * buffer,const size_t & bytesSingle)1067  void AudioServerSinkPlugin::DumpEntireAudioBuffer(uint8_t* buffer, const size_t& bytesSingle)
1068  {
1069      if (!enableEntireDump_) {
1070          return;
1071      }
1072  
1073      if (entireDumpFile_ == nullptr) {
1074          std::string path = "data/media/audio-sink-entire.pcm";
1075          entireDumpFile_ = fopen(path.c_str(), "wb+");
1076      }
1077      if (entireDumpFile_ == nullptr) {
1078          return;
1079      }
1080      (void)fwrite(buffer, bytesSingle, 1, entireDumpFile_);
1081      (void)fflush(entireDumpFile_);
1082  }
1083  
DumpSliceAudioBuffer(uint8_t * buffer,const size_t & bytesSingle)1084  void AudioServerSinkPlugin::DumpSliceAudioBuffer(uint8_t* buffer, const size_t& bytesSingle)
1085  {
1086      if (!enableDumpSlice_) {
1087          return;
1088      }
1089  
1090      if (curCount_ != sliceCount_) {
1091          curCount_ = sliceCount_;
1092          if (sliceDumpFile_ != nullptr) {
1093              (void)fclose(sliceDumpFile_);
1094          }
1095          std::string path = "data/media/audio-sink-slice-" + std::to_string(sliceCount_) + ".pcm";
1096          sliceDumpFile_ = fopen(path.c_str(), "wb+");
1097      }
1098      if (sliceDumpFile_  == nullptr) {
1099          return;
1100      }
1101      (void)fwrite(buffer, bytesSingle, 1, sliceDumpFile_);
1102      (void)fflush(sliceDumpFile_);
1103  }
1104  
SetMuted(bool isMuted)1105  Status AudioServerSinkPlugin::SetMuted(bool isMuted)
1106  {
1107      FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
1108      MEDIA_LOG_D("SetMuted in");
1109      audioRenderer_->SetSilentModeAndMixWithOthers(isMuted);
1110      MEDIA_LOG_I("SetMuted out");
1111      return Status::OK;
1112  }
1113  
GetWriteDurationMs()1114  int64_t AudioServerSinkPlugin::GetWriteDurationMs()
1115  {
1116      int64_t writeDuration = writeDuration_;
1117      writeDuration_ = 0;
1118      return writeDuration;
1119  }
1120  } // namespace Plugin
1121  } // namespace Media
1122  } // namespace OHOS
1123