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