1
2 /*
3 * Copyright (C) 2023 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "cache_buffer.h"
18 #include "media_log.h"
19 #include "media_errors.h"
20 #include "securec.h"
21 #include "audio_renderer_manager.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "CacheBuffer"};
25 static const int32_t ERROE_GLOBAL_ID = -1;
26 }
27
28 namespace OHOS {
29 namespace Media {
CacheBuffer(const Format & trackFormat,const int32_t & soundID,const int32_t & streamID,std::shared_ptr<ThreadPool> cacheBufferStopThreadPool)30 CacheBuffer::CacheBuffer(const Format &trackFormat, const int32_t &soundID, const int32_t &streamID,
31 std::shared_ptr<ThreadPool> cacheBufferStopThreadPool) : trackFormat_(trackFormat),
32 soundID_(soundID), streamID_(streamID), cacheBufferStopThreadPool_(cacheBufferStopThreadPool),
33 cacheDataFrameIndex_(0), havePlayedCount_(0)
34 {
35 MEDIA_LOGI("Construction CacheBuffer soundID:%{public}d, streamID:%{public}d", soundID, streamID);
36 }
37
~CacheBuffer()38 CacheBuffer::~CacheBuffer()
39 {
40 MEDIA_LOGI("Destruction CacheBuffer soundID:%{public}d, streamID:%{public}d", soundID_, streamID_);
41 Release();
42 }
43
SetSoundData(const std::shared_ptr<AudioBufferEntry> & cacheData,const size_t & cacheDataTotalSize)44 void CacheBuffer::SetSoundData(const std::shared_ptr<AudioBufferEntry> &cacheData, const size_t &cacheDataTotalSize)
45 {
46 fullCacheData_ = cacheData;
47 cacheDataTotalSize_ = cacheDataTotalSize;
48 }
49
SetManager(std::weak_ptr<StreamIDManager> streamIDManager)50 void CacheBuffer::SetManager(std::weak_ptr<StreamIDManager> streamIDManager)
51 {
52 manager_ = streamIDManager;
53 }
54
GetGlobalId(int32_t soundID)55 int32_t CacheBuffer::GetGlobalId(int32_t soundID)
56 {
57 if (auto sharedManager = manager_.lock()) {
58 return sharedManager->GetGlobalId(soundID);
59 } else {
60 return ERROE_GLOBAL_ID;
61 }
62 }
63
DelGlobalId(int32_t globalId)64 void CacheBuffer::DelGlobalId(int32_t globalId)
65 {
66 if (auto sharedManager = manager_.lock()) {
67 sharedManager->DelGlobalId(globalId);
68 }
69 }
70
SetGlobalId(int32_t soundID,int32_t globalId)71 void CacheBuffer::SetGlobalId(int32_t soundID, int32_t globalId)
72 {
73 if (auto sharedManager = manager_.lock()) {
74 sharedManager->SetGlobalId(soundID, globalId);
75 }
76 }
77
IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo & audioRendererInfo)78 bool CacheBuffer::IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo &audioRendererInfo)
79 {
80 AudioStandard::AudioStreamType streamType = AudioStandard::AudioSystemManager::GetStreamType(
81 audioRendererInfo.contentType, audioRendererInfo.streamUsage);
82 if (streamType == AudioStandard::AudioStreamType::STREAM_MUSIC ||
83 streamType == AudioStandard::AudioStreamType::STREAM_MOVIE ||
84 streamType == AudioStandard::AudioStreamType::STREAM_SPEECH) {
85 return true;
86 }
87 return false;
88 }
89
DealAudioRendererParams(AudioStandard::AudioRendererOptions & rendererOptions,const AudioStandard::AudioRendererInfo & audioRendererInfo)90 void CacheBuffer::DealAudioRendererParams(AudioStandard::AudioRendererOptions &rendererOptions,
91 const AudioStandard::AudioRendererInfo &audioRendererInfo)
92 {
93 int32_t sampleRate;
94 int32_t sampleFormat;
95 int32_t channelCount;
96 // Set to PCM encoding
97 rendererOptions.streamInfo.encoding = AudioStandard::AudioEncodingType::ENCODING_PCM;
98 // Get sample rate from trackFormat and set it to audiorender.
99 trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampleRate);
100 rendererOptions.streamInfo.samplingRate = static_cast<AudioStandard::AudioSamplingRate>(sampleRate);
101 // Get sample format from trackFormat and set it to audiorender.
102 trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, sampleFormat);
103 // Align audiorender capability
104 sampleFormat_ = static_cast<AudioStandard::AudioSampleFormat>(sampleFormat);
105 rendererOptions.streamInfo.format = sampleFormat_;
106 // Get channel count from trackFormat and set it to audiorender.
107 trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channelCount);
108 audioChannel_ = static_cast<AudioStandard::AudioChannel>(channelCount);
109 rendererOptions.streamInfo.channels = audioChannel_;
110 // contentType streamUsage rendererFlags come from user.
111 if (IsAudioRendererCanMix(audioRendererInfo)) {
112 rendererOptions.strategy.concurrencyMode = AudioStandard::AudioConcurrencyMode::MIX_WITH_OTHERS;
113 }
114 rendererOptions.rendererInfo.contentType = audioRendererInfo.contentType;
115 rendererOptions.rendererInfo.streamUsage = audioRendererInfo.streamUsage;
116 rendererOptions.privacyType = AudioStandard::PRIVACY_TYPE_PUBLIC;
117 rendererFlags_ = audioRendererInfo.rendererFlags;
118 rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
119 rendererOptions.rendererInfo.playerType = AudioStandard::PlayerType::PLAYER_TYPE_SOUND_POOL;
120 rendererOptions.rendererInfo.expectedPlaybackDurationBytes = static_cast<uint64_t>(cacheDataTotalSize_);
121 }
122
CreateAudioRenderer(const AudioStandard::AudioRendererInfo & audioRendererInfo,const PlayParams & playParams)123 std::unique_ptr<AudioStandard::AudioRenderer> CacheBuffer::CreateAudioRenderer(
124 const AudioStandard::AudioRendererInfo &audioRendererInfo, const PlayParams &playParams)
125 {
126 MediaTrace trace("CacheBuffer::CreateAudioRenderer");
127 AudioStandard::AudioRendererOptions rendererOptions = {};
128 DealAudioRendererParams(rendererOptions, audioRendererInfo);
129 std::string cacheDir = "/data/storage/el2/base/temp";
130 if (playParams.cacheDir != "") {
131 cacheDir = playParams.cacheDir;
132 }
133
134 SoundPoolXCollie soundPoolXCollie("AudioRenderer::Create time out",
135 [](void *) {
136 MEDIA_LOGI("AudioRenderer::Create time out");
137 });
138 std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer =
139 AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
140 soundPoolXCollie.CancelXCollieTimer();
141
142 if (audioRenderer == nullptr) {
143 MEDIA_LOGE("create audiorenderer failed, try again.");
144 if (rendererFlags_ == AudioStandard::AUDIO_FLAG_VKB_FAST
145 || rendererFlags_ == AudioStandard::AUDIO_FLAG_VKB_NORMAL) {
146 rendererFlags_ = AudioStandard::AUDIO_FLAG_VKB_NORMAL;
147 } else {
148 rendererFlags_ = NORMAL_PLAY_RENDERER_FLAGS;
149 }
150 rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
151 SoundPoolXCollie soundPoolXCollieNormal("AudioRenderer::Create normal time out",
152 [](void *) {
153 MEDIA_LOGI("AudioRenderer::Create normal time out");
154 });
155 audioRenderer = AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
156 soundPoolXCollieNormal.CancelXCollieTimer();
157 }
158
159 CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, nullptr, "Invalid audioRenderer.");
160 return audioRenderer;
161 }
162
PrepareAudioRenderer(std::unique_ptr<AudioStandard::AudioRenderer> & audioRenderer)163 void CacheBuffer::PrepareAudioRenderer(std::unique_ptr<AudioStandard::AudioRenderer> &audioRenderer)
164 {
165 size_t targetSize = 0;
166 int32_t ret = audioRenderer->GetBufferSize(targetSize);
167 audioRenderer->SetRenderMode(AudioStandard::AudioRenderMode::RENDER_MODE_CALLBACK);
168 if (ret == 0 && targetSize != 0 && !audioRenderer->IsFastRenderer()) {
169 size_t bufferDuration = 20; // 20 -> 20ms
170 audioRenderer->SetBufferDuration(bufferDuration);
171 MEDIA_LOGI("Using buffer size:%{public}zu, duration %{public}zu", targetSize, bufferDuration);
172 }
173 int32_t retCallback = audioRenderer->SetRendererWriteCallback(shared_from_this());
174 int32_t retFirstCallback = audioRenderer->SetRendererFirstFrameWritingCallback(shared_from_this());
175 int32_t retRenderCallback = audioRenderer->SetRendererCallback(shared_from_this());
176 MEDIA_LOGI("CacheBuffer::CreateAudioRenderer retCallback:%{public}d, retFirstCallback:%{public}d,"
177 " retRenderCallback:%{public}d", retCallback, retFirstCallback, retRenderCallback);
178 }
179
GetAvailableAudioRenderer(const AudioStandard::AudioRendererInfo & audioRendererInfo,const PlayParams & playParams)180 void CacheBuffer::GetAvailableAudioRenderer(const AudioStandard::AudioRendererInfo &audioRendererInfo,
181 const PlayParams &playParams)
182 {
183 MediaTrace trace("CacheBuffer::GetAvailableAudioRenderer");
184 MEDIA_LOGI("CacheBuffer::GetAvailableAudioRenderer start");
185 bool result = true;
186 while (result) {
187 int32_t globalId = GetGlobalId(soundID_);
188 if (globalId > 0) {
189 audioRenderer_ = AudioRendererManager::GetInstance().GetAudioRendererInstance(globalId);
190 if (audioRenderer_ != nullptr) {
191 MEDIA_LOGI("CacheBuffer::GetAvailableAudioRenderer useOld audiorenderer,"
192 "globalId:%{public}d, soundID:%{public}d", globalId, soundID_);
193 break;
194 } else {
195 DelGlobalId(globalId);
196 }
197 } else {
198 result = false;
199 }
200 }
201 if (audioRenderer_ == nullptr) {
202 MEDIA_LOGI("CacheBuffer::GetAvailableAudioRenderer CreateAudioRenderer New start");
203 audioRenderer_ = CreateAudioRenderer(audioRendererInfo, playParams);
204 if (audioRenderer_ == nullptr) {
205 AudioRendererManager::GetInstance().RemoveOldAudioRenderer();
206 MEDIA_LOGE("CacheBuffer::GetAvailableAudioRenderer CreateAudioRenderer fail, release old auidoRenderer");
207 audioRenderer_ = CreateAudioRenderer(audioRendererInfo, playParams);
208 }
209 MEDIA_LOGI("CacheBuffer::GetAvailableAudioRenderer CreateAudioRenderer New end");
210 CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "Invalid CreateAudioRenderer");
211 PrepareAudioRenderer(audioRenderer_);
212 }
213 MEDIA_LOGI("CacheBuffer::GetAvailableAudioRenderer end");
214 }
215
PreparePlayInner(const AudioStandard::AudioRendererInfo & audioRendererInfo,const PlayParams & playParams)216 int32_t CacheBuffer::PreparePlayInner(const AudioStandard::AudioRendererInfo &audioRendererInfo,
217 const PlayParams &playParams)
218 {
219 if (audioRenderer_ != nullptr) {
220 MEDIA_LOGI("CacheBuffer::PreparePlayInner has audiorenderer available");
221 DealPlayParamsBeforePlay(playParams);
222 return MSERR_OK;
223 }
224 GetAvailableAudioRenderer(audioRendererInfo, playParams);
225 CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "Invalid GetAvailableAudioRenderer");
226 DealPlayParamsBeforePlay(playParams);
227 return MSERR_OK;
228 }
229
PreparePlay(const AudioStandard::AudioRendererInfo & audioRendererInfo,const PlayParams & playParams)230 int32_t CacheBuffer::PreparePlay(const AudioStandard::AudioRendererInfo &audioRendererInfo,
231 const PlayParams &playParams)
232 {
233 std::lock_guard lock(cacheBufferLock_);
234 playParameters_ = playParams;
235 audioRendererInfo_ = audioRendererInfo;
236 return PreparePlayInner(audioRendererInfo, playParams);
237 }
238
DoPlay(const int32_t streamID)239 int32_t CacheBuffer::DoPlay(const int32_t streamID)
240 {
241 MediaTrace trace("CacheBuffer::DoPlay");
242 CHECK_AND_RETURN_RET_LOG(streamID == streamID_, MSERR_INVALID_VAL, "Invalid streamID, failed to DoPlay.");
243 std::lock_guard lock(cacheBufferLock_);
244 CHECK_AND_RETURN_RET_LOG(fullCacheData_ != nullptr, MSERR_INVALID_VAL, "fullCacheData_ is nullptr.");
245 if (audioRenderer_ == nullptr) {
246 MEDIA_LOGI("CacheBuffer::DoPlay audioRenderer_ is nullptr, try again");
247 PreparePlayInner(audioRendererInfo_, playParameters_);
248 }
249 MEDIA_LOGI("CacheBuffer::DoPlay start, streamID:%{public}d", streamID);
250 CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "Invalid audioRenderer.");
251 size_t bufferSize;
252 audioRenderer_->GetBufferSize(bufferSize);
253 MEDIA_LOGI("CacheBuffer::DoPlay, streamID_:%{public}d, bufferSize:%{public}zu, cacheDataFrameIndex_:%{public}zu,"
254 " cacheDataTotalSize_:%{public}zu", streamID_, bufferSize, cacheDataFrameIndex_, cacheDataTotalSize_);
255 audioRenderer_->SetSourceDuration(sourceDurationMs_);
256
257 cacheDataFrameIndex_ = 0;
258 havePlayedCount_ = 0;
259 isRunning_.store(true);
260 SoundPoolXCollie soundPoolXCollie("audioRenderer::Start time out",
261 [](void *) {
262 MEDIA_LOGI("audioRenderer::Start time out");
263 });
264 if (!audioRenderer_->Start()) {
265 soundPoolXCollie.CancelXCollieTimer();
266 return HandleRendererNotStart(streamID);
267 } else {
268 soundPoolXCollie.CancelXCollieTimer();
269 }
270 MEDIA_LOGI("CacheBuffer::DoPlay success, streamID:%{public}d", streamID);
271 return MSERR_OK;
272 }
273
HandleRendererNotStart(const int32_t streamID)274 int32_t CacheBuffer::HandleRendererNotStart(const int32_t streamID)
275 {
276 OHOS::AudioStandard::RendererState state = audioRenderer_->GetStatus();
277 if (state == OHOS::AudioStandard::RendererState::RENDERER_RUNNING) {
278 MEDIA_LOGI("CacheBuffer::HandleRendererNotStart audioRenderer has started,"
279 " streamID:%{public}d", streamID);
280 isRunning_.store(true);
281 if (callback_ != nullptr) {
282 MEDIA_LOGI("CacheBuffer::HandleRendererNotStart callback_ OnPlayFinished,"
283 "streamID:%{public}d", streamID);
284 callback_->OnPlayFinished(streamID_);
285 }
286 isNeedFadeIn_ = true;
287 return MSERR_OK;
288 } else {
289 MEDIA_LOGE("CacheBuffer::HandleRendererNotStart audioRenderer start failed,"
290 "streamID:%{public}d", streamID);
291 isRunning_.store(false);
292 if (callback_ != nullptr) {
293 MEDIA_LOGI("CacheBuffer::HandleRendererNotStart doPlay failed, call callback,"
294 "streamID:%{public}d", streamID);
295 callback_->OnError(MSERR_INVALID_VAL);
296 SoundPoolUtils::ErrorInfo errorInfo{MSERR_INVALID_VAL, soundID_,
297 streamID_, ERROR_TYPE::PLAY_ERROR, callback_};
298 SoundPoolUtils::SendErrorInfo(errorInfo);
299 }
300 if (cacheBufferCallback_ != nullptr) cacheBufferCallback_->OnError(MSERR_INVALID_VAL);
301 return MSERR_INVALID_VAL;
302 }
303 }
304
DealPlayParamsBeforePlay(const PlayParams & playParams)305 void CacheBuffer::DealPlayParamsBeforePlay(const PlayParams &playParams)
306 {
307 audioRenderer_->SetOffloadAllowed(false);
308 loop_ = playParams.loop;
309 audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(playParams.rate));
310 audioRenderer_->SetVolume(playParams.leftVolume);
311 priority_ = playParams.priority;
312 audioRenderer_->SetParallelPlayFlag(playParams.parallelPlayFlag);
313 audioRenderer_->SetAudioHapticsSyncId(playParams.audioHapticsSyncId);
314 MEDIA_LOGI("CacheBuffer::DealPlayParamsBeforePlay end");
315 }
316
CheckAndAlignRendererRate(const int32_t rate)317 AudioStandard::AudioRendererRate CacheBuffer::CheckAndAlignRendererRate(const int32_t rate)
318 {
319 AudioStandard::AudioRendererRate renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
320 switch (rate) {
321 case AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL:
322 renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
323 break;
324 case AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE:
325 renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE;
326 break;
327 case AudioStandard::AudioRendererRate::RENDER_RATE_HALF:
328 renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_HALF;
329 break;
330 default:
331 renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
332 break;
333 }
334 return renderRate;
335 }
336
OnWriteData(size_t length)337 void CacheBuffer::OnWriteData(size_t length)
338 {
339 if (audioRenderer_ == nullptr) {
340 MEDIA_LOGE("audioRenderer is nullptr.");
341 return;
342 }
343 if (!isRunning_.load()) {
344 MEDIA_LOGE("audioRenderer is stop.");
345 return;
346 }
347 CHECK_AND_RETURN_LOG(isReadyToStopAudioRenderer_.load() == false,
348 "CacheBuffer::OnWriteData is ready To stop AudioRenderer, streamID:%{public}d", streamID_);
349 std::lock_guard lock(cacheBufferLock_);
350 CHECK_AND_RETURN_LOG(fullCacheData_ != nullptr, "fullCacheData_ is nullptr");
351 if (cacheDataFrameIndex_ >= static_cast<size_t>(fullCacheData_->size)) {
352 if (loop_ >= 0 && havePlayedCount_ >= loop_) {
353 MEDIA_LOGI("CacheBuffer stream write finish, cacheDataFrameIndex_:%{public}zu,"
354 " havePlayedCount_:%{public}d, loop:%{public}d, streamID_:%{public}d, length: %{public}zu",
355 cacheDataFrameIndex_, havePlayedCount_, loop_, streamID_, length);
356 int32_t streamIDStop = streamID_;
357 ThreadPool::Task cacheBufferStopTask = [this, streamIDStop] { this->Stop(streamIDStop); };
358 if (auto ptr = cacheBufferStopThreadPool_.lock()) {
359 ptr->AddTask(cacheBufferStopTask);
360 isReadyToStopAudioRenderer_.store(true);
361 }
362 return;
363 }
364 cacheDataFrameIndex_ = 0;
365 havePlayedCount_++;
366 }
367 DealWriteData(length);
368 }
369
DealWriteData(size_t length)370 void CacheBuffer::DealWriteData(size_t length)
371 {
372 CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "DealWriteData audioRenderer_ is nullptr");
373 AudioStandard::BufferDesc bufDesc;
374 audioRenderer_->GetBufferDesc(bufDesc);
375 if (bufDesc.buffer != nullptr && fullCacheData_ != nullptr && fullCacheData_->buffer != nullptr) {
376 if (static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_ >= length) {
377 int32_t ret = memcpy_s(bufDesc.buffer, length,
378 fullCacheData_->buffer + cacheDataFrameIndex_, length);
379 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed total length.");
380 bufDesc.bufLength = length;
381 bufDesc.dataLength = length;
382 cacheDataFrameIndex_ += length;
383 } else {
384 size_t copyLength = static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_;
385 int32_t ret = AudioStandard::AudioRenderer::MuteAudioBuffer(bufDesc.buffer, 0, length, sampleFormat_);
386 CHECK_AND_RETURN_LOG(ret == AudioStandard::SUCCESS, "fill mute buffer failed.");
387 ret = memcpy_s(bufDesc.buffer, length, fullCacheData_->buffer + cacheDataFrameIndex_,
388 copyLength);
389 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed not enough length.");
390 bufDesc.bufLength = length;
391 bufDesc.dataLength = length;
392 cacheDataFrameIndex_ += copyLength;
393 }
394 FadeInAudioBuffer(bufDesc);
395 audioRenderer_->Enqueue(bufDesc);
396 if (cacheDataFrameIndex_ >= static_cast<size_t>(fullCacheData_->size) &&
397 (loop_ < 0 || havePlayedCount_ < loop_)) {
398 MEDIA_LOGI("DealWriteData ResetFirstFrameState when looping");
399 audioRenderer_->ResetFirstFrameState();
400 }
401 } else if (fullCacheData_ != nullptr) {
402 MEDIA_LOGE("OnWriteData, cacheDataFrameIndex_: %{public}zu, length: %{public}zu,"
403 " bufDesc.buffer:%{public}d, fullCacheData_:1, fullCacheData_->buffer:%{public}d,"
404 " streamID_:%{public}d",
405 cacheDataFrameIndex_, length, bufDesc.buffer != nullptr,
406 fullCacheData_->buffer != nullptr, streamID_);
407 } else {
408 MEDIA_LOGE("OnWriteData, cacheDataFrameIndex_: %{public}zu, length: %{public}zu,"
409 " bufDesc.buffer:%{public}d, fullCacheData_:0, streamID_:%{public}d",
410 cacheDataFrameIndex_, length, bufDesc.buffer != nullptr, streamID_);
411 }
412 }
413
OnFirstFrameWriting(uint64_t latency)414 void CacheBuffer::OnFirstFrameWriting(uint64_t latency)
415 {
416 MEDIA_LOGI("CacheBuffer::OnFirstFrameWriting, streamID_:%{public}d", streamID_);
417 CHECK_AND_RETURN_LOG(frameWriteCallback_ != nullptr, "frameWriteCallback is null.");
418 frameWriteCallback_->OnFirstAudioFrameWritingCallback(latency);
419 }
420
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)421 void CacheBuffer::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
422 {
423 MEDIA_LOGI("CacheBuffer::OnInterrupt, streamID_:%{public}d, eventType:%{public}d, forceType:%{public}d,"
424 "hintType:%{public}d", streamID_, interruptEvent.eventType, interruptEvent.forceType,
425 interruptEvent.hintType);
426 if (interruptEvent.hintType == AudioStandard::InterruptHint::INTERRUPT_HINT_PAUSE ||
427 interruptEvent.hintType == AudioStandard::InterruptHint::INTERRUPT_HINT_STOP) {
428 MEDIA_LOGI("CacheBuffer::OnInterrupt, interrupt cacheBuffer, streamID_:%{public}d", streamID_);
429 int32_t streamIDInterrupt = streamID_;
430 ThreadPool::Task cacheBufferInterruptTask = [this, streamIDInterrupt] { this->Stop(streamIDInterrupt); };
431 if (auto ptr = cacheBufferStopThreadPool_.lock()) {
432 ptr->AddTask(cacheBufferInterruptTask);
433 }
434 }
435 }
436
OnStateChange(const AudioStandard::RendererState state,const AudioStandard::StateChangeCmdType cmdType)437 void CacheBuffer::OnStateChange(const AudioStandard::RendererState state,
438 const AudioStandard::StateChangeCmdType cmdType)
439 {
440 MEDIA_LOGI("CacheBuffer::OnStateChange, state:%{public}d", state);
441 }
442
Stop(const int32_t streamID)443 int32_t CacheBuffer::Stop(const int32_t streamID)
444 {
445 MediaTrace trace("CacheBuffer::Stop");
446 MEDIA_LOGI("CacheBuffer::Stop streamID:%{public}d", streamID_);
447 std::lock_guard lock(cacheBufferLock_);
448 CHECK_AND_RETURN_RET_LOG(streamID == streamID_, MSERR_INVALID_VAL, "Invalid streamID_.");
449 if (audioRenderer_ != nullptr && isRunning_.load()) {
450 isRunning_.store(false);
451 SoundPoolXCollie soundPoolXCollie("audioRenderer::Pause or Stop time out",
452 [](void *) {
453 MEDIA_LOGI("audioRenderer::Pause or Stop time out");
454 });
455 if (audioRenderer_->IsFastRenderer()) {
456 MEDIA_LOGI("audioRenderer fast renderer pause.");
457 audioRenderer_->Pause();
458 audioRenderer_->Flush();
459 } else {
460 MEDIA_LOGI("audioRenderer normal stop.");
461 audioRenderer_->Stop();
462 }
463 soundPoolXCollie.CancelXCollieTimer();
464 cacheDataFrameIndex_ = 0;
465 havePlayedCount_ = 0;
466 if (callback_ != nullptr) {
467 MEDIA_LOGI("cachebuffer callback_ OnPlayFinished.");
468 callback_->OnPlayFinished(streamID_);
469 }
470 int32_t globalId = AudioRendererManager::GetInstance().GetGlobalId();
471 AudioRendererManager::GetInstance().SetAudioRendererInstance(globalId, std::move(audioRenderer_));
472 SetGlobalId(soundID_, globalId);
473 if (cacheBufferCallback_ != nullptr) {
474 MEDIA_LOGI("cachebuffer cacheBufferCallback_ OnPlayFinished.");
475 cacheBufferCallback_->OnPlayFinished(streamID_);
476 }
477 } else {
478 MEDIA_LOGI("CacheBuffer::Stop isRunning_:%{public}d", isRunning_.load());
479 }
480 isReadyToStopAudioRenderer_.store(false);
481 return MSERR_OK;
482 }
483
SetVolume(const int32_t streamID,const float leftVolume,const float rightVolume)484 int32_t CacheBuffer::SetVolume(const int32_t streamID, const float leftVolume, const float rightVolume)
485 {
486 std::lock_guard lock(cacheBufferLock_);
487 int32_t ret = MSERR_OK;
488 if (streamID == streamID_) {
489 if (audioRenderer_ != nullptr) {
490 MEDIA_LOGI("CacheBuffer::SetVolume start streamID:%{public}d", streamID_);
491 // audio cannot support left & right volume, all use left volume.
492 (void) rightVolume;
493 ret = audioRenderer_->SetVolume(leftVolume);
494 }
495 }
496 return ret;
497 }
498
SetRate(const int32_t streamID,const AudioStandard::AudioRendererRate renderRate)499 int32_t CacheBuffer::SetRate(const int32_t streamID, const AudioStandard::AudioRendererRate renderRate)
500 {
501 std::lock_guard lock(cacheBufferLock_);
502 int32_t ret = MSERR_OK;
503 if (streamID == streamID_) {
504 if (audioRenderer_ != nullptr) {
505 MEDIA_LOGI("CacheBuffer::SetRate start streamID:%{public}d", streamID_);
506 ret = audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(renderRate));
507 }
508 }
509 return ret;
510 }
511
SetPriority(const int32_t streamID,const int32_t priority)512 int32_t CacheBuffer::SetPriority(const int32_t streamID, const int32_t priority)
513 {
514 std::lock_guard lock(cacheBufferLock_);
515 if (streamID == streamID_) {
516 priority_ = priority;
517 }
518 return MSERR_OK;
519 }
520
SetLoop(const int32_t streamID,const int32_t loop)521 int32_t CacheBuffer::SetLoop(const int32_t streamID, const int32_t loop)
522 {
523 std::lock_guard lock(cacheBufferLock_);
524 if (streamID == streamID_) {
525 loop_ = loop;
526 havePlayedCount_ = 0;
527 }
528 return MSERR_OK;
529 }
530
SetParallelPlayFlag(const int32_t streamID,const bool parallelPlayFlag)531 int32_t CacheBuffer::SetParallelPlayFlag(const int32_t streamID, const bool parallelPlayFlag)
532 {
533 std::lock_guard lock(cacheBufferLock_);
534 if (streamID == streamID_) {
535 if (audioRenderer_ != nullptr) {
536 MEDIA_LOGI("CacheBuffer parallelPlayFlag:%{public}d.", parallelPlayFlag);
537 audioRenderer_->SetParallelPlayFlag(parallelPlayFlag);
538 }
539 }
540 return MSERR_OK;
541 }
542
Release()543 int32_t CacheBuffer::Release()
544 {
545 MediaTrace trace("CacheBuffer::Release");
546 // Define a temporary variable.Let audioRenderer_ to audioRenderer can protect audioRenderer_ concurrently
547 // modified.So will not cause null pointers.
548 std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer;
549 {
550 std::lock_guard lock(cacheBufferLock_);
551 audioRenderer = std::move(audioRenderer_);
552 audioRenderer_ = nullptr;
553 isRunning_.store(false);
554 }
555
556 MEDIA_LOGI("CacheBuffer::Release start, streamID:%{public}d", streamID_);
557 // Use audioRenderer to release and don't lock, so it will not cause dead lock. if here locked, audioRenderer
558 // will wait callback thread stop, and the callback thread can't get the lock, it will cause dead lock
559 if (audioRenderer != nullptr) {
560 SoundPoolXCollie soundPoolXCollie("Release audioRenderer::Stop time out",
561 [](void *) {
562 MEDIA_LOGI("Release audioRenderer::Stop time out");
563 });
564 audioRenderer->Stop();
565 soundPoolXCollie.CancelXCollieTimer();
566 SoundPoolXCollie soundPoolXCollieRelease("Release audioRenderer::Release time out",
567 [](void *) {
568 MEDIA_LOGI("Release audioRenderer::Release time out");
569 });
570 audioRenderer->Release();
571 soundPoolXCollieRelease.CancelXCollieTimer();
572 audioRenderer = nullptr;
573 }
574
575 std::lock_guard lock(cacheBufferLock_);
576 if (!cacheData_.empty()) cacheData_.clear();
577 if (fullCacheData_ != nullptr) fullCacheData_.reset();
578 if (callback_ != nullptr) callback_.reset();
579 if (cacheBufferCallback_ != nullptr) cacheBufferCallback_.reset();
580 if (frameWriteCallback_ != nullptr) frameWriteCallback_.reset();
581 MEDIA_LOGI("CacheBuffer::Release end, streamID:%{public}d", streamID_);
582 return MSERR_OK;
583 }
584
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)585 int32_t CacheBuffer::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
586 {
587 callback_ = callback;
588 return MSERR_OK;
589 }
590
SetCacheBufferCallback(const std::shared_ptr<ISoundPoolCallback> & callback)591 int32_t CacheBuffer::SetCacheBufferCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
592 {
593 cacheBufferCallback_ = callback;
594 return MSERR_OK;
595 }
596
SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> & callback)597 int32_t CacheBuffer::SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> &callback)
598 {
599 frameWriteCallback_ = callback;
600 return MSERR_OK;
601 }
602
SetSourceDuration(int64_t durationMs)603 void CacheBuffer::SetSourceDuration(int64_t durationMs)
604 {
605 sourceDurationMs_ = durationMs;
606 }
607
FadeInAudioBuffer(const AudioStandard::BufferDesc & bufDesc)608 void CacheBuffer::FadeInAudioBuffer(const AudioStandard::BufferDesc &bufDesc)
609 {
610 if (isNeedFadeIn_) {
611 isNeedFadeIn_ = false;
612 MEDIA_LOGI("CacheBuffer::FadeInAudioBuffer, streamID:%{public}d", streamID_);
613 int32_t ret = AudioStandard::AudioRenderer::FadeInAudioBuffer(bufDesc, sampleFormat_, audioChannel_);
614 if (ret != AudioStandard::SUCCESS) {
615 MEDIA_LOGW("CacheBuffer::FadeInAudioBuffer failed ret: %{public}d, streamID:%{public}d", ret, streamID_);
616 }
617 }
618 }
619 } // namespace Media
620 } // namespace OHOS
621