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