1 /*
2 * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define MEDIA_PLUGIN
17 #define HST_LOG_TAG "ASSP"
18
19 #include "audio_server_sink_plugin.h"
20 #include <functional>
21 #include "audio_errors.h"
22 #include "avcodec_trace.h"
23 #include "common/log.h"
24 #include "common/media_core.h"
25 #include "meta/meta_key.h"
26 #include "osal/task/autolock.h"
27 #include "osal/task/jobutils.h"
28 #include "common/status.h"
29 #include "common/media_core.h"
30 #include "audio_info.h"
31 #include "cpp_ext/algorithm_ext.h"
32 #include "osal/utils/steady_clock.h"
33 #include "plugin/plugin_time.h"
34 #include "param_wrapper.h"
35
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "HiStreamer" };
38 using namespace OHOS::Media::Plugins;
39 constexpr int TUPLE_SECOND_ITEM_INDEX = 2;
40 constexpr int32_t DEFAULT_BUFFER_NUM = 8;
41
42 const std::pair<AudioInterruptMode, OHOS::AudioStandard::InterruptMode> g_auInterruptMap[] = {
43 {AudioInterruptMode::SHARE_MODE, OHOS::AudioStandard::InterruptMode::SHARE_MODE},
44 {AudioInterruptMode::INDEPENDENT_MODE, OHOS::AudioStandard::InterruptMode::INDEPENDENT_MODE},
45 };
46
47 const std::vector<std::tuple<AudioSampleFormat, OHOS::AudioStandard::AudioSampleFormat, AVSampleFormat>> g_aduFmtMap = {
48 {AudioSampleFormat::SAMPLE_S8, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
49 {AudioSampleFormat::SAMPLE_U8, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_U8, AV_SAMPLE_FMT_U8},
50 {AudioSampleFormat::SAMPLE_S8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
51 {AudioSampleFormat::SAMPLE_U8P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_U8P},
52 {AudioSampleFormat::SAMPLE_S16LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE, AV_SAMPLE_FMT_S16},
53 {AudioSampleFormat::SAMPLE_U16, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
54 {AudioSampleFormat::SAMPLE_S16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S16P},
55 {AudioSampleFormat::SAMPLE_U16P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
56 {AudioSampleFormat::SAMPLE_S24LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S24LE, AV_SAMPLE_FMT_NONE},
57 {AudioSampleFormat::SAMPLE_U24, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
58 {AudioSampleFormat::SAMPLE_S24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
59 {AudioSampleFormat::SAMPLE_U24P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
60 {AudioSampleFormat::SAMPLE_S32LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S32LE, AV_SAMPLE_FMT_S32},
61 {AudioSampleFormat::SAMPLE_U32, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
62 {AudioSampleFormat::SAMPLE_S32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S32P},
63 {AudioSampleFormat::SAMPLE_U32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
64 {AudioSampleFormat::SAMPLE_F32LE, OHOS::AudioStandard::AudioSampleFormat::SAMPLE_F32LE, AV_SAMPLE_FMT_NONE},
65 {AudioSampleFormat::SAMPLE_F32P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_FLTP},
66 {AudioSampleFormat::SAMPLE_F64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBL},
67 {AudioSampleFormat::SAMPLE_F64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_DBLP},
68 {AudioSampleFormat::SAMPLE_S64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64},
69 {AudioSampleFormat::SAMPLE_U64, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
70 {AudioSampleFormat::SAMPLE_S64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_S64P},
71 {AudioSampleFormat::SAMPLE_U64P, OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH, AV_SAMPLE_FMT_NONE},
72 };
73
AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,OHOS::AudioStandard::InterruptMode & interruptMode)74 void AudioInterruptMode2InterruptMode(AudioInterruptMode audioInterruptMode,
75 OHOS::AudioStandard::InterruptMode &interruptMode)
76 {
77 for (const auto &item : g_auInterruptMap) {
78 if (item.first == audioInterruptMode) {
79 interruptMode = item.second;
80 }
81 }
82 }
83
UpdateSupportedSampleRate(Capability & inCaps)84 void UpdateSupportedSampleRate(Capability &inCaps)
85 {
86 auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
87 if (!supportedSampleRateList.empty()) {
88 DiscreteCapability<uint32_t> values;
89 for (const auto &rate : supportedSampleRateList) {
90 values.push_back(static_cast<uint32_t>(rate));
91 }
92 if (!values.empty()) {
93 inCaps.AppendDiscreteKeys<uint32_t>(OHOS::Media::Tag::AUDIO_SAMPLE_RATE, values);
94 }
95 }
96 }
97
UpdateSupportedSampleFormat(Capability & inCaps)98 void UpdateSupportedSampleFormat(Capability &inCaps)
99 {
100 DiscreteCapability<AudioSampleFormat> values(g_aduFmtMap.size());
101 for (const auto &item : g_aduFmtMap) {
102 if (std::get<1>(item) != OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH ||
103 std::get<TUPLE_SECOND_ITEM_INDEX>(item) != AV_SAMPLE_FMT_NONE) {
104 values.emplace_back(std::get<0>(item));
105 }
106 }
107 inCaps.AppendDiscreteKeys(OHOS::Media::Tag::AUDIO_SAMPLE_FORMAT, values);
108 }
109
AudioServerSinkRegister(const std::shared_ptr<Register> & reg)110 OHOS::Media::Status AudioServerSinkRegister(const std::shared_ptr<Register> ®)
111 {
112 AudioSinkPluginDef definition;
113 definition.name = "AudioServerSink";
114 definition.description = "Audio sink for audio server of media standard";
115 definition.rank = 100; // 100: max rank
116 auto func = [](const std::string &name) -> std::shared_ptr<AudioSinkPlugin> {
117 return std::make_shared<OHOS::Media::Plugins::AudioServerSinkPlugin>(name);
118 };
119 definition.SetCreator(func);
120 Capability inCaps(MimeType::AUDIO_RAW);
121 UpdateSupportedSampleRate(inCaps);
122 UpdateSupportedSampleFormat(inCaps);
123 definition.AddInCaps(inCaps);
124 return reg->AddPlugin(definition);
125 }
126
__anonb92ec06b0302null127 PLUGIN_DEFINITION(AudioServerSink, LicenseType::APACHE_V2, AudioServerSinkRegister, [] {});
128
ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams & param)129 inline void ResetAudioRendererParams(OHOS::AudioStandard::AudioRendererParams ¶m)
130 {
131 using namespace OHOS::AudioStandard;
132 param.sampleFormat = OHOS::AudioStandard::INVALID_WIDTH;
133 param.sampleRate = SAMPLE_RATE_8000;
134 param.channelCount = OHOS::AudioStandard::MONO;
135 param.encodingType = ENCODING_INVALID;
136 }
137 } // namespace
138
139 namespace OHOS {
140 namespace Media {
141 namespace Plugins {
142 using namespace OHOS::Media::Plugins;
143
AudioRendererCallbackImpl(const std::shared_ptr<Pipeline::EventReceiver> & receiver,const bool & isPaused)144 AudioServerSinkPlugin::AudioRendererCallbackImpl::AudioRendererCallbackImpl(
145 const std::shared_ptr<Pipeline::EventReceiver> &receiver, const bool &isPaused) : playerEventReceiver_(receiver),
146 isPaused_(isPaused)
147 {
148 }
149
AudioServiceDiedCallbackImpl(std::shared_ptr<Pipeline::EventReceiver> & receiver)150 AudioServerSinkPlugin::AudioServiceDiedCallbackImpl::AudioServiceDiedCallbackImpl(
151 std::shared_ptr<Pipeline::EventReceiver> &receiver) : playerEventReceiver_(receiver)
152 {
153 }
154
AudioFirstFrameCallbackImpl(std::shared_ptr<Pipeline::EventReceiver> & receiver)155 AudioServerSinkPlugin::AudioFirstFrameCallbackImpl::AudioFirstFrameCallbackImpl(
156 std::shared_ptr<Pipeline::EventReceiver> &receiver)
157 {
158 FALSE_RETURN(receiver != nullptr);
159 playerEventReceiver_ = receiver;
160 }
161
OnInterrupt(const OHOS::AudioStandard::InterruptEvent & interruptEvent)162 void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnInterrupt(
163 const OHOS::AudioStandard::InterruptEvent &interruptEvent)
164 {
165 MEDIA_LOG_D_T("OnInterrupt forceType is " PUBLIC_LOG_U32, static_cast<uint32_t>(interruptEvent.forceType));
166 if (interruptEvent.forceType == OHOS::AudioStandard::INTERRUPT_FORCE) {
167 switch (interruptEvent.hintType) {
168 case OHOS::AudioStandard::INTERRUPT_HINT_PAUSE:
169 isPaused_ = true;
170 break;
171 default:
172 isPaused_ = false;
173 break;
174 }
175 }
176 Event event {
177 .srcFilter = "Audio interrupt event",
178 .type = EventType::EVENT_AUDIO_INTERRUPT,
179 .param = interruptEvent
180 };
181 FALSE_RETURN(playerEventReceiver_ != nullptr);
182 MEDIA_LOG_D_T("OnInterrupt event upload ");
183 playerEventReceiver_->OnEvent(event);
184 }
185
OnStateChange(const OHOS::AudioStandard::RendererState state,const OHOS::AudioStandard::StateChangeCmdType cmdType)186 void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnStateChange(
187 const OHOS::AudioStandard::RendererState state, const OHOS::AudioStandard::StateChangeCmdType cmdType)
188 {
189 MEDIA_LOG_D_T("RenderState is " PUBLIC_LOG_U32, static_cast<uint32_t>(state));
190 if (cmdType == AudioStandard::StateChangeCmdType::CMD_FROM_SYSTEM) {
191 Event event {
192 .srcFilter = "Audio state change event",
193 .type = EventType::EVENT_AUDIO_STATE_CHANGE,
194 .param = state
195 };
196 FALSE_RETURN(playerEventReceiver_ != nullptr);
197 playerEventReceiver_->OnEvent(event);
198 }
199 }
200
OnOutputDeviceChange(const AudioStandard::DeviceInfo & deviceInfo,const AudioStandard::AudioStreamDeviceChangeReason reason)201 void AudioServerSinkPlugin::AudioRendererCallbackImpl::OnOutputDeviceChange(
202 const AudioStandard::DeviceInfo &deviceInfo, const AudioStandard::AudioStreamDeviceChangeReason reason)
203 {
204 MEDIA_LOG_D_T("DeviceChange reason is " PUBLIC_LOG_D32, static_cast<int32_t>(reason));
205 auto param = std::make_pair(deviceInfo, reason);
206 Event event {
207 .srcFilter = "Audio deviceChange change event",
208 .type = EventType::EVENT_AUDIO_DEVICE_CHANGE,
209 .param = param
210 };
211 FALSE_RETURN(playerEventReceiver_ != nullptr);
212 playerEventReceiver_->OnEvent(event);
213 }
214
OnFirstFrameWriting(uint64_t latency)215 void AudioServerSinkPlugin::AudioFirstFrameCallbackImpl::OnFirstFrameWriting(uint64_t latency)
216 {
217 MEDIA_LOG_I_T("OnFirstFrameWriting latency: " PUBLIC_LOG_U64, latency);
218 Event event {
219 .srcFilter = "Audio render first frame writing event",
220 .type = EventType::EVENT_AUDIO_FIRST_FRAME,
221 .param = latency
222 };
223 FALSE_RETURN(playerEventReceiver_ != nullptr);
224 playerEventReceiver_->OnEvent(event);
225 MEDIA_LOG_I_T("OnFirstFrameWriting event upload ");
226 }
227
OnAudioPolicyServiceDied()228 void AudioServerSinkPlugin::AudioServiceDiedCallbackImpl::OnAudioPolicyServiceDied()
229 {
230 MEDIA_LOG_I_T("OnAudioPolicyServiceDied enter");
231 Event event {
232 .srcFilter = "Audio service died event",
233 .type = EventType::EVENT_AUDIO_SERVICE_DIED
234 };
235 FALSE_RETURN(playerEventReceiver_ != nullptr);
236 playerEventReceiver_->OnEvent(event);
237 MEDIA_LOG_I_T("OnAudioPolicyServiceDied end");
238 }
239
AudioServerSinkPlugin(std::string name)240 AudioServerSinkPlugin::AudioServerSinkPlugin(std::string name)
241 : Plugins::AudioSinkPlugin(std::move(name)), audioRenderer_(nullptr)
242 {
243 SetUpParamsSetterMap();
244 SetAudioDumpBySysParam();
245 }
246
~AudioServerSinkPlugin()247 AudioServerSinkPlugin::~AudioServerSinkPlugin()
248 {
249 MEDIA_LOG_I_T("~AudioServerSinkPlugin() entered.");
250 ReleaseRender();
251 ReleaseFile();
252 }
253
Init()254 Status AudioServerSinkPlugin::Init()
255 {
256 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Init");
257 MEDIA_LOG_I_T("Init entered.");
258 FALSE_RETURN_V_MSG(audioRenderer_ == nullptr, Status::OK, "audio renderer already create ");
259 AudioStandard::AppInfo appInfo;
260 appInfo.appPid = appPid_;
261 appInfo.appUid = appUid_;
262 MEDIA_LOG_I_T("Create audio renderer for apppid_ " PUBLIC_LOG_D32 " appuid_ " PUBLIC_LOG_D32
263 " contentType " PUBLIC_LOG_D32 " streamUsage " PUBLIC_LOG_D32 " rendererFlags " PUBLIC_LOG_D32
264 " audioInterruptMode_ " PUBLIC_LOG_U32,
265 appPid_, appUid_, audioRenderInfo_.contentType, audioRenderInfo_.streamUsage,
266 audioRenderInfo_.rendererFlags, static_cast<uint32_t>(audioInterruptMode_));
267 rendererOptions_.rendererInfo.contentType = static_cast<AudioStandard::ContentType>(audioRenderInfo_.contentType);
268 rendererOptions_.rendererInfo.streamUsage = static_cast<AudioStandard::StreamUsage>(audioRenderInfo_.streamUsage);
269 rendererOptions_.rendererInfo.rendererFlags = audioRenderInfo_.rendererFlags;
270 rendererOptions_.streamInfo.samplingRate = rendererParams_.sampleRate;
271 rendererOptions_.streamInfo.encoding =
272 mimeType_ == MimeType::AUDIO_AVS3DA ? AudioStandard::ENCODING_AUDIOVIVID : AudioStandard::ENCODING_PCM;
273 rendererOptions_.streamInfo.format = rendererParams_.sampleFormat;
274 rendererOptions_.streamInfo.channels = rendererParams_.channelCount;
275 MEDIA_LOG_I_T("Create audio renderer for samplingRate " PUBLIC_LOG_D32 " encoding " PUBLIC_LOG_D32
276 " sampleFormat " PUBLIC_LOG_D32 " channels " PUBLIC_LOG_D32,
277 rendererOptions_.streamInfo.samplingRate, rendererOptions_.streamInfo.encoding,
278 rendererOptions_.streamInfo.format, rendererOptions_.streamInfo.channels);
279 audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions_, appInfo);
280 if (audioRenderer_ == nullptr && playerEventReceiver_ != nullptr) {
281 playerEventReceiver_->OnEvent({"audioSinkPlugin", EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_SAMPLE_RATE});
282 }
283 FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
284 if (audioRenderSetFlag_ && (audioRenderInfo_.streamUsage == AudioStandard::STREAM_USAGE_MUSIC ||
285 audioRenderInfo_.streamUsage == AudioStandard::STREAM_USAGE_AUDIOBOOK)) {
286 audioRenderer_->SetOffloadAllowed(true);
287 } else {
288 audioRenderer_->SetOffloadAllowed(false);
289 }
290 audioRenderer_->SetInterruptMode(audioInterruptMode_);
291 return Status::OK;
292 }
293
GetSampleFormat()294 AudioSampleFormat AudioServerSinkPlugin::GetSampleFormat()
295 {
296 return static_cast<AudioSampleFormat>(rendererOptions_.streamInfo.format);
297 }
298
ReleaseRender()299 void AudioServerSinkPlugin::ReleaseRender()
300 {
301 if (audioRenderer_ != nullptr && audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_RELEASED) {
302 MEDIA_LOG_I_T("AudioRenderer::Release start");
303 FALSE_RETURN_MSG(audioRenderer_->Release(), "AudioRenderer::Release failed");
304 MEDIA_LOG_I_T("AudioRenderer::Release end");
305 }
306 audioRenderer_.reset();
307 }
308
ReleaseFile()309 void AudioServerSinkPlugin::ReleaseFile()
310 {
311 if (entireDumpFile_ != nullptr) {
312 (void)fclose(entireDumpFile_);
313 entireDumpFile_ = nullptr;
314 }
315 if (sliceDumpFile_ != nullptr) {
316 (void)fclose(sliceDumpFile_);
317 sliceDumpFile_ = nullptr;
318 }
319 }
320
Deinit()321 Status AudioServerSinkPlugin::Deinit()
322 {
323 MEDIA_LOG_D_T("Deinit entered");
324 ReleaseRender();
325 ReleaseFile();
326 return Status::OK;
327 }
328
Prepare()329 Status AudioServerSinkPlugin::Prepare()
330 {
331 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Prepare");
332 MEDIA_LOG_D_T("Prepare >>");
333 auto types = AudioStandard::AudioRenderer::GetSupportedEncodingTypes();
334 bool ret = CppExt::AnyOf(types.begin(), types.end(), [](AudioStandard::AudioEncodingType tmp) -> bool {
335 return tmp == AudioStandard::ENCODING_PCM;
336 });
337 FALSE_RETURN_V_MSG(ret, Status::ERROR_INVALID_PARAMETER, "audio renderer do not support pcm encoding");
338 {
339 FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
340 if (audioRendererCallback_ == nullptr) {
341 audioRendererCallback_ = std::make_shared<AudioRendererCallbackImpl>(playerEventReceiver_, isForcePaused_);
342 audioRenderer_->SetRendererCallback(audioRendererCallback_);
343 audioRenderer_->RegisterOutputDeviceChangeWithInfoCallback(audioRendererCallback_);
344 }
345 if (audioFirstFrameCallback_ == nullptr) {
346 audioFirstFrameCallback_ = std::make_shared<AudioFirstFrameCallbackImpl>(playerEventReceiver_);
347 audioRenderer_->SetRendererFirstFrameWritingCallback(audioFirstFrameCallback_);
348 }
349 if (audioServiceDiedCallback_ == nullptr) {
350 audioServiceDiedCallback_ = std::make_shared<AudioServiceDiedCallbackImpl>(playerEventReceiver_);
351 audioRenderer_->RegisterAudioPolicyServerDiedCb(getprocpid(), audioServiceDiedCallback_);
352 }
353 }
354 MEDIA_LOG_I_T("Prepare <<");
355 return Status::OK;
356 }
357
StopRender()358 bool AudioServerSinkPlugin::StopRender()
359 {
360 if (audioRenderer_) {
361 //The audio stop interface cannot be quickly stopped.
362 if (audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING) {
363 MEDIA_LOG_I_T("pause entered.");
364 return audioRenderer_->Pause();
365 }
366 FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() != AudioStandard::RendererState::RENDERER_STOPPED,
367 true, "AudioRenderer is already in stopped state.");
368 sliceCount_++;
369 return audioRenderer_->Stop();
370 }
371 return true;
372 }
373
Reset()374 Status AudioServerSinkPlugin::Reset()
375 {
376 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Reset");
377 MEDIA_LOG_I_T("Reset entered.");
378 FALSE_RETURN_V_MSG(StopRender(), Status::ERROR_UNKNOWN, "stop render error");
379 ResetAudioRendererParams(rendererParams_);
380 fmtSupported_ = false;
381 reSrcFfFmt_ = AV_SAMPLE_FMT_NONE;
382 channels_ = 0;
383 bitRate_ = 0;
384 sampleRate_ = 0;
385 samplesPerFrame_ = 0;
386 needReformat_ = false;
387 if (resample_) {
388 resample_.reset();
389 }
390 return Status::OK;
391 }
392
Start()393 Status AudioServerSinkPlugin::Start()
394 {
395 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Start");
396 MEDIA_LOG_D_T("Start entered.");
397 if (audioRenderer_ == nullptr) {
398 return Status::ERROR_WRONG_STATE;
399 }
400 bool ret = audioRenderer_->Start();
401 FALSE_RETURN_V_MSG(ret, Status::ERROR_UNKNOWN, "AudioRenderer::Start failed");
402 MEDIA_LOG_I_T("AudioRenderer::Start end");
403 return Status::OK;
404 }
405
Stop()406 Status AudioServerSinkPlugin::Stop()
407 {
408 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Stop");
409 MEDIA_LOG_D_T("Stop entered.");
410 FALSE_RETURN_V_MSG(StopRender(), Status::ERROR_UNKNOWN, "stop render failed");
411 MEDIA_LOG_I_T("stop render success");
412 return Status::OK;
413 }
414
SetVolumeWithRamp(float targetVolume,int32_t duration)415 int32_t AudioServerSinkPlugin::SetVolumeWithRamp(float targetVolume, int32_t duration)
416 {
417 MEDIA_LOG_D_T("SetVolumeWithRamp entered.");
418 int32_t ret = 0;
419 {
420 if (audioRenderer_ == nullptr) {
421 return 0;
422 }
423 if (duration == 0) {
424 ret = audioRenderer_->SetVolume(targetVolume);
425 } else {
426 MEDIA_LOG_I_T("plugin set vol AudioRenderer::SetVolumeWithRamp start");
427 ret = audioRenderer_->SetVolumeWithRamp(targetVolume, duration);
428 MEDIA_LOG_I_T("plugin set vol AudioRenderer::SetVolumeWithRamp end");
429 }
430 }
431 OHOS::Media::SleepInJob(duration + 40); // fade out sleep more 40 ms
432 MEDIA_LOG_I_T("SetVolumeWithRamp end.");
433 return ret;
434 }
435
GetParameter(std::shared_ptr<Meta> & meta)436 Status AudioServerSinkPlugin::GetParameter(std::shared_ptr<Meta> &meta)
437 {
438 AudioStandard::AudioRendererParams params;
439 meta->Set<Tag::MEDIA_BITRATE>(bitRate_);
440 if (audioRenderer_ && audioRenderer_->GetParams(params) == AudioStandard::SUCCESS) {
441 MEDIA_LOG_I_T("get param with fmt " PUBLIC_LOG_D32 " sampleRate " PUBLIC_LOG_D32 " channel " PUBLIC_LOG_D32
442 " encode type " PUBLIC_LOG_D32,
443 params.sampleFormat, params.sampleRate, params.channelCount, params.encodingType);
444 if (params.sampleRate != rendererParams_.sampleRate) {
445 MEDIA_LOG_W("samplingRate has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
446 rendererParams_.sampleRate, params.sampleRate);
447 }
448 meta->Set<Tag::AUDIO_SAMPLE_RATE>(params.sampleRate);
449 if (params.sampleFormat != rendererParams_.sampleFormat) {
450 MEDIA_LOG_W("sampleFormat has changed from " PUBLIC_LOG_U32 " to " PUBLIC_LOG_U32,
451 rendererParams_.sampleFormat, params.sampleFormat);
452 }
453 for (const auto &item : g_aduFmtMap) {
454 if (std::get<1>(item) == params.sampleFormat) {
455 meta->Set<Tag::AUDIO_SAMPLE_FORMAT>(std::get<0>(item));
456 }
457 }
458 }
459 return Status::OK;
460 }
461
AssignSampleRateIfSupported(uint32_t sampleRate)462 bool AudioServerSinkPlugin::AssignSampleRateIfSupported(uint32_t sampleRate)
463 {
464 sampleRate_ = sampleRate;
465 auto supportedSampleRateList = OHOS::AudioStandard::AudioRenderer::GetSupportedSamplingRates();
466 FALSE_RETURN_V_MSG(!supportedSampleRateList.empty(), false, "GetSupportedSamplingRates fail");
467 for (const auto &rate : supportedSampleRateList) {
468 if (static_cast<uint32_t>(rate) == sampleRate) {
469 rendererParams_.sampleRate = rate;
470 MEDIA_LOG_D_T("sampleRate: " PUBLIC_LOG_U32, rendererParams_.sampleRate);
471 return true;
472 }
473 }
474 MEDIA_LOG_E_T("sample rate " PUBLIC_LOG_U32 "not supported", sampleRate);
475 return false;
476 }
477
AssignChannelNumIfSupported(uint32_t channelNum)478 bool AudioServerSinkPlugin::AssignChannelNumIfSupported(uint32_t channelNum)
479 {
480 auto supportedChannelsList = OHOS::AudioStandard::AudioRenderer::GetSupportedChannels();
481 FALSE_RETURN_V_MSG(!supportedChannelsList.empty(), false, "GetSupportedChannels fail");
482 for (const auto &channel : supportedChannelsList) {
483 if (static_cast<uint32_t>(channel) == channelNum) {
484 rendererParams_.channelCount = channel;
485 MEDIA_LOG_D_T("channelCount: " PUBLIC_LOG_U32, rendererParams_.channelCount);
486 return true;
487 }
488 }
489 MEDIA_LOG_E_T("channel num " PUBLIC_LOG_U32 "not supported", channelNum);
490 return false;
491 }
492
AssignSampleFmtIfSupported(Plugins::AudioSampleFormat sampleFormat)493 bool AudioServerSinkPlugin::AssignSampleFmtIfSupported(Plugins::AudioSampleFormat sampleFormat)
494 {
495 MEDIA_LOG_I_T("AssignSampleFmtIfSupported AudioSampleFormat " PUBLIC_LOG_D32, sampleFormat);
496 const auto &item = std::find_if(g_aduFmtMap.begin(), g_aduFmtMap.end(), [&sampleFormat](const auto &tmp) -> bool {
497 return std::get<0>(tmp) == sampleFormat;
498 });
499 auto stdFmt = std::get<1>(*item);
500 if (stdFmt == OHOS::AudioStandard::AudioSampleFormat::INVALID_WIDTH) {
501 if (std::get<2>(*item) == AV_SAMPLE_FMT_NONE) { // 2
502 MEDIA_LOG_I_T("AssignSampleFmtIfSupported AV_SAMPLE_FMT_NONE");
503 fmtSupported_ = false;
504 } else {
505 MEDIA_LOG_I_T("AssignSampleFmtIfSupported needReformat_");
506 fmtSupported_ = true;
507 needReformat_ = true;
508 reSrcFfFmt_ = std::get<2>(*item); // 2
509 rendererParams_.sampleFormat = reStdDestFmt_;
510 }
511 } else {
512 auto supportedFmts = OHOS::AudioStandard::AudioRenderer::GetSupportedFormats();
513 if (CppExt::AnyOf(supportedFmts.begin(), supportedFmts.end(),
514 [&stdFmt](const auto &tmp) -> bool { return tmp == stdFmt; })) {
515 MEDIA_LOG_I_T("AssignSampleFmtIfSupported needReformat_ false");
516 fmtSupported_ = true;
517 needReformat_ = false;
518 } else {
519 fmtSupported_ = false;
520 needReformat_ = false;
521 }
522 rendererParams_.sampleFormat = stdFmt;
523 }
524 return fmtSupported_;
525 }
526
SetInterruptMode(AudioStandard::InterruptMode interruptMode)527 void AudioServerSinkPlugin::SetInterruptMode(AudioStandard::InterruptMode interruptMode)
528 {
529 if (audioRenderer_) {
530 audioRenderer_->SetInterruptMode(interruptMode);
531 }
532 }
533
SetUpParamsSetterMap()534 void AudioServerSinkPlugin::SetUpParamsSetterMap()
535 {
536 SetUpMimeTypeSetter();
537 SetUpSampleRateSetter();
538 SetUpAudioOutputChannelsSetter();
539 SetUpMediaBitRateSetter();
540 SetUpAudioSampleFormatSetter();
541 SetUpAudioOutputChannelLayoutSetter();
542 SetUpAudioSamplePerFrameSetter();
543 SetUpBitsPerCodedSampleSetter();
544 SetUpMediaSeekableSetter();
545 SetUpAppPidSetter();
546 SetUpAppUidSetter();
547 SetUpAudioRenderInfoSetter();
548 SetUpAudioRenderSetFlagSetter();
549 SetUpAudioInterruptModeSetter();
550 }
551
SetUpMimeTypeSetter()552 void AudioServerSinkPlugin::SetUpMimeTypeSetter()
553 {
554 paramsSetterMap_[Tag::MIME_TYPE] = [this](const ValueType ¶) {
555 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<std::string>(para), Status::ERROR_MISMATCHED_TYPE,
556 "mimeType type should be string");
557 mimeType_ = AnyCast<std::string>(para);
558 MEDIA_LOG_I_T("Set mimeType: " PUBLIC_LOG_S, mimeType_.c_str());
559 return Status::OK;
560 };
561 }
562
SetUpSampleRateSetter()563 void AudioServerSinkPlugin::SetUpSampleRateSetter()
564 {
565 paramsSetterMap_[Tag::AUDIO_SAMPLE_RATE] = [this](const ValueType ¶) {
566 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
567 "sample rate type should be int32_t");
568 if (!AssignSampleRateIfSupported(AnyCast<int32_t>(para))) {
569 MEDIA_LOG_E_T("sampleRate isn't supported");
570 playerEventReceiver_->OnEvent({"sampleRate isn't supported",
571 EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_SAMPLE_RATE});
572 return Status::ERROR_INVALID_PARAMETER;
573 }
574 return Status::OK;
575 };
576 }
577
SetUpAudioOutputChannelsSetter()578 void AudioServerSinkPlugin::SetUpAudioOutputChannelsSetter()
579 {
580 paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNELS] = [this](const ValueType ¶) {
581 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
582 "channels type should be int32_t");
583 channels_ = AnyCast<uint32_t>(para);
584 MEDIA_LOG_I_T("Set outputChannels: " PUBLIC_LOG_U32, channels_);
585 if (!AssignChannelNumIfSupported(channels_)) {
586 MEDIA_LOG_E_T("channel isn't supported");
587 playerEventReceiver_->OnEvent({"channel isn't supported",
588 EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_CHANNEL_NUM});
589 return Status::ERROR_INVALID_PARAMETER;
590 }
591 return Status::OK;
592 };
593 }
594
SetUpMediaBitRateSetter()595 void AudioServerSinkPlugin::SetUpMediaBitRateSetter()
596 {
597 paramsSetterMap_[Tag::MEDIA_BITRATE] = [this](const ValueType ¶) {
598 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int64_t>(para), Status::ERROR_MISMATCHED_TYPE,
599 "bit rate type should be int64_t");
600 bitRate_ = AnyCast<int64_t>(para);
601 return Status::OK;
602 };
603 }
SetUpAudioSampleFormatSetter()604 void AudioServerSinkPlugin::SetUpAudioSampleFormatSetter()
605 {
606 paramsSetterMap_[Tag::AUDIO_SAMPLE_FORMAT] = [this](const ValueType ¶) {
607 MEDIA_LOG_I_T("SetUpAudioSampleFormat");
608 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioSampleFormat>(para), Status::ERROR_MISMATCHED_TYPE,
609 "AudioSampleFormat type should be AudioSampleFormat");
610 if (!AssignSampleFmtIfSupported(AnyCast<AudioSampleFormat>(para))) {
611 MEDIA_LOG_E_T("sampleFmt isn't supported by audio renderer or resample lib");
612 playerEventReceiver_->OnEvent({"sampleFmt isn't supported",
613 EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_PARAMS});
614 return Status::ERROR_INVALID_PARAMETER;
615 }
616 return Status::OK;
617 };
618 }
SetUpAudioOutputChannelLayoutSetter()619 void AudioServerSinkPlugin::SetUpAudioOutputChannelLayoutSetter()
620 {
621 paramsSetterMap_[Tag::AUDIO_OUTPUT_CHANNEL_LAYOUT] = [this](const ValueType ¶) {
622 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioChannelLayout>(para), Status::ERROR_MISMATCHED_TYPE,
623 "channel layout type should be AudioChannelLayout");
624 channelLayout_ = AnyCast<AudioChannelLayout>(para);
625 MEDIA_LOG_I_T("Set outputChannelLayout: " PUBLIC_LOG_U64, channelLayout_);
626 return Status::OK;
627 };
628 }
SetUpAudioSamplePerFrameSetter()629 void AudioServerSinkPlugin::SetUpAudioSamplePerFrameSetter()
630 {
631 paramsSetterMap_[Tag::AUDIO_SAMPLE_PER_FRAME] = [this](const ValueType ¶) {
632 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
633 "SAMPLE_PER_FRAME type should be int32_t");
634 samplesPerFrame_ = AnyCast<uint32_t>(para);
635 return Status::OK;
636 };
637 }
SetUpBitsPerCodedSampleSetter()638 void AudioServerSinkPlugin::SetUpBitsPerCodedSampleSetter()
639 {
640 paramsSetterMap_[Tag::AUDIO_BITS_PER_CODED_SAMPLE] = [this](const ValueType ¶) {
641 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
642 "BITS_PER_CODED_SAMPLE type should be int32_t");
643 bitsPerSample_ = AnyCast<uint32_t>(para);
644 return Status::OK;
645 };
646 }
SetUpMediaSeekableSetter()647 void AudioServerSinkPlugin::SetUpMediaSeekableSetter()
648 {
649 paramsSetterMap_[Tag::MEDIA_SEEKABLE] = [this](const ValueType ¶) {
650 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<Seekable>(para), Status::ERROR_MISMATCHED_TYPE,
651 "MEDIA_SEEKABLE type should be Seekable");
652 seekable_ = AnyCast<Plugins::Seekable>(para);
653 return Status::OK;
654 };
655 }
SetUpAppPidSetter()656 void AudioServerSinkPlugin::SetUpAppPidSetter()
657 {
658 paramsSetterMap_[Tag::APP_PID] = [this](const ValueType ¶) {
659 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
660 "APP_PID type should be int32_t");
661 appPid_ = AnyCast<int32_t>(para);
662 return Status::OK;
663 };
664 }
SetUpAppUidSetter()665 void AudioServerSinkPlugin::SetUpAppUidSetter()
666 {
667 paramsSetterMap_[Tag::APP_UID] = [this](const ValueType ¶) {
668 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
669 "APP_UID type should be int32_t");
670 appUid_ = AnyCast<int32_t>(para);
671 return Status::OK;
672 };
673 }
SetUpAudioRenderInfoSetter()674 void AudioServerSinkPlugin::SetUpAudioRenderInfoSetter()
675 {
676 paramsSetterMap_[Tag::AUDIO_RENDER_INFO] = [this](const ValueType ¶) {
677 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<AudioRenderInfo>(para), Status::ERROR_MISMATCHED_TYPE,
678 "AUDIO_RENDER_INFO type should be AudioRenderInfo");
679 audioRenderInfo_ = AnyCast<AudioRenderInfo>(para);
680 return Status::OK;
681 };
682 }
683
SetUpAudioRenderSetFlagSetter()684 void AudioServerSinkPlugin::SetUpAudioRenderSetFlagSetter()
685 {
686 paramsSetterMap_[Tag::AUDIO_RENDER_SET_FLAG] = [this](const ValueType ¶) {
687 if (!Any::IsSameTypeWith<bool>(para)) {
688 MEDIA_LOG_E_T("AUDIO_RENDER_SET_FLAG type should be bool");
689 playerEventReceiver_->OnEvent({"AUDIO_RENDER_SET_FLAG type is not bool",
690 EventType::EVENT_ERROR, MSERR_EXT_API9_INVALID_PARAMETER});
691 return Status::ERROR_MISMATCHED_TYPE;
692 }
693 audioRenderSetFlag_ = AnyCast<bool>(para);
694 return Status::OK;
695 };
696 }
697
SetUpAudioInterruptModeSetter()698 void AudioServerSinkPlugin::SetUpAudioInterruptModeSetter()
699 {
700 paramsSetterMap_[Tag::AUDIO_INTERRUPT_MODE] = [this](const ValueType ¶) {
701 FALSE_RETURN_V_MSG_E(Any::IsSameTypeWith<int32_t>(para), Status::ERROR_MISMATCHED_TYPE,
702 "AUDIO_INTERRUPT_MODE type should be int32_t");
703 AudioInterruptMode2InterruptMode(AnyCast<AudioInterruptMode>(para), audioInterruptMode_);
704 SetInterruptMode(audioInterruptMode_);
705 return Status::OK;
706 };
707 }
708
SetParameter(const std::shared_ptr<Meta> & meta)709 Status AudioServerSinkPlugin::SetParameter(const std::shared_ptr<Meta> &meta)
710 {
711 for (MapIt iter = meta->begin(); iter != meta->end(); iter++) {
712 MEDIA_LOG_D_T("SetParameter iter->first " PUBLIC_LOG_S, iter->first.c_str());
713 if (paramsSetterMap_.find(iter->first) == paramsSetterMap_.end()) {
714 continue;
715 }
716 std::function<Status(const ValueType ¶)> paramSetter = paramsSetterMap_[iter->first];
717 paramSetter(iter->second);
718 }
719 return Status::OK;
720 }
721
GetVolume(float & volume)722 Status AudioServerSinkPlugin::GetVolume(float &volume)
723 {
724 MEDIA_LOG_I_T("GetVolume entered.");
725 if (audioRenderer_ != nullptr) {
726 volume = audioRenderer_->GetVolume();
727 return Status::OK;
728 }
729 return Status::ERROR_WRONG_STATE;
730 }
731
SetVolume(float volume)732 Status AudioServerSinkPlugin::SetVolume(float volume)
733 {
734 MEDIA_LOG_D("SetVolume entered.");
735 if (audioRenderer_ != nullptr) {
736 int32_t ret = audioRenderer_->SetVolume(volume);
737 FALSE_RETURN_V_MSG_E(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
738 "set volume failed with code " PUBLIC_LOG_D32, ret);
739 MEDIA_LOG_D("SetVolume succ");
740 audioRendererVolume_ = volume;
741 return Status::OK;
742 }
743 return Status::ERROR_WRONG_STATE;
744 }
745
GetAudioEffectMode(int32_t & effectMode)746 Status AudioServerSinkPlugin::GetAudioEffectMode(int32_t &effectMode)
747 {
748 MEDIA_LOG_I_T("GetAudioEffectMode entered.");
749 if (audioRenderer_ != nullptr) {
750 effectMode = audioRenderer_->GetAudioEffectMode();
751 MEDIA_LOG_I_T("GetAudioEffectMode %{public}d", effectMode);
752 return Status::OK;
753 }
754 return Status::ERROR_WRONG_STATE;
755 }
756
SetAudioEffectMode(int32_t effectMode)757 Status AudioServerSinkPlugin::SetAudioEffectMode(int32_t effectMode)
758 {
759 MEDIA_LOG_I_T("SetAudioEffectMode %{public}d", effectMode);
760 if (audioRenderer_ != nullptr) {
761 int32_t ret = audioRenderer_->SetAudioEffectMode(static_cast<OHOS::AudioStandard::AudioEffectMode>(effectMode));
762 FALSE_RETURN_V_MSG(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
763 "set AudioEffectMode failed with code " PUBLIC_LOG_D32, ret);
764 return Status::OK;
765 }
766 return Status::ERROR_WRONG_STATE;
767 }
768
GetSpeed(float & speed)769 Status AudioServerSinkPlugin::GetSpeed(float &speed)
770 {
771 MEDIA_LOG_I_T("GetSpeed entered.");
772 if (audioRenderer_ != nullptr) {
773 speed = audioRenderer_->GetSpeed();
774 return Status::OK;
775 }
776 return Status::ERROR_WRONG_STATE;
777 }
778
SetSpeed(float speed)779 Status AudioServerSinkPlugin::SetSpeed(float speed)
780 {
781 MEDIA_LOG_I_T("SetSpeed entered.");
782 if (audioRenderer_ != nullptr) {
783 int32_t ret = audioRenderer_->SetSpeed(speed);
784 FALSE_RETURN_V_MSG(ret == OHOS::AudioStandard::SUCCESS, Status::ERROR_UNKNOWN,
785 "set speed failed with code " PUBLIC_LOG_D32, ret);
786 return Status::OK;
787 }
788 return Status::ERROR_WRONG_STATE;
789 }
790
Resume()791 Status AudioServerSinkPlugin::Resume()
792 {
793 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Resume");
794 MEDIA_LOG_D_T("Resume entered");
795 return Start();
796 }
797
Pause()798 Status AudioServerSinkPlugin::Pause()
799 {
800 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Pause");
801 MEDIA_LOG_I_T("Pause entered");
802 FALSE_RETURN_V_MSG(audioRenderer_ != nullptr, Status::ERROR_UNKNOWN, "audio renderer pause fail");
803 FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING,
804 Status::OK, "audio renderer no need pause");
805 sliceCount_++;
806 FALSE_RETURN_V_MSG_W(audioRenderer_->Pause(), Status::ERROR_UNKNOWN, "renderer pause fail.");
807 MEDIA_LOG_I_T("audio renderer pause success");
808 return Status::OK;
809 }
810
PauseTransitent()811 Status AudioServerSinkPlugin::PauseTransitent()
812 {
813 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::PauseTransitent");
814 MEDIA_LOG_I_T("PauseTransitent entered.");
815 FALSE_RETURN_V_MSG(audioRenderer_ != nullptr, Status::ERROR_UNKNOWN, "audio renderer pauseTransitent fail");
816 FALSE_RETURN_V_MSG(audioRenderer_->GetStatus() == OHOS::AudioStandard::RENDERER_RUNNING,
817 Status::OK, "audio renderer no need pauseTransitent");
818 sliceCount_++;
819 FALSE_RETURN_V_MSG_W(audioRenderer_->PauseTransitent(), Status::ERROR_UNKNOWN, "renderer pauseTransitent fail.");
820 MEDIA_LOG_I_T("audio renderer pauseTransitent success");
821 return Status::OK;
822 }
823
GetLatency(uint64_t & hstTime)824 Status AudioServerSinkPlugin::GetLatency(uint64_t &hstTime)
825 {
826 FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
827 audioRenderer_->GetLatency(hstTime); // audioRender->getLatency lack accuracy
828 return Status::OK;
829 }
830
DrainCacheData(bool render)831 Status AudioServerSinkPlugin::DrainCacheData(bool render)
832 {
833 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::DrainCacheData " + std::to_string(render));
834 if (!render) {
835 MEDIA_LOG_D("Drop cache buffer because render=false");
836 cachedBuffers_.clear();
837 return Status::OK;
838 }
839 if (cachedBuffers_.empty()) {
840 return Status::OK;
841 }
842 AudioStandard::RendererState rendererState = (audioRenderer_ != nullptr) ?
843 audioRenderer_->GetStatus() : AudioStandard::RendererState::RENDERER_INVALID;
844 FALSE_RETURN_V_MSG(rendererState != AudioStandard::RendererState::RENDERER_PAUSED,
845 Status::ERROR_AGAIN, "audioRenderer_ is still paused, try again later");
846 if (rendererState != AudioStandard::RendererState::RENDERER_RUNNING) {
847 cachedBuffers_.clear();
848 MEDIA_LOG_W("Drop cache buffer because audioRenderer_ state invalid");
849 return Status::ERROR_UNKNOWN;
850 }
851 while (cachedBuffers_.size() > 0) { // do drain cache buffers
852 auto currBuffer = cachedBuffers_.front();
853 uint8_t* destBuffer = currBuffer.data();
854 size_t destLength = currBuffer.size();
855 bool shouldDrop = false;
856 size_t remained = WriteAudioBuffer(destBuffer, destLength, shouldDrop);
857 if (remained == 0) { // write ok
858 cachedBuffers_.pop_front();
859 continue;
860 }
861 if (shouldDrop) { // write error and drop buffer
862 cachedBuffers_.clear();
863 MEDIA_LOG_W("Drop cache buffer, error happens during drain");
864 return Status::ERROR_UNKNOWN;
865 }
866 if (remained < destLength) { // some data written, then audioRender paused again, update cache
867 std::vector<uint8_t> tmpBuffer(destBuffer + destLength - remained, destBuffer + destLength);
868 cachedBuffers_.pop_front();
869 cachedBuffers_.emplace_front(std::move(tmpBuffer));
870 } // else no data written, no need to update front cache
871 MEDIA_LOG_W("Audiorender pause again during drain cache buffers");
872 return Status::ERROR_AGAIN;
873 }
874 MEDIA_LOG_I("Drain cache buffer success");
875 return Status::OK;
876 }
877
CacheData(uint8_t * inputBuffer,size_t bufferSize)878 void AudioServerSinkPlugin::CacheData(uint8_t* inputBuffer, size_t bufferSize)
879 {
880 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::CacheData " + std::to_string(bufferSize));
881 std::vector<uint8_t> tmpBuffer(inputBuffer, inputBuffer + bufferSize);
882 cachedBuffers_.emplace_back(std::move(tmpBuffer));
883 MEDIA_LOG_I("Cache one audio buffer, data size is " PUBLIC_LOG_U64, bufferSize);
884 while (cachedBuffers_.size() > DEFAULT_BUFFER_NUM) {
885 auto dropSize = cachedBuffers_.front().size();
886 MEDIA_LOG_W("Drop one cached buffer size " PUBLIC_LOG_U64 " because max cache size reached.", dropSize);
887 cachedBuffers_.pop_front();
888 }
889 }
890
WriteAudioBuffer(uint8_t * inputBuffer,size_t bufferSize,bool & shouldDrop)891 size_t AudioServerSinkPlugin::WriteAudioBuffer(uint8_t* inputBuffer, size_t bufferSize, bool& shouldDrop)
892 {
893 uint8_t* destBuffer = inputBuffer;
894 size_t destLength = bufferSize;
895 while (destLength > 0) {
896 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::WriteAudioBuffer: " + std::to_string(destLength));
897 auto systemTimeBeforeWriteMs = Plugins::GetCurrentMillisecond();
898 int32_t ret = audioRenderer_->Write(destBuffer, destLength);
899 writeDuration_ = std::max(Plugins::GetCurrentMillisecond() - systemTimeBeforeWriteMs, writeDuration_);
900 if (ret < 0) {
901 if (audioRenderer_->GetStatus() == AudioStandard::RendererState::RENDERER_PAUSED) {
902 MEDIA_LOG_W("WriteAudioBuffer error because audioRenderer_ paused, cache data.");
903 shouldDrop = false;
904 } else {
905 MEDIA_LOG_W("WriteAudioBuffer error because audioRenderer_ error, drop data.");
906 shouldDrop = true;
907 }
908 break;
909 } else if (static_cast<size_t>(ret) < destLength) {
910 OHOS::Media::SleepInJob(5); // 5ms
911 }
912 if (static_cast<size_t>(ret) > destLength) {
913 MEDIA_LOG_W("audioRenderer_ return ret " PUBLIC_LOG_D32 "> destLength " PUBLIC_LOG_U64,
914 ret, destLength);
915 ret = static_cast<int32_t>(destLength);
916 }
917 destBuffer += ret;
918 destLength -= static_cast<size_t>(ret);
919 MEDIA_LOG_D("Written data size " PUBLIC_LOG_D32 ", bufferSize " PUBLIC_LOG_U64, ret, bufferSize);
920 }
921 return destLength;
922 }
923
Write(const std::shared_ptr<OHOS::Media::AVBuffer> & inputBuffer)924 Status AudioServerSinkPlugin::Write(const std::shared_ptr<OHOS::Media::AVBuffer> &inputBuffer)
925 {
926 MEDIA_LOG_D_T("Write buffer to audio framework");
927 FALSE_RETURN_V_MSG_W(inputBuffer != nullptr && inputBuffer->memory_->GetSize() != 0, Status::OK,
928 "Receive empty buffer."); // return ok
929 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::Write, bufferSize: "
930 + std::to_string(inputBuffer->memory_->GetSize()));
931 int32_t ret = 0;
932 if (mimeType_ == MimeType::AUDIO_AVS3DA) {
933 ret = WriteAudioVivid(inputBuffer);
934 return ret >= 0 ? Status::OK : Status::ERROR_UNKNOWN;
935 }
936 auto mem = inputBuffer->memory_;
937 auto srcBuffer = mem->GetAddr();
938 auto destBuffer = const_cast<uint8_t *>(srcBuffer);
939 auto srcLength = mem->GetSize();
940 size_t destLength = static_cast<size_t>(srcLength);
941 while (isForcePaused_ && seekable_ == Seekable::SEEKABLE) {
942 OHOS::Media::SleepInJob(5); // 5ms
943 }
944 if (audioRenderer_ == nullptr) {
945 DrainCacheData(false);
946 return Status::ERROR_NULL_POINTER;
947 }
948 auto drainCacheRet = DrainCacheData(true);
949 if (drainCacheRet != Status::OK) {
950 if (drainCacheRet == Status::ERROR_AGAIN) {
951 CacheData(destBuffer, destLength);
952 }
953 return Status::ERROR_UNKNOWN;
954 }
955 bool shouldDrop = false;
956 size_t remained = WriteAudioBuffer(destBuffer, destLength, shouldDrop);
957 if (remained == 0) {
958 return Status::OK;
959 }
960 if (!shouldDrop) {
961 CacheData(destBuffer + destLength - remained, remained);
962 }
963 return Status::ERROR_UNKNOWN;
964 }
965
WriteAudioVivid(const std::shared_ptr<OHOS::Media::AVBuffer> & inputBuffer)966 int32_t AudioServerSinkPlugin::WriteAudioVivid(const std::shared_ptr<OHOS::Media::AVBuffer> &inputBuffer)
967 {
968 MediaAVCodec::AVCodecTrace trace("AudioServerSinkPlugin::WriteAudioVivid");
969 auto mem = inputBuffer->memory_;
970 auto pcmBuffer = mem->GetAddr();
971 auto pcmBufferSize = mem->GetSize();
972 auto meta = inputBuffer->meta_;
973 std::vector<uint8_t> metaData;
974 meta->GetData(Tag::OH_MD_KEY_AUDIO_VIVID_METADATA, metaData);
975 FALSE_RETURN_V(audioRenderer_ != nullptr, -1);
976 return audioRenderer_->Write(pcmBuffer, pcmBufferSize, metaData.data(), metaData.size());
977 }
978
Flush()979 Status AudioServerSinkPlugin::Flush()
980 {
981 MEDIA_LOG_I_T("Flush entered.");
982 DrainCacheData(false);
983 if (audioRenderer_ == nullptr) {
984 return Status::ERROR_WRONG_STATE;
985 }
986 if (audioRenderer_->Flush()) {
987 MEDIA_LOG_D_T("flush renderer success");
988 return Status::OK;
989 }
990 MEDIA_LOG_E_T("flush renderer fail");
991 return Status::ERROR_UNKNOWN;
992 }
993
Drain()994 Status AudioServerSinkPlugin::Drain()
995 {
996 MEDIA_LOG_I_T("Drain entered.");
997 if (audioRenderer_ == nullptr) {
998 DrainCacheData(false);
999 return Status::ERROR_WRONG_STATE;
1000 }
1001 DrainCacheData(true); // try to drain
1002 cachedBuffers_.clear(); // force clear cached data, no matter drain success or not
1003 if (!audioRenderer_->Drain()) {
1004 uint64_t latency = 0;
1005 audioRenderer_->GetLatency(latency);
1006 latency /= 1000; // 1000 cast into ms
1007 if (latency > 50) { // 50 latency too large
1008 MEDIA_LOG_W("Drain failed and latency is too large, will sleep " PUBLIC_LOG_U64 " ms, aka. latency.",
1009 latency);
1010 OHOS::Media::SleepInJob(latency);
1011 }
1012 }
1013 MEDIA_LOG_I_T("drain renderer success");
1014 return Status::OK;
1015 }
1016
GetPlayedOutDurationUs(int64_t nowUs)1017 int64_t AudioServerSinkPlugin::GetPlayedOutDurationUs(int64_t nowUs)
1018 {
1019 FALSE_RETURN_V(audioRenderer_ != nullptr && rendererParams_.sampleRate != 0, -1);
1020 uint32_t numFramesPlayed = 0;
1021 AudioStandard::Timestamp ts;
1022 bool res = audioRenderer_->GetAudioTime(ts, AudioStandard::Timestamp::Timestampbase::MONOTONIC);
1023 if (res) {
1024 numFramesPlayed = ts.framePosition;
1025 }
1026 return numFramesPlayed;
1027 }
1028
GetFramePosition(int32_t & framePosition)1029 Status AudioServerSinkPlugin::GetFramePosition(int32_t &framePosition)
1030 {
1031 AudioStandard::Timestamp ts;
1032 if (audioRenderer_ == nullptr) {
1033 return Status::ERROR_WRONG_STATE;
1034 }
1035 bool res = audioRenderer_->GetAudioTime(ts, AudioStandard::Timestamp::Timestampbase::MONOTONIC);
1036 if (!res) {
1037 return Status::ERROR_UNKNOWN;
1038 }
1039 framePosition = static_cast<int32_t>(ts.framePosition);
1040 return Status::OK;
1041 }
1042
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)1043 void AudioServerSinkPlugin::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver>& receiver)
1044 {
1045 FALSE_RETURN(receiver != nullptr);
1046 playerEventReceiver_ = receiver;
1047 }
1048
SetAudioDumpBySysParam()1049 void AudioServerSinkPlugin::SetAudioDumpBySysParam()
1050 {
1051 std::string dumpAllEnable;
1052 enableEntireDump_ = false;
1053 int32_t dumpAllRes = OHOS::system::GetStringParameter("sys.media.sink.entiredump.enable", dumpAllEnable, "");
1054 if (dumpAllRes == 0 && !dumpAllEnable.empty() && dumpAllEnable == "true") {
1055 enableEntireDump_ = true;
1056 }
1057 std::string dumpSliceEnable;
1058 enableDumpSlice_ = false;
1059 int32_t sliceDumpRes = OHOS::system::GetStringParameter("sys.media.sink.slicedump.enable", dumpSliceEnable, "");
1060 if (sliceDumpRes == 0 && !dumpSliceEnable.empty() && dumpSliceEnable == "true") {
1061 enableDumpSlice_ = true;
1062 }
1063 MEDIA_LOG_D_T("sys.media.sink.entiredump.enable: " PUBLIC_LOG_S ", sys.media.sink.slicedump.enable: "
1064 PUBLIC_LOG_S, dumpAllEnable.c_str(), dumpSliceEnable.c_str());
1065 }
1066
DumpEntireAudioBuffer(uint8_t * buffer,const size_t & bytesSingle)1067 void AudioServerSinkPlugin::DumpEntireAudioBuffer(uint8_t* buffer, const size_t& bytesSingle)
1068 {
1069 if (!enableEntireDump_) {
1070 return;
1071 }
1072
1073 if (entireDumpFile_ == nullptr) {
1074 std::string path = "data/media/audio-sink-entire.pcm";
1075 entireDumpFile_ = fopen(path.c_str(), "wb+");
1076 }
1077 if (entireDumpFile_ == nullptr) {
1078 return;
1079 }
1080 (void)fwrite(buffer, bytesSingle, 1, entireDumpFile_);
1081 (void)fflush(entireDumpFile_);
1082 }
1083
DumpSliceAudioBuffer(uint8_t * buffer,const size_t & bytesSingle)1084 void AudioServerSinkPlugin::DumpSliceAudioBuffer(uint8_t* buffer, const size_t& bytesSingle)
1085 {
1086 if (!enableDumpSlice_) {
1087 return;
1088 }
1089
1090 if (curCount_ != sliceCount_) {
1091 curCount_ = sliceCount_;
1092 if (sliceDumpFile_ != nullptr) {
1093 (void)fclose(sliceDumpFile_);
1094 }
1095 std::string path = "data/media/audio-sink-slice-" + std::to_string(sliceCount_) + ".pcm";
1096 sliceDumpFile_ = fopen(path.c_str(), "wb+");
1097 }
1098 if (sliceDumpFile_ == nullptr) {
1099 return;
1100 }
1101 (void)fwrite(buffer, bytesSingle, 1, sliceDumpFile_);
1102 (void)fflush(sliceDumpFile_);
1103 }
1104
SetMuted(bool isMuted)1105 Status AudioServerSinkPlugin::SetMuted(bool isMuted)
1106 {
1107 FALSE_RETURN_V(audioRenderer_ != nullptr, Status::ERROR_NULL_POINTER);
1108 MEDIA_LOG_D("SetMuted in");
1109 audioRenderer_->SetSilentModeAndMixWithOthers(isMuted);
1110 MEDIA_LOG_I("SetMuted out");
1111 return Status::OK;
1112 }
1113
GetWriteDurationMs()1114 int64_t AudioServerSinkPlugin::GetWriteDurationMs()
1115 {
1116 int64_t writeDuration = writeDuration_;
1117 writeDuration_ = 0;
1118 return writeDuration;
1119 }
1120 } // namespace Plugin
1121 } // namespace Media
1122 } // namespace OHOS
1123