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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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 ¶) {
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