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