1 /*
2  * Copyright (c) 2022-2022 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 HST_LOG_TAG "AudioServerSinkPlugin"
17 
18 #include "audio_server_sink_plugin.h"
19 #include <functional>
20 #include "audio_errors.h"
21 #include "foundation/cpp_ext/algorithm_ext.h"
22 #include "foundation/log.h"
23 #include "foundation/osal/thread/scoped_lock.h"
24 #include "foundation/osal/utils/util.h"
25 #include "foundation/utils/constants.h"
26 #include "plugin/common/plugin_attr_desc.h"
27 #include "plugin/common/plugin_time.h"
28 
29 namespace {
30 using namespace OHOS::Media::Plugin;
31 constexpr uint32_t DEFAULT_OUTPUT_CHANNELS = 2;
32 constexpr AudioChannelLayout DEFAULT_OUTPUT_CHANNEL_LAYOUT = AudioChannelLayout::STEREO;
33 const std::pair<OHOS::AudioStandard::AudioSamplingRate, uint32_t> g_auSampleRateMap[] = {
34     {OHOS::AudioStandard::SAMPLE_RATE_8000, 8000},
35     {OHOS::AudioStandard::SAMPLE_RATE_11025, 11025},
36     {OHOS::AudioStandard::SAMPLE_RATE_12000, 12000},
37     {OHOS::AudioStandard::SAMPLE_RATE_16000, 16000},
38     {OHOS::AudioStandard::SAMPLE_RATE_22050, 22050},
39     {OHOS::AudioStandard::SAMPLE_RATE_24000, 24000},
40     {OHOS::AudioStandard::SAMPLE_RATE_32000, 32000},
41     {OHOS::AudioStandard::SAMPLE_RATE_44100, 44100},
42     {OHOS::AudioStandard::SAMPLE_RATE_48000, 48000},
43     {OHOS::AudioStandard::SAMPLE_RATE_64000, 64000},
44     {OHOS::AudioStandard::SAMPLE_RATE_96000, 96000},
45 };
46 
47 const std::pair<AudioInterruptMode, OHOS::AudioStandard::InterruptMode> g_auInterruptMap[] = {
48     {AudioInterruptMode::SHARE_MODE, OHOS::AudioStandard::InterruptMode::SHARE_MODE},
49     {AudioInterruptMode::INDEPENDENT_MODE, OHOS::AudioStandard::InterruptMode::INDEPENDENT_MODE},
50 };
51 
52 const std::vector<std::tuple<AudioSampleFormat, OHOS::AudioStandard::AudioSampleFormat, AVSampleFormat>> g_aduFmtMap = {
53     {AudioSampleFormat::S8, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
54     {AudioSampleFormat::U8, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_U8, AV_SAMPLE_FMT_U8},
55     {AudioSampleFormat::S8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
56     {AudioSampleFormat::U8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_U8P},
57     {AudioSampleFormat::S16, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE, AV_SAMPLE_FMT_S16},
58     {AudioSampleFormat::U16, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
59     {AudioSampleFormat::S16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S16P},
60     {AudioSampleFormat::U16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
61     {AudioSampleFormat::S24, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S24LE, AV_SAMPLE_FMT_NONE},
62     {AudioSampleFormat::U24, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
63     {AudioSampleFormat::S24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
64     {AudioSampleFormat::U24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
65     {AudioSampleFormat::S32, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S32LE, AV_SAMPLE_FMT_S32},
66     {AudioSampleFormat::U32, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
67     {AudioSampleFormat::S32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S32P},
68     {AudioSampleFormat::U32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
69     {AudioSampleFormat::F32, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_FLT},
70     {AudioSampleFormat::F32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_FLTP},
71     {AudioSampleFormat::F64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBL},
72     {AudioSampleFormat::F64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBLP},
73     {AudioSampleFormat::S64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64},
74     {AudioSampleFormat::U64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
75     {AudioSampleFormat::S64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64P},
76     {AudioSampleFormat::U64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
77 };
78 
79 const std::pair<OHOS::AudioStandard::AudioChannel, uint32_t> g_auChannelsMap[] = {
80     {OHOS::AudioStandard::MONO, 1},
81     {OHOS::AudioStandard::STEREO, 2},
82 };
83 
SampleRateEnum2Num(OHOS::AudioStandard::AudioSamplingRate enumVal,uint32_t & numVal)84 bool SampleRateEnum2Num (OHOS::AudioStandard::AudioSamplingRate enumVal, uint32_t& numVal)
85 {
86     for (const auto& item : g_auSampleRateMap) {
87         if (item.first == enumVal) {
88             numVal = item.second;
89             return true;
90         }
91     }
92     numVal = 0;
93     return false;
94 }
95 
SampleRateNum2Enum(uint32_t numVal,OHOS::AudioStandard::AudioSamplingRate & enumVal)96 bool SampleRateNum2Enum (uint32_t numVal, OHOS::AudioStandard::AudioSamplingRate& enumVal)
97 {
98     for (const auto& item : g_auSampleRateMap) {
99         if (item.second == numVal) {
100             enumVal = item.first;
101             return true;
102         }
103     }
104     return false;
105 }
106 
ChannelNumNum2Enum(uint32_t numVal,OHOS::AudioStandard::AudioChannel & enumVal)107 bool ChannelNumNum2Enum(uint32_t numVal, OHOS::AudioStandard::AudioChannel& enumVal)
108 {
109     for (const auto& item : g_auChannelsMap) {
110         if (item.second == numVal) {
111             enumVal = item.first;
112             return true;
113         }
114     }
115     return false;
116 }
117 
AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,OHOS::AudioStandard::InterruptMode & interruptMode)118 void AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,
119                                       OHOS::AudioStandard::InterruptMode& interruptMode)
120 {
121     for (const auto& item : g_auInterruptMap) {
122         if (item.first == audioInterruptMode) {
123             interruptMode = item.second;
124         }
125     }
126 }
127 
AudioServerSinkPluginCreater(const std::string & name)128 std::shared_ptr<AudioSinkPlugin> AudioServerSinkPluginCreater(const std::string& name)
129 {
130     return std::make_shared<OHOS::Media::Plugin::AuSrSinkPlugin::AudioServerSinkPlugin>(name);
131 }
132 
UpdateSupportedSampleRate(Capability & inCaps)133 void UpdateSupportedSampleRate(Capability& inCaps)
134 {
135     auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
136     if (!supportedSampleRateList.empty()) {
137         DiscreteCapability<uint32_t> values;
138         for (const auto& rate : supportedSampleRateList) {
139             uint32_t sampleRate = 0;
140             if (SampleRateEnum2Num(rate, sampleRate)) {
141                 values.push_back(sampleRate);
142             }
143         }
144         if (!values.empty()) {
145             inCaps.AppendDiscreteKeys<uint32_t>(Capability::Key::AUDIO_SAMPLE_RATE, values);
146         }
147     }
148 }
149 
UpdateSupportedSampleFormat(Capability & inCaps)150 void UpdateSupportedSampleFormat(Capability& inCaps)
151 {
152     DiscreteCapability<AudioSampleFormat> values(g_aduFmtMap.size());
153     for (const auto& item : g_aduFmtMap) {
154         if (std::get<1>(item) != OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH ||
155             std::get<2>(item) != AV_SAMPLE_FMT_NONE) {
156             values.emplace_back(std::get<0>(item));
157         }
158     }
159     inCaps.AppendDiscreteKeys(Capability::Key::AUDIO_SAMPLE_FORMAT, values);
160 }
161 
AudioServerSinkRegister(const std::shared_ptr<Register> & reg)162 Status AudioServerSinkRegister(const std::shared_ptr<Register>& reg)
163 {
164     AudioSinkPluginDef definition;
165     definition.name = "AudioServerSink";
166     definition.description = "Audio sink for audio server of media standard";
167     definition.rank = 100; // 100: max rank
168     definition.creator = AudioServerSinkPluginCreater;
169     Capability inCaps(OHOS::Media::MEDIA_MIME_AUDIO_RAW);
170     UpdateSupportedSampleRate(inCaps);
171     UpdateSupportedSampleFormat(inCaps);
172     definition.inCaps.push_back(inCaps);
173     return reg->AddPlugin(definition);
174 }
175 
__anon58c837e40202null176 PLUGIN_DEFINITION(AudioServerSink, LicenseType::APACHE_V2, AudioServerSinkRegister, [] {});
177 
ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams & param)178 inline void ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams& param)
179 {
180     using namespace OHOS::AudioStandard;
181     param.sampleFormat = INVALID_WIDTH;
182     param.sampleRate = SAMPLE_RATE_8000;
183     param.channelCount = MONO;
184     param.encodingType = ENCODING_INVALID;
185 }
186 } // namespace
187 
188 namespace OHOS {
189 namespace Media {
190 namespace Plugin {
191 namespace AuSrSinkPlugin {
192 using namespace OHOS::Media::Plugin;
193 
194 
AudioRendererCallbackImpl(Callback * cb,bool & isPaused)195 AudioServerSinkPlugin::AudioRendererCallbackImpl::AudioRendererCallbackImpl(Callback* cb, bool& isPaused)
196     : callback_(cb), isPaused_(isPaused)
197 {
198 }
199 
OnInterrupt(const OHOS::AudioStandard::InterruptEvent & interruptEvent)200 void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnInterrupt(
201     const OHOS::AudioStandard::InterruptEvent& interruptEvent)
202 {
203     if (interruptEvent.forceType == OHOS::AudioStandard::INTERRUPT_FORCE) {
204         switch (interruptEvent.hintType) {
205             case OHOS::AudioStandard::INTERRUPT_HINT_PAUSE:
206                 isPaused_ = true;
207                 break;
208             default:
209                 isPaused_ = false;
210                 break;
211         }
212     }
213     callback_->OnEvent(PluginEvent{PluginEventType::AUDIO_INTERRUPT, interruptEvent, "Audio interrupt event"});
214 }
215 
OnStateChange(const OHOS::AudioStandard::RendererState state,const OHOS::AudioStandard::StateChangeCmdType cmdType)216 void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnStateChange(const OHOS::AudioStandard::RendererState state,
217     const OHOS::AudioStandard::StateChangeCmdType cmdType)
218 {
219     MEDIA_LOG_D("RenderState is " PUBLIC_LOG_U32, static_cast<uint32_t>(state));
220     if (cmdType == AudioStandard::StateChangeCmdType::CMD_FROM_SYSTEM) {
221         callback_->OnEvent(PluginEvent{PluginEventType::AUDIO_STATE_CHANGE, state});
222     }
223 }
224 
AudioServerSinkPlugin(std::string name)225 AudioServerSinkPlugin::AudioServerSinkPlugin(std::string name)
226     : Plugin::AudioSinkPlugin(std::move(name)), audioRenderer_(nullptr)
227 {
228     SetUpParamsSetterMap();
229 }
230 
~AudioServerSinkPlugin()231 AudioServerSinkPlugin::~AudioServerSinkPlugin()
232 {
233     MEDIA_LOG_I("~AudioServerSinkPlugin() entered.");
234     ReleaseRender();
235 }
236 
Init()237 Status AudioServerSinkPlugin::Init()
238 {
239     MEDIA_LOG_I("Init entered.");
240     OSAL::ScopedLock lock(renderMutex_);
241     if (audioRenderer_ == nullptr) {
242         AudioStandard::AppInfo appInfo;
243         appInfo.appPid = appPid_;
244         appInfo.appUid = appUid_;
245         MEDIA_LOG_I("Create audio renderer for apppid_ " PUBLIC_LOG_D32 " appuid_ " PUBLIC_LOG_D32 " contentType "
246             PUBLIC_LOG_D32 " streamUsage " PUBLIC_LOG_D32 " rendererFlags " PUBLIC_LOG_D32 " audioInterruptMode_ "
247             PUBLIC_LOG_U32, appPid_, appUid_, audioRenderInfo_.contentType, audioRenderInfo_.streamUsage,
248             audioRenderInfo_.rendererFlags, static_cast<uint32_t>(audioInterruptMode_));
249         rendererOptions_.rendererInfo.contentType = static_cast<AudioStandard::ContentType>(
250             audioRenderInfo_.contentType);
251         rendererOptions_.rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(
252             audioRenderInfo_.streamUsage);
253         rendererOptions_.rendererInfo.rendererFlags = audioRenderInfo_.rendererFlags;
254         rendererOptions_.streamInfo.samplingRate = AudioStandard::SAMPLE_RATE_8000;
255         rendererOptions_.streamInfo.encoding = AudioStandard::ENCODING_PCM;
256         rendererOptions_.streamInfo.format = AudioStandard::SAMPLE_S16LE;
257         rendererOptions_.streamInfo.channels = AudioStandard::MONO;
258         audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions_, appInfo);
259         if (audioRenderer_ == nullptr) {
260             MEDIA_LOG_E("Create audioRenderer_ fail");
261             return Status::ERROR_UNKNOWN;
262         }
263         audioRenderer_->SetInterruptMode(audioInterruptMode_);
264         if (audioRendererCallback_ == nullptr) {
265             audioRendererCallback_ = std::make_shared<AudioRendererCallbackImpl>(callback_, isForcePaused_);
266             audioRenderer_->SetRendererCallback(audioRendererCallback_);
267         }
268     }
269     return Status::OK;
270 }
271 
ReleaseRender()272 void AudioServerSinkPlugin::ReleaseRender()
273 {
274     OSAL::ScopedLock lock(renderMutex_);
275     if (audioRenderer_ != nullptr && audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_RELEASED) {
276         if (!audioRenderer_->Release()) {
277             MEDIA_LOG_W("release audio render failed");
278             return;
279         }
280     }
281     audioRenderer_.reset();
282 }
283 
Deinit()284 Status AudioServerSinkPlugin::Deinit()
285 {
286     MEDIA_LOG_I("Deinit entered.");
287     ReleaseRender();
288     return Status::OK;
289 }
290 
Prepare()291 Status AudioServerSinkPlugin::Prepare()
292 {
293     MEDIA_LOG_I("Prepare entered.");
294     FALSE_RETURN_V_MSG_E(fmtSupported_, Status::ERROR_INVALID_PARAMETER, "sample fmt is not supported");
295     if (bitsPerSample_ == 8 || bitsPerSample_ == 24) { // 8 24
296         needReformat_ = true;
297         rendererParams_.sampleFormat = reStdDestFmt_;
298     }
299     auto types = AudioStandard::AudioRenderer::GetSupportedEncodingTypes();
300     if (!CppExt::AnyOf(types.begin(), types.end(), [](AudioStandard::AudioEncodingType tmp) -> bool {
301         return tmp == AudioStandard::ENCODING_PCM;
302     })) {
303         MEDIA_LOG_E("audio renderer do not support pcm encoding");
304         return Status::ERROR_INVALID_PARAMETER;
305     }
306     rendererParams_.encodingType = AudioStandard::ENCODING_PCM;
307     MEDIA_LOG_I("set param with fmt " PUBLIC_LOG_D32 " sampleRate " PUBLIC_LOG_D32 " channel " PUBLIC_LOG_D32
308         " encode type " PUBLIC_LOG_D32,
309         rendererParams_.sampleFormat, rendererParams_.sampleRate, rendererParams_.channelCount,
310         rendererParams_.encodingType);
311     {
312         OSAL::ScopedLock lock(renderMutex_);
313         auto ret = audioRenderer_->SetParams(rendererParams_);
314         if (ret != AudioStandard::SUCCESS) {
315             MEDIA_LOG_E("audio renderer SetParams() fail with " PUBLIC_LOG_D32, ret);
316             return Status::ERROR_UNKNOWN;
317         }
318     }
319     if (needReformat_) {
320         resample_ = std::make_shared<Ffmpeg::Resample>();
321         Ffmpeg::ResamplePara resamplePara {
322             channels_,
323             sampleRate_,
324             bitsPerSample_,
325             static_cast<int64_t>(channelLayout_),
326             reSrcFfFmt_,
327             samplesPerFrame_,
328             reFfDestFmt_,
329         };
330         FALSE_RETURN_V_MSG(resample_->Init(resamplePara) == Status::OK, Status::ERROR_UNKNOWN, "Resample init error");
331     }
332     return Status::OK;
333 }
334 
StopRender()335 bool AudioServerSinkPlugin::StopRender()
336 {
337     OSAL::ScopedLock lock(renderMutex_);
338     if (audioRenderer_) {
339         if (audioRenderer_->GetStatus() == AudioStandard::RendererState::RENDERER_STOPPED) {
340             MEDIA_LOG_I("AudioRenderer is already in stopped state.");
341             return true;
342         }
343         return audioRenderer_->Stop();
344     }
345     return true;
346 }
347 
Reset()348 Status AudioServerSinkPlugin::Reset()
349 {
350     MEDIA_LOG_I("Reset entered.");
351     if (!StopRender()) {
352         MEDIA_LOG_E("stop render error");
353         return Status::ERROR_UNKNOWN;
354     }
355     ResetAudioRendererParams(rendererParams_);
356     fmtSupported_ = false;
357     reSrcFfFmt_ = AV_SAMPLE_FMT_NONE;
358     channels_ = 0;
359     bitRate_ = 0;
360     sampleRate_ = 0;
361     samplesPerFrame_ = 0;
362     needReformat_ = false;
363     if (resample_) {
364         resample_.reset();
365     }
366     return Status::OK;
367 }
368 
Start()369 Status AudioServerSinkPlugin::Start()
370 {
371     MEDIA_LOG_I("Start entered.");
372     bool ret = false;
373     OSAL::ScopedLock lock(renderMutex_);
374     {
375         if (audioRenderer_ == nullptr) {
376             return Status::ERROR_WRONG_STATE;
377         }
378         ret = audioRenderer_->Start();
379     }
380     if (ret) {
381         MEDIA_LOG_I("audioRenderer_ Start() success");
382         return Status::OK;
383     } else {
384         MEDIA_LOG_E("audioRenderer_ Start() fail");
385     }
386     return Status::ERROR_UNKNOWN;
387 }
388 
Stop()389 Status AudioServerSinkPlugin::Stop()
390 {
391     MEDIA_LOG_I("Stop entered.");
392     if (StopRender()) {
393         MEDIA_LOG_I("stop render success");
394         return Status::OK;
395     } else {
396         MEDIA_LOG_E("stop render failed");
397     }
398     return Status::ERROR_UNKNOWN;
399 }
400 
GetParameter(Tag tag,ValueType & para)401 Status AudioServerSinkPlugin::GetParameter(Tag tag, ValueType& para)
402 {
403     MEDIA_LOG_I("GetParameter entered, key: " PUBLIC_LOG_S, Tag2String(tag));
404     AudioStandard::AudioRendererParams params;
405     OSAL::ScopedLock lock(renderMutex_);
406     switch (tag) {
407         case Tag::AUDIO_SAMPLE_RATE:
408             if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
409                 if (params.sampleRate != rendererParams_.sampleRate) {
410                     MEDIA_LOG_W("samplingRate has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
411                                 rendererParams_.sampleRate, params.sampleRate);
412                 }
413                 para = params.sampleRate;
414             }
415             break;
416         case Tag::AUDIO_OUTPUT_CHANNELS:
417             para = DEFAULT_OUTPUT_CHANNELS; // get the real output channels from audio server here
418             MEDIA_LOG_I("Get outputChannels: " PUBLIC_LOG_U32, DEFAULT_OUTPUT_CHANNELS);
419             break;
420         case Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT:
421             para = DEFAULT_OUTPUT_CHANNEL_LAYOUT; // get the real output channel layout from audio server here
422             MEDIA_LOG_I("Get outputChannelLayout: " PUBLIC_LOG_U64, DEFAULT_OUTPUT_CHANNEL_LAYOUT);
423             break;
424         case Tag::MEDIA_BITRATE:
425             para = bitRate_;
426             break;
427         case Tag::AUDIO_SAMPLE_FORMAT:
428             if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
429                 if (params.sampleFormat != rendererParams_.sampleFormat) {
430                     MEDIA_LOG_W("sampleFormat has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
431                                 rendererParams_.sampleFormat, params.sampleFormat);
432                 }
433                 para = params.sampleFormat;
434             }
435             break;
436         default:
437             MEDIA_LOG_I("Unknown key");
438             break;
439     }
440     return Status::OK;
441 }
442 
AssignSampleRateIfSupported(uint32_t sampleRate)443 bool AudioServerSinkPlugin::AssignSampleRateIfSupported(uint32_t sampleRate)
444 {
445     sampleRate_ = sampleRate;
446     AudioStandard::AudioSamplingRate aRate = AudioStandard::SAMPLE_RATE_8000;
447     if (!SampleRateNum2Enum(sampleRate, aRate)) {
448         MEDIA_LOG_E("sample rate " PUBLIC_LOG_U32 "not supported", sampleRate);
449         return false;
450     }
451     auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
452     if (supportedSampleRateList.empty()) {
453         MEDIA_LOG_E("GetSupportedSamplingRates() fail");
454         return false;
455     }
456     for (const auto& rate : supportedSampleRateList) {
457         if (rate == aRate) {
458             rendererParams_.sampleRate = rate;
459             MEDIA_LOG_D("sampleRate: " PUBLIC_LOG_U32, rendererParams_.sampleRate);
460             return true;
461         }
462     }
463     return false;
464 }
465 
AssignChannelNumIfSupported(uint32_t channelNum)466 bool AudioServerSinkPlugin::AssignChannelNumIfSupported(uint32_t channelNum)
467 {
468     AudioStandard::AudioChannel aChannel = AudioStandard::MONO;
469     if (!ChannelNumNum2Enum(channelNum, aChannel)) {
470         MEDIA_LOG_E("channel num " PUBLIC_LOG_U32 "not supported", channelNum);
471         return false;
472     }
473     auto supportedChannelsList = OHOS::AudioStandard::AudioRenderer::GetSupportedChannels();
474     if (supportedChannelsList.empty()) {
475         MEDIA_LOG_E("GetSupportedChannels() fail");
476         return false;
477     }
478     for (const auto& channel : supportedChannelsList) {
479         if (channel == aChannel) {
480             rendererParams_.channelCount = channel;
481             MEDIA_LOG_D("channelCount: " PUBLIC_LOG_U32, rendererParams_.channelCount);
482             return true;
483         }
484     }
485     return false;
486 }
487 
AssignSampleFmtIfSupported(Plugin::AudioSampleFormat sampleFormat)488 bool AudioServerSinkPlugin::AssignSampleFmtIfSupported(Plugin::AudioSampleFormat sampleFormat)
489 {
490     const auto& item = std::find_if(g_aduFmtMap.begin(), g_aduFmtMap.end(), [&sampleFormat] (const auto& tmp) -> bool {
491         return std::get<0>(tmp) == sampleFormat;
492     });
493     auto stdFmt = std::get<1>(*item);
494     if (stdFmt == OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH) {
495         if (std::get<2>(*item) == AV_SAMPLE_FMT_NONE) { // 2
496             fmtSupported_ = false;
497         } else {
498             fmtSupported_ = true;
499             needReformat_ = true;
500             reSrcFfFmt_ = std::get<2>(*item); // 2
501             rendererParams_.sampleFormat = reStdDestFmt_;
502         }
503     } else {
504         auto supportedFmts = OHOS::AudioStandard::AudioRenderer::GetSupportedFormats();
505         if (CppExt::AnyOf(supportedFmts.begin(), supportedFmts.end(), [&stdFmt](const auto& tmp) -> bool {
506             return tmp == stdFmt;
507         })) {
508             fmtSupported_ = true;
509             needReformat_ = false;
510             rendererParams_.sampleFormat = stdFmt;
511         } else {
512             fmtSupported_ = false;
513             needReformat_ = false;
514         }
515     }
516     return fmtSupported_;
517 }
518 
SetInterruptMode(AudioStandard::InterruptMode interruptMode)519 void AudioServerSinkPlugin::SetInterruptMode(AudioStandard::InterruptMode interruptMode)
520 {
521     OSAL::ScopedLock lock(renderMutex_);
522     if (audioRenderer_) {
523         audioRenderer_->SetInterruptMode(interruptMode);
524     }
525 }
526 
SetUpParamsSetterMap()527 void AudioServerSinkPlugin::SetUpParamsSetterMap()
528 {
529     SetUpSampleRateSetter();
530     SetUpAudioOutputChannelsSetter();
531     SetUpMediaBitRateSetter();
532     SetUpAudioSampleFormatSetter();
533     SetUpAudioOutputChannelLayoutSetter();
534     SetUpAudioSamplePerFrameSetter();
535     SetUpBitsPerCodedSampleSetter();
536     SetUpMediaSeekableSetter();
537     SetUpAppPidSetter();
538     SetUpAppUidSetter();
539     SetUpAudioRenderInfoSetter();
540     SetUpAudioInterruptModeSetter();
541 }
542 
SetUpSampleRateSetter()543 void AudioServerSinkPlugin::SetUpSampleRateSetter()
544 {
545     paramsSetterMap_[Tag::AUDIO_SAMPLE_RATE] = [this](const ValueType& para) {
546         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<uint32_t>(para), Status::ERROR_MISMATCHED_TYPE,
547                              "sample rate type should be uint32_t");
548         FALSE_RETURN_V_MSG_E(AssignSampleRateIfSupported(Plugin::AnyCast<uint32_t>(para)),
549                              Status::ERROR_INVALID_PARAMETER, "sampleRate isn't supported");
550         return Status::OK;
551     };
552 }
553 
SetUpAudioOutputChannelsSetter()554 void AudioServerSinkPlugin::SetUpAudioOutputChannelsSetter()
555 {
556     paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNELS] = [this](const ValueType &para) {
557         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<uint32_t>(para), Status::ERROR_MISMATCHED_TYPE,
558                              "channels type should be uint32_t");
559         channels_ = Plugin::AnyCast<uint32_t>(para);
560         MEDIA_LOG_I("Set outputChannels: " PUBLIC_LOG_U32, channels_);
561         FALSE_RETURN_V_MSG_E(AssignChannelNumIfSupported(channels_), Status::ERROR_INVALID_PARAMETER,
562                              "channel isn't supported");
563         return Status::OK;
564     };
565 }
566 
SetUpMediaBitRateSetter()567 void AudioServerSinkPlugin::SetUpMediaBitRateSetter()
568 {
569     paramsSetterMap_[Tag::MEDIA_BITRATE] = [this](const ValueType &para) {
570         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int64_t>(para), Status::ERROR_MISMATCHED_TYPE,
571             "bit rate type should be int64_t");
572         bitRate_ = Plugin::AnyCast<int64_t>(para);
573         return Status::OK;
574     };
575 }
SetUpAudioSampleFormatSetter()576 void AudioServerSinkPlugin::SetUpAudioSampleFormatSetter()
577 {
578     paramsSetterMap_[Tag::AUDIO_SAMPLE_FORMAT] = [this](const ValueType &para) {
579         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioSampleFormat>(para), Status::ERROR_MISMATCHED_TYPE,
580             "AudioSampleFormat type should be AudioSampleFormat");
581         FALSE_RETURN_V_MSG_E(AssignSampleFmtIfSupported(Plugin::AnyCast<AudioSampleFormat>(para)),
582             Status::ERROR_INVALID_PARAMETER, "sampleFmt isn't supported by audio renderer or resample lib");
583         return Status::OK;
584     };
585 }
SetUpAudioOutputChannelLayoutSetter()586 void AudioServerSinkPlugin::SetUpAudioOutputChannelLayoutSetter()
587 {
588     paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT] = [this](const ValueType &para) {
589         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioChannelLayout>(para), Status::ERROR_MISMATCHED_TYPE,
590             "channel layout type should be AudioChannelLayout");
591         channelLayout_ = Plugin::AnyCast<AudioChannelLayout>(para);
592         MEDIA_LOG_I("Set outputChannelLayout: " PUBLIC_LOG_U64, channelLayout_);
593         return Status::OK;
594     };
595 }
SetUpAudioSamplePerFrameSetter()596 void AudioServerSinkPlugin::SetUpAudioSamplePerFrameSetter()
597 {
598     paramsSetterMap_[Tag::AUDIO_SAMPLE_PER_FRAME] = [this](const ValueType &para) {
599         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<uint32_t>(para), Status::ERROR_MISMATCHED_TYPE,
600             "SAMPLE_PER_FRAME type should be uint32_t");
601         samplesPerFrame_ = Plugin::AnyCast<uint32_t>(para);
602         return Status::OK;
603     };
604 }
SetUpBitsPerCodedSampleSetter()605 void AudioServerSinkPlugin::SetUpBitsPerCodedSampleSetter()
606 {
607     paramsSetterMap_[Tag::BITS_PER_CODED_SAMPLE] = [this](const ValueType &para) {
608         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<uint32_t>(para), Status::ERROR_MISMATCHED_TYPE,
609                              "BITS_PER_CODED_SAMPLE type should be uint32_t");
610         bitsPerSample_ = Plugin::AnyCast<uint32_t>(para);
611         return Status::OK;
612     };
613 }
SetUpMediaSeekableSetter()614 void AudioServerSinkPlugin::SetUpMediaSeekableSetter()
615 {
616     paramsSetterMap_[Tag::MEDIA_SEEKABLE] = [this](const ValueType &para) {
617         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<Seekable>(para), Status::ERROR_MISMATCHED_TYPE,
618                              "MEDIA_SEEKABLE type should be Seekable");
619         seekable_ = Plugin::AnyCast<Plugin::Seekable>(para);
620         return Status::OK;
621     };
622 }
SetUpAppPidSetter()623 void AudioServerSinkPlugin::SetUpAppPidSetter()
624 {
625     paramsSetterMap_[Tag::APP_PID] = [this](const ValueType &para) {
626         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
627             "APP_PID type should be int32_t");
628         appPid_ = Plugin::AnyCast<int32_t>(para);
629         return Status::OK;
630     };
631 }
SetUpAppUidSetter()632 void AudioServerSinkPlugin::SetUpAppUidSetter()
633 {
634     paramsSetterMap_[Tag::APP_UID] = [this](const ValueType &para) {
635         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
636             "APP_UID type should be int32_t");
637         appUid_ = Plugin::AnyCast<int32_t>(para);
638         return Status::OK;
639     };
640 }
SetUpAudioRenderInfoSetter()641 void AudioServerSinkPlugin::SetUpAudioRenderInfoSetter()
642 {
643     paramsSetterMap_[Tag::AUDIO_RENDER_INFO] = [this](const ValueType &para) {
644         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioRenderInfo>(para), Status::ERROR_MISMATCHED_TYPE,
645                              "AUDIO_RENDER_INFO type should be AudioRenderInfo");
646         audioRenderInfo_ = Plugin::AnyCast<AudioRenderInfo>(para);
647         return Status::OK;
648     };
649 }
SetUpAudioInterruptModeSetter()650 void AudioServerSinkPlugin::SetUpAudioInterruptModeSetter()
651 {
652     paramsSetterMap_[Tag::AUDIO_INTERRUPT_MODE] = [this](const ValueType &para) {
653         FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioInterruptMode>(para), Status::ERROR_MISMATCHED_TYPE,
654                              "AUDIO_INTERRUPT_MODE type should be AudioInterruptMode");
655         AudioInterruptMode2InterruptMode(Plugin::AnyCast<AudioInterruptMode>(para), audioInterruptMode_);
656         SetInterruptMode(audioInterruptMode_);
657         return Status::OK;
658     };
659 }
660 
SetParameter(Tag tag,const ValueType & para)661 Status AudioServerSinkPlugin::SetParameter(Tag tag, const ValueType& para)
662 {
663     MEDIA_LOG_I("SetParameter entered, key: " PUBLIC_LOG_S, Tag2String(tag));
664     auto iter = paramsSetterMap_.find(tag);
665     if (iter == paramsSetterMap_.end()) {
666         MEDIA_LOG_I("Unknown key");
667         return Status::OK;
668     }
669 
670     std::function<Status(const ValueType& para)> paramSetter = iter->second;
671     return paramSetter(para);
672 }
673 
GetVolume(float & volume)674 Status AudioServerSinkPlugin::GetVolume(float& volume)
675 {
676     MEDIA_LOG_I("GetVolume entered.");
677     OSAL::ScopedLock lock(renderMutex_);
678     if (audioRenderer_ != nullptr) {
679         volume = audioRenderer_->GetVolume();
680         return Status::OK;
681     }
682     return Status::ERROR_WRONG_STATE;
683 }
684 
SetVolume(float volume)685 Status AudioServerSinkPlugin::SetVolume(float volume)
686 {
687     MEDIA_LOG_I("SetVolume entered.");
688     OSAL::ScopedLock lock(renderMutex_);
689     if (audioRenderer_ != nullptr) {
690         int32_t ret = audioRenderer_->SetVolume(volume);
691         if (ret != OHOS::AudioStandard::SUCCESS) {
692             MEDIA_LOG_E("set volume failed with code " PUBLIC_LOG_D32, ret);
693             return Status::ERROR_UNKNOWN;
694         }
695         return Status::OK;
696     }
697     return Status::ERROR_WRONG_STATE;
698 }
699 
Resume()700 Status AudioServerSinkPlugin::Resume()
701 {
702     MEDIA_LOG_I("Resume entered.");
703     return Start();
704 }
705 
Pause()706 Status AudioServerSinkPlugin::Pause()
707 {
708     MEDIA_LOG_I("Pause entered.");
709     OSAL::ScopedLock lock(renderMutex_);
710     if (audioRenderer_ && audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING
711         && !audioRenderer_->Pause()) {
712         MEDIA_LOG_E("audio renderer pause fail");
713         return Status::ERROR_UNKNOWN;
714     }
715     MEDIA_LOG_I("audio renderer pause success");
716     return Status::OK;
717 }
718 
GetLatency(uint64_t & hstTime)719 Status AudioServerSinkPlugin::GetLatency(uint64_t& hstTime)
720 {
721     hstTime = 0; // set latency as 0 since latency of audio system is not reliable
722     return Status::OK;
723 }
724 
Write(const std::shared_ptr<Buffer> & input)725 Status AudioServerSinkPlugin::Write(const std::shared_ptr<Buffer>& input)
726 {
727     FALSE_RETURN_V_MSG_W(input != nullptr && !input->IsEmpty(), Status::OK, "Receive empty buffer."); // return ok
728     auto mem = input->GetMemory();
729     auto srcBuffer = mem->GetReadOnlyData();
730     auto destBuffer = const_cast<uint8_t*>(srcBuffer);
731     auto srcLength = mem->GetSize();
732     auto destLength = srcLength;
733     if (needReformat_ && resample_ && srcLength >0) {
734         FALSE_LOG(resample_->Convert(srcBuffer, srcLength, destBuffer, destLength) == Status::OK);
735     }
736     MEDIA_LOG_DD("write data size " PUBLIC_LOG_ZU, destLength);
737     while (isForcePaused_ && seekable_ == Seekable::SEEKABLE) {
738         OSAL::SleepFor(5); // 5ms
739         continue;
740     }
741     int32_t ret = 0;
742     OSAL::ScopedLock lock(renderMutex_);
743     FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_WRONG_STATE);
744     for (; destLength > 0;) {
745         ret = audioRenderer_->Write(destBuffer, destLength);
746         if (ret < 0) {
747             MEDIA_LOG_E("Write data error ret is: " PUBLIC_LOG_D32, ret);
748             break;
749         } else if (static_cast<size_t>(ret) < destLength) {
750             OSAL::SleepFor(5); // 5ms
751         }
752         destBuffer += ret;
753         destLength -= ret;
754         MEDIA_LOG_DD("written data size " PUBLIC_LOG_D32, ret);
755     }
756     return ret >= 0 ? Status::OK : Status::ERROR_UNKNOWN;
757 }
758 
Flush()759 Status AudioServerSinkPlugin::Flush()
760 {
761     MEDIA_LOG_I("Flush entered.");
762     OSAL::ScopedLock lock(renderMutex_);
763     if (audioRenderer_ == nullptr) {
764         return Status::ERROR_WRONG_STATE;
765     }
766     if (audioRenderer_->Flush()) {
767         MEDIA_LOG_I("audioRenderer_ Flush() success");
768         return Status::OK;
769     }
770     MEDIA_LOG_E("audioRenderer_ Flush() fail");
771     return Status::ERROR_UNKNOWN;
772 }
773 
Drain()774 Status AudioServerSinkPlugin::Drain()
775 {
776     MEDIA_LOG_I("Drain entered.");
777     OSAL::ScopedLock lock(renderMutex_);
778     if (audioRenderer_ == nullptr) {
779         return Status::ERROR_WRONG_STATE;
780     }
781     if (!audioRenderer_->Drain()) {
782         uint64_t latency = 0;
783         audioRenderer_->GetLatency(latency);
784         latency /= 1000; // 1000 cast into ms
785         if (latency > 50) { // 50 latency too large
786             MEDIA_LOG_W("Drain failed and latency is too large, will sleep " PUBLIC_LOG_U64 " ms, aka. latency.",
787                         latency);
788             OSAL::SleepFor(latency);
789         }
790     }
791     MEDIA_LOG_I("audioRenderer_ Drain() success");
792     return Status::OK;
793 }
794 } // namespace AuSrSinkPlugin
795 } // Plugin
796 } // namespace Media
797 } // namespace OHOS
798