• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
__anon68ed62490202null176 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 }
229 
~AudioServerSinkPlugin()230 AudioServerSinkPlugin::~AudioServerSinkPlugin()
231 {
232     MEDIA_LOG_I("~AudioServerSinkPlugin() entered.");
233     ReleaseRender();
234 }
235 
Init()236 Status AudioServerSinkPlugin::Init()
237 {
238     MEDIA_LOG_I("Init entered.");
239     OSAL::ScopedLock lock(renderMutex_);
240     if (audioRenderer_ == nullptr) {
241         AudioStandard::AppInfo appInfo;
242         appInfo.appPid = appPid_;
243         appInfo.appUid = appUid_;
244         MEDIA_LOG_I("Create audio renderer for apppid_ " PUBLIC_LOG_D32 " appuid_ " PUBLIC_LOG_D32 " contentType "
245             PUBLIC_LOG_D32 " streamUsage " PUBLIC_LOG_D32 " rendererFlags " PUBLIC_LOG_D32 " audioInterruptMode_ "
246             PUBLIC_LOG_U32, appPid_, appUid_, audioRenderInfo_.contentType, audioRenderInfo_.streamUsage,
247             audioRenderInfo_.rendererFlags, static_cast<uint32_t>(audioInterruptMode_));
248         rendererOptions_.rendererInfo.contentType = static_cast<AudioStandard::ContentType>(
249             audioRenderInfo_.contentType);
250         rendererOptions_.rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(
251             audioRenderInfo_.streamUsage);
252         rendererOptions_.rendererInfo.rendererFlags = audioRenderInfo_.rendererFlags;
253         rendererOptions_.streamInfo.samplingRate = AudioStandard::SAMPLE_RATE_8000;
254         rendererOptions_.streamInfo.encoding = AudioStandard::ENCODING_PCM;
255         rendererOptions_.streamInfo.format = AudioStandard::SAMPLE_S16LE;
256         rendererOptions_.streamInfo.channels = AudioStandard::MONO;
257         audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions_, appInfo);
258         if (audioRenderer_ == nullptr) {
259             MEDIA_LOG_E("Create audioRenderer_ fail");
260             return Status::ERROR_UNKNOWN;
261         }
262         audioRenderer_->SetInterruptMode(audioInterruptMode_);
263         if (audioRendererCallback_ == nullptr) {
264             audioRendererCallback_ = std::make_shared<AudioRendererCallbackImpl>(callback_, isForcePaused_);
265             audioRenderer_->SetRendererCallback(audioRendererCallback_);
266         }
267     }
268     return Status::OK;
269 }
270 
ReleaseRender()271 void AudioServerSinkPlugin::ReleaseRender()
272 {
273     OSAL::ScopedLock lock(renderMutex_);
274     if (audioRenderer_ != nullptr && audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_RELEASED) {
275         if (!audioRenderer_->Release()) {
276             MEDIA_LOG_W("release audio render failed");
277             return;
278         }
279     }
280     audioRenderer_.reset();
281 }
282 
Deinit()283 Status AudioServerSinkPlugin::Deinit()
284 {
285     MEDIA_LOG_I("Deinit entered.");
286     ReleaseRender();
287     return Status::OK;
288 }
289 
Prepare()290 Status AudioServerSinkPlugin::Prepare()
291 {
292     MEDIA_LOG_I("Prepare entered.");
293     FALSE_RETURN_V_MSG_E(fmtSupported_, Status::ERROR_INVALID_PARAMETER, "sample fmt is not supported");
294     if (bitsPerSample_ == 8 || bitsPerSample_ == 24) { // 8 24
295         needReformat_ = true;
296         rendererParams_.sampleFormat = reStdDestFmt_;
297     }
298     auto types = AudioStandard::AudioRenderer::GetSupportedEncodingTypes();
299     if (!CppExt::AnyOf(types.begin(), types.end(), [](AudioStandard::AudioEncodingType tmp) -> bool {
300         return tmp == AudioStandard::ENCODING_PCM;
301     })) {
302         MEDIA_LOG_E("audio renderer do not support pcm encoding");
303         return Status::ERROR_INVALID_PARAMETER;
304     }
305     rendererParams_.encodingType = AudioStandard::ENCODING_PCM;
306     MEDIA_LOG_I("set param with fmt " PUBLIC_LOG_D32 " sampleRate " PUBLIC_LOG_D32 " channel " PUBLIC_LOG_D32
307         " encode type " PUBLIC_LOG_D32,
308         rendererParams_.sampleFormat, rendererParams_.sampleRate, rendererParams_.channelCount,
309         rendererParams_.encodingType);
310     {
311         OSAL::ScopedLock lock(renderMutex_);
312         auto ret = audioRenderer_->SetParams(rendererParams_);
313         if (ret != AudioStandard::SUCCESS) {
314             MEDIA_LOG_E("audio renderer SetParams() fail with " PUBLIC_LOG_D32, ret);
315             return Status::ERROR_UNKNOWN;
316         }
317     }
318     if (needReformat_) {
319         resample_ = std::make_shared<Ffmpeg::Resample>();
320         Ffmpeg::ResamplePara resamplePara {
321             channels_,
322             sampleRate_,
323             bitsPerSample_,
324             static_cast<int64_t>(channelLayout_),
325             reSrcFfFmt_,
326             samplesPerFrame_,
327             reFfDestFmt_,
328         };
329         FALSE_RETURN_V_MSG(resample_->Init(resamplePara) == Status::OK, Status::ERROR_UNKNOWN, "Resample init error");
330     }
331     return Status::OK;
332 }
333 
StopRender()334 bool AudioServerSinkPlugin::StopRender()
335 {
336     OSAL::ScopedLock lock(renderMutex_);
337     if (audioRenderer_) {
338         if (audioRenderer_->GetStatus() == AudioStandard::RendererState::RENDERER_STOPPED) {
339             MEDIA_LOG_I("AudioRenderer is already in stopped state.");
340             return true;
341         }
342         return audioRenderer_->Stop();
343     }
344     return true;
345 }
346 
Reset()347 Status AudioServerSinkPlugin::Reset()
348 {
349     MEDIA_LOG_I("Reset entered.");
350     if (!StopRender()) {
351         MEDIA_LOG_E("stop render error");
352         return Status::ERROR_UNKNOWN;
353     }
354     ResetAudioRendererParams(rendererParams_);
355     fmtSupported_ = false;
356     reSrcFfFmt_ = AV_SAMPLE_FMT_NONE;
357     channels_ = 0;
358     bitRate_ = 0;
359     sampleRate_ = 0;
360     samplesPerFrame_ = 0;
361     needReformat_ = false;
362     if (resample_) {
363         resample_.reset();
364     }
365     return Status::OK;
366 }
367 
Start()368 Status AudioServerSinkPlugin::Start()
369 {
370     MEDIA_LOG_I("Start entered.");
371     bool ret = false;
372     OSAL::ScopedLock lock(renderMutex_);
373     {
374         if (audioRenderer_ == nullptr) {
375             return Status::ERROR_WRONG_STATE;
376         }
377         ret = audioRenderer_->Start();
378     }
379     if (ret) {
380         MEDIA_LOG_I("audioRenderer_ Start() success");
381         return Status::OK;
382     } else {
383         MEDIA_LOG_E("audioRenderer_ Start() fail");
384     }
385     return Status::ERROR_UNKNOWN;
386 }
387 
Stop()388 Status AudioServerSinkPlugin::Stop()
389 {
390     MEDIA_LOG_I("Stop entered.");
391     if (StopRender()) {
392         MEDIA_LOG_I("stop render success");
393         return Status::OK;
394     } else {
395         MEDIA_LOG_E("stop render failed");
396     }
397     return Status::ERROR_UNKNOWN;
398 }
399 
GetParameter(Tag tag,ValueType & para)400 Status AudioServerSinkPlugin::GetParameter(Tag tag, ValueType& para)
401 {
402     MEDIA_LOG_I("GetParameter entered, key: " PUBLIC_LOG_S, Tag2String(tag));
403     AudioStandard::AudioRendererParams params;
404     OSAL::ScopedLock lock(renderMutex_);
405     switch (tag) {
406         case Tag::AUDIO_SAMPLE_RATE:
407             if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
408                 if (params.sampleRate != rendererParams_.sampleRate) {
409                     MEDIA_LOG_W("samplingRate has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
410                                 rendererParams_.sampleRate, params.sampleRate);
411                 }
412                 para = params.sampleRate;
413             }
414             break;
415         case Tag::AUDIO_OUTPUT_CHANNELS:
416             para = DEFAULT_OUTPUT_CHANNELS; // get the real output channels from audio server here
417             MEDIA_LOG_I("Get outputChannels: " PUBLIC_LOG_U32, DEFAULT_OUTPUT_CHANNELS);
418             break;
419         case Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT:
420             para = DEFAULT_OUTPUT_CHANNEL_LAYOUT; // get the real output channel layout from audio server here
421             MEDIA_LOG_I("Get outputChannelLayout: " PUBLIC_LOG_U64, DEFAULT_OUTPUT_CHANNEL_LAYOUT);
422             break;
423         case Tag::MEDIA_BITRATE:
424             para = bitRate_;
425             break;
426         case Tag::AUDIO_SAMPLE_FORMAT:
427             if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
428                 if (params.sampleFormat != rendererParams_.sampleFormat) {
429                     MEDIA_LOG_W("sampleFormat has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
430                                 rendererParams_.sampleFormat, params.sampleFormat);
431                 }
432                 para = params.sampleFormat;
433             }
434             break;
435         default:
436             MEDIA_LOG_I("Unknown key");
437             break;
438     }
439     return Status::OK;
440 }
441 
AssignSampleRateIfSupported(uint32_t sampleRate)442 bool AudioServerSinkPlugin::AssignSampleRateIfSupported(uint32_t sampleRate)
443 {
444     sampleRate_ = sampleRate;
445     AudioStandard::AudioSamplingRate aRate = AudioStandard::SAMPLE_RATE_8000;
446     if (!SampleRateNum2Enum(sampleRate, aRate)) {
447         MEDIA_LOG_E("sample rate " PUBLIC_LOG_U32 "not supported", sampleRate);
448         return false;
449     }
450     auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
451     if (supportedSampleRateList.empty()) {
452         MEDIA_LOG_E("GetSupportedSamplingRates() fail");
453         return false;
454     }
455     for (const auto& rate : supportedSampleRateList) {
456         if (rate == aRate) {
457             rendererParams_.sampleRate = rate;
458             MEDIA_LOG_D("sampleRate: " PUBLIC_LOG_U32, rendererParams_.sampleRate);
459             return true;
460         }
461     }
462     return false;
463 }
464 
AssignChannelNumIfSupported(uint32_t channelNum)465 bool AudioServerSinkPlugin::AssignChannelNumIfSupported(uint32_t channelNum)
466 {
467     AudioStandard::AudioChannel aChannel = AudioStandard::MONO;
468     if (!ChannelNumNum2Enum(channelNum, aChannel)) {
469         MEDIA_LOG_E("channel num " PUBLIC_LOG_U32 "not supported", channelNum);
470         return false;
471     }
472     auto supportedChannelsList = OHOS::AudioStandard::AudioRenderer::GetSupportedChannels();
473     if (supportedChannelsList.empty()) {
474         MEDIA_LOG_E("GetSupportedChannels() fail");
475         return false;
476     }
477     for (const auto& channel : supportedChannelsList) {
478         if (channel == aChannel) {
479             rendererParams_.channelCount = channel;
480             MEDIA_LOG_D("channelCount: " PUBLIC_LOG_U32, rendererParams_.channelCount);
481             return true;
482         }
483     }
484     return false;
485 }
486 
AssignSampleFmtIfSupported(Plugin::AudioSampleFormat sampleFormat)487 bool AudioServerSinkPlugin::AssignSampleFmtIfSupported(Plugin::AudioSampleFormat sampleFormat)
488 {
489     const auto& item = std::find_if(g_aduFmtMap.begin(), g_aduFmtMap.end(), [&sampleFormat] (const auto& tmp) -> bool {
490         return std::get<0>(tmp) == sampleFormat;
491     });
492     auto stdFmt = std::get<1>(*item);
493     if (stdFmt == OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH) {
494         if (std::get<2>(*item) == AV_SAMPLE_FMT_NONE) { // 2
495             fmtSupported_ = false;
496         } else {
497             fmtSupported_ = true;
498             needReformat_ = true;
499             reSrcFfFmt_ = std::get<2>(*item); // 2
500             rendererParams_.sampleFormat = reStdDestFmt_;
501         }
502     } else {
503         auto supportedFmts = OHOS::AudioStandard::AudioRenderer::GetSupportedFormats();
504         if (CppExt::AnyOf(supportedFmts.begin(), supportedFmts.end(), [&stdFmt](const auto& tmp) -> bool {
505             return tmp == stdFmt;
506         })) {
507             fmtSupported_ = true;
508             needReformat_ = false;
509             rendererParams_.sampleFormat = stdFmt;
510         } else {
511             fmtSupported_ = false;
512             needReformat_ = false;
513         }
514     }
515     return fmtSupported_;
516 }
517 
SetInterruptMode(AudioStandard::InterruptMode interruptMode)518 void AudioServerSinkPlugin::SetInterruptMode(AudioStandard::InterruptMode interruptMode)
519 {
520     OSAL::ScopedLock lock(renderMutex_);
521     if (audioRenderer_) {
522         audioRenderer_->SetInterruptMode(interruptMode);
523     }
524 }
525 
SetParameter(Tag tag,const ValueType & para)526 Status AudioServerSinkPlugin::SetParameter(Tag tag, const ValueType& para)
527 {
528     MEDIA_LOG_I("SetParameter entered, key: " PUBLIC_LOG_S, Tag2String(tag));
529     switch (tag) {
530         case Tag::AUDIO_SAMPLE_RATE:
531             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(uint32_t)), Status::ERROR_MISMATCHED_TYPE,
532                 "sample rate type should be uint32_t");
533             FALSE_RETURN_V_MSG_E(AssignSampleRateIfSupported(Plugin::AnyCast<uint32_t>(para)),
534                 Status::ERROR_INVALID_PARAMETER, "sampleRate isn't supported");
535             break;
536         case Tag::AUDIO_OUTPUT_CHANNELS:
537             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(uint32_t)), Status::ERROR_MISMATCHED_TYPE,
538                 "channels type should be uint32_t");
539             channels_ = Plugin::AnyCast<uint32_t>(para);
540             MEDIA_LOG_I("Set outputChannels: " PUBLIC_LOG_U32, channels_);
541             FALSE_RETURN_V_MSG_E(AssignChannelNumIfSupported(channels_), Status::ERROR_INVALID_PARAMETER,
542                 "channel isn't supported");
543             break;
544         case Tag::MEDIA_BITRATE:
545             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(int64_t)), Status::ERROR_MISMATCHED_TYPE,
546                 "bit rate type should be int64_t");
547             bitRate_ = Plugin::AnyCast<int64_t>(para);
548             break;
549         case Tag::AUDIO_SAMPLE_FORMAT:
550             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(AudioSampleFormat)), Status::ERROR_MISMATCHED_TYPE,
551                 "AudioSampleFormat type should be AudioSampleFormat");
552             FALSE_RETURN_V_MSG_E(AssignSampleFmtIfSupported(Plugin::AnyCast<AudioSampleFormat>(para)),
553                 Status::ERROR_INVALID_PARAMETER, "sampleFmt isn't supported by audio renderer or resample lib");
554             break;
555         case Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT:
556             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(AudioChannelLayout)), Status::ERROR_MISMATCHED_TYPE,
557                 "channel layout type should be AudioChannelLayout");
558             channelLayout_ = Plugin::AnyCast<AudioChannelLayout>(para);
559             MEDIA_LOG_I("Set outputChannelLayout: " PUBLIC_LOG_U64, channelLayout_);
560             break;
561         case Tag::AUDIO_SAMPLE_PER_FRAME:
562             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(uint32_t)), Status::ERROR_MISMATCHED_TYPE,
563                 "SAMPLE_PER_FRAME type should be uint32_t");
564             samplesPerFrame_ = Plugin::AnyCast<uint32_t>(para);
565             break;
566         case Tag::BITS_PER_CODED_SAMPLE:
567             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(uint32_t)), Status::ERROR_MISMATCHED_TYPE,
568                                  "BITS_PER_CODED_SAMPLE type should be uint32_t");
569             bitsPerSample_ = Plugin::AnyCast<uint32_t>(para);
570             break;
571         case Tag::MEDIA_SEEKABLE:
572             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(Seekable)), Status::ERROR_MISMATCHED_TYPE,
573                                  "MEDIA_SEEKABLE type should be Seekable");
574             seekable_ = Plugin::AnyCast<Plugin::Seekable>(para);
575             break;
576         case Tag::APP_PID:
577             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(int32_t)), Status::ERROR_MISMATCHED_TYPE,
578                 "APP_PID type should be int32_t");
579             appPid_ = Plugin::AnyCast<int32_t>(para);
580             break;
581         case Tag::APP_UID:
582             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(int32_t)), Status::ERROR_MISMATCHED_TYPE,
583                 "APP_UID type should be int32_t");
584             appUid_ = Plugin::AnyCast<int32_t>(para);
585             break;
586         case Tag::AUDIO_RENDER_INFO:
587             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(AudioRenderInfo)), Status::ERROR_MISMATCHED_TYPE,
588                                  "AUDIO_RENDER_INFO type should be AudioRenderInfo");
589             audioRenderInfo_ = Plugin::AnyCast<AudioRenderInfo>(para);
590             break;
591         case Tag::AUDIO_INTERRUPT_MODE:
592             FALSE_RETURN_V_MSG_E(para.SameTypeWith(typeid(AudioInterruptMode)), Status::ERROR_MISMATCHED_TYPE,
593                                  "AUDIO_INTERRUPT_MODE type should be AudioInterruptMode");
594             AudioInterruptMode2InterruptMode(Plugin::AnyCast<AudioInterruptMode>(para), audioInterruptMode_);
595             SetInterruptMode(audioInterruptMode_);
596             break;
597         default:
598             MEDIA_LOG_I("Unknown key");
599             break;
600     }
601     return Status::OK;
602 }
603 
GetVolume(float & volume)604 Status AudioServerSinkPlugin::GetVolume(float& volume)
605 {
606     MEDIA_LOG_I("GetVolume entered.");
607     OSAL::ScopedLock lock(renderMutex_);
608     if (audioRenderer_ != nullptr) {
609         volume = audioRenderer_->GetVolume();
610         return Status::OK;
611     }
612     return Status::ERROR_WRONG_STATE;
613 }
614 
SetVolume(float volume)615 Status AudioServerSinkPlugin::SetVolume(float volume)
616 {
617     MEDIA_LOG_I("SetVolume entered.");
618     OSAL::ScopedLock lock(renderMutex_);
619     if (audioRenderer_ != nullptr) {
620         int32_t ret = audioRenderer_->SetVolume(volume);
621         if (ret != OHOS::AudioStandard::SUCCESS) {
622             MEDIA_LOG_E("set volume failed with code " PUBLIC_LOG_D32, ret);
623             return Status::ERROR_UNKNOWN;
624         }
625         return Status::OK;
626     }
627     return Status::ERROR_WRONG_STATE;
628 }
629 
Resume()630 Status AudioServerSinkPlugin::Resume()
631 {
632     MEDIA_LOG_I("Resume entered.");
633     return Start();
634 }
635 
Pause()636 Status AudioServerSinkPlugin::Pause()
637 {
638     MEDIA_LOG_I("Pause entered.");
639     OSAL::ScopedLock lock(renderMutex_);
640     if (audioRenderer_ && audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING
641         && !audioRenderer_->Pause()) {
642         MEDIA_LOG_E("audio renderer pause fail");
643         return Status::ERROR_UNKNOWN;
644     }
645     MEDIA_LOG_I("audio renderer pause success");
646     return Status::OK;
647 }
648 
GetLatency(uint64_t & hstTime)649 Status AudioServerSinkPlugin::GetLatency(uint64_t& hstTime)
650 {
651     hstTime = 0; // set latency as 0 since latency of audio system is not reliable
652     return Status::OK;
653 }
654 
Write(const std::shared_ptr<Buffer> & input)655 Status AudioServerSinkPlugin::Write(const std::shared_ptr<Buffer>& input)
656 {
657     FALSE_RETURN_V_MSG_W(input != nullptr && !input->IsEmpty(), Status::OK, "Receive empty buffer."); // return ok
658     auto mem = input->GetMemory();
659     auto srcBuffer = mem->GetReadOnlyData();
660     auto destBuffer = const_cast<uint8_t*>(srcBuffer);
661     auto srcLength = mem->GetSize();
662     auto destLength = srcLength;
663     if (needReformat_ && resample_ && srcLength >0) {
664         FALSE_LOG(resample_->Convert(srcBuffer, srcLength, destBuffer, destLength) == Status::OK);
665     }
666     MEDIA_LOG_DD("write data size " PUBLIC_LOG_ZU, destLength);
667     while (isForcePaused_ && seekable_ == Seekable::SEEKABLE) {
668         OSAL::SleepFor(5); // 5ms
669         continue;
670     }
671     int32_t ret = 0;
672     OSAL::ScopedLock lock(renderMutex_);
673     FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_WRONG_STATE);
674     for (; destLength > 0;) {
675         ret = audioRenderer_->Write(destBuffer, destLength);
676         if (ret < 0) {
677             MEDIA_LOG_E("Write data error ret is: " PUBLIC_LOG_D32, ret);
678             break;
679         } else if (static_cast<size_t>(ret) < destLength) {
680             OSAL::SleepFor(5); // 5ms
681         }
682         destBuffer += ret;
683         destLength -= ret;
684         MEDIA_LOG_DD("written data size " PUBLIC_LOG_D32, ret);
685     }
686     return ret >= 0 ? Status::OK : Status::ERROR_UNKNOWN;
687 }
688 
Flush()689 Status AudioServerSinkPlugin::Flush()
690 {
691     MEDIA_LOG_I("Flush entered.");
692     OSAL::ScopedLock lock(renderMutex_);
693     if (audioRenderer_ == nullptr) {
694         return Status::ERROR_WRONG_STATE;
695     }
696     if (audioRenderer_->Flush()) {
697         MEDIA_LOG_I("audioRenderer_ Flush() success");
698         return Status::OK;
699     }
700     MEDIA_LOG_E("audioRenderer_ Flush() fail");
701     return Status::ERROR_UNKNOWN;
702 }
703 
Drain()704 Status AudioServerSinkPlugin::Drain()
705 {
706     MEDIA_LOG_I("Drain entered.");
707     OSAL::ScopedLock lock(renderMutex_);
708     if (audioRenderer_ == nullptr) {
709         return Status::ERROR_WRONG_STATE;
710     }
711     if (!audioRenderer_->Drain()) {
712         uint64_t latency = 0;
713         audioRenderer_->GetLatency(latency);
714         latency /= 1000; // 1000 cast into ms
715         if (latency > 50) { // 50 latency too large
716             MEDIA_LOG_W("Drain failed and latency is too large, will sleep " PUBLIC_LOG_U64 " ms, aka. latency.",
717                         latency);
718             OSAL::SleepFor(latency);
719         }
720     }
721     MEDIA_LOG_I("audioRenderer_ Drain() success");
722     return Status::OK;
723 }
724 } // namespace AuSrSinkPlugin
725 } // Plugin
726 } // namespace Media
727 } // namespace OHOS
728