• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #include "stream.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "securec.h"
20 #include "audio_renderer_manager.h"
21 
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "Stream"};
24     static const int32_t NORMAL_PLAY_RENDERER_FLAGS = 0;
25     static const int32_t ERROE_GLOBAL_ID = -1;
26 }
27 
28 namespace OHOS {
29 namespace Media {
Stream(const Format & trackFormat,const int32_t & soundID,const int32_t & streamID,std::shared_ptr<ThreadPool> streamStopThreadPool)30 Stream::Stream(const Format &trackFormat, const int32_t &soundID, const int32_t &streamID,
31     std::shared_ptr<ThreadPool> streamStopThreadPool) : trackFormat_(trackFormat),
32     soundID_(soundID), streamID_(streamID), streamStopThreadPool_(streamStopThreadPool),
33     cacheDataFrameIndex_(0), havePlayedCount_(0)
34 {
35     MEDIA_LOGI("Construction Stream soundID:%{public}d, streamID:%{public}d", soundID, streamID);
36     int32_t sampleFormat;
37     bool res = trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, sampleFormat);
38     CHECK_AND_RETURN_LOG(res == true, "Stream::Stream trackFormat_.GetIntValue error, res:%{public}d", res);
39     sampleFormat_ = static_cast<AudioStandard::AudioSampleFormat>(sampleFormat);
40 }
41 
~Stream()42 Stream::~Stream()
43 {
44     MEDIA_LOGI("Stream::~Stream soundID:%{public}d, streamID:%{public}d", soundID_, streamID_);
45 }
46 
SetSoundData(const std::shared_ptr<AudioBufferEntry> & cacheData,const size_t & cacheDataTotalSize)47 void Stream::SetSoundData(const std::shared_ptr<AudioBufferEntry> &cacheData, const size_t &cacheDataTotalSize)
48 {
49     fullCacheData_ = cacheData;
50     cacheDataTotalSize_ = cacheDataTotalSize;
51 }
52 
SetPlayParamAndRendererInfo(PlayParams & playParameters,AudioStandard::AudioRendererInfo & audioRenderInfo)53 void Stream::SetPlayParamAndRendererInfo(PlayParams &playParameters,
54     AudioStandard::AudioRendererInfo &audioRenderInfo)
55 {
56     playParameters_ = playParameters;
57     priority_ = playParameters.priority;
58     audioRendererInfo_ = audioRenderInfo;
59 }
60 
SetManager(std::weak_ptr<ParallelStreamManager> parallelStreamManager)61 void Stream::SetManager(std::weak_ptr<ParallelStreamManager> parallelStreamManager)
62 {
63     manager_ = parallelStreamManager;
64 }
65 
GetGlobalId(int32_t soundID)66 int32_t Stream::GetGlobalId(int32_t soundID)
67 {
68     if (auto sharedManager = manager_.lock()) {
69         return sharedManager->GetGlobalId(soundID);
70     } else {
71         return ERROE_GLOBAL_ID;
72     }
73 }
74 
DelGlobalId(int32_t globalId)75 void Stream::DelGlobalId(int32_t globalId)
76 {
77     if (auto sharedManager = manager_.lock()) {
78         sharedManager->DelGlobalId(globalId);
79     }
80 }
81 
SetGlobalId(int32_t soundID,int32_t globalId)82 void Stream::SetGlobalId(int32_t soundID, int32_t globalId)
83 {
84     if (auto sharedManager = manager_.lock()) {
85         sharedManager->SetGlobalId(soundID, globalId);
86     }
87 }
88 
PreparePlay()89 void Stream::PreparePlay()
90 {
91     MediaTrace trace("Stream::PreparePlay");
92     bool result = true;
93     while (result) {
94         int32_t globalId = GetGlobalId(soundID_);
95         if (globalId > 0) {
96             audioRenderer_ = AudioRendererManager::GetInstance().GetAudioRendererInstance(globalId);
97             if (audioRenderer_ != nullptr) {
98                 MEDIA_LOGI("Stream::PreparePlay useOld audiorenderer globalId:%{public}d, soundID:%{public}d",
99                     globalId, soundID_);
100                 break;
101             } else {
102                 DelGlobalId(globalId);
103             }
104         } else {
105             result = false;
106         }
107     }
108     if (audioRenderer_ == nullptr) {
109         MEDIA_LOGI("Stream::PreparePlay CreateAudioRenderer New start");
110         audioRenderer_ = CreateAudioRenderer(audioRendererInfo_, playParameters_);
111         if (audioRenderer_ == nullptr) {
112             AudioRendererManager::GetInstance().RemoveOldAudioRenderer();
113             MEDIA_LOGE("Stream::PreparePlay CreateAudioRenderer fail, release old auidoRenderer");
114             audioRenderer_ = CreateAudioRenderer(audioRendererInfo_, playParameters_);
115         }
116         MEDIA_LOGI("Stream::PreparePlay CreateAudioRenderer New end");
117     }
118     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "Stream::PreparePlay create or get audioRenderer fail");
119     PrepareAudioRenderer(audioRenderer_);
120     DealPlayParamsBeforePlay(playParameters_);
121 }
122 
IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo & audioRendererInfo)123 bool Stream::IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo &audioRendererInfo)
124 {
125     AudioStandard::AudioStreamType streamType = AudioStandard::AudioSystemManager::GetStreamType(
126         audioRendererInfo.contentType, audioRendererInfo.streamUsage);
127     if (streamType == AudioStandard::AudioStreamType::STREAM_MUSIC ||
128         streamType == AudioStandard::AudioStreamType::STREAM_MOVIE ||
129         streamType == AudioStandard::AudioStreamType::STREAM_SPEECH) {
130             return true;
131         }
132     return false;
133 }
134 
DealAudioRendererParams(AudioStandard::AudioRendererOptions & rendererOptions,const AudioStandard::AudioRendererInfo & audioRendererInfo)135 void Stream::DealAudioRendererParams(AudioStandard::AudioRendererOptions &rendererOptions,
136     const AudioStandard::AudioRendererInfo &audioRendererInfo)
137 {
138     int32_t sampleRate;
139     int32_t sampleFormat;
140     int32_t channelCount;
141     // Set to PCM encoding
142     rendererOptions.streamInfo.encoding = AudioStandard::AudioEncodingType::ENCODING_PCM;
143     // Get sample rate from trackFormat and set it to audiorender.
144     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampleRate);
145     rendererOptions.streamInfo.samplingRate = static_cast<AudioStandard::AudioSamplingRate>(sampleRate);
146     // Get sample format from trackFormat and set it to audiorender.
147     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, sampleFormat);
148     // Align audiorender capability
149     sampleFormat_ = static_cast<AudioStandard::AudioSampleFormat>(sampleFormat);
150     rendererOptions.streamInfo.format = sampleFormat_;
151     // Get channel count from trackFormat and set it to audiorender.
152     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channelCount);
153     rendererOptions.streamInfo.channels = static_cast<AudioStandard::AudioChannel>(channelCount);
154     // contentType streamUsage rendererFlags come from user.
155     if (IsAudioRendererCanMix(audioRendererInfo)) {
156         rendererOptions.strategy.concurrencyMode = AudioStandard::AudioConcurrencyMode::MIX_WITH_OTHERS;
157     }
158     rendererOptions.rendererInfo.contentType = audioRendererInfo.contentType;
159     rendererOptions.rendererInfo.streamUsage = audioRendererInfo.streamUsage;
160     rendererOptions.privacyType = AudioStandard::PRIVACY_TYPE_PUBLIC;
161     rendererFlags_ = audioRendererInfo.rendererFlags;
162     rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
163     rendererOptions.rendererInfo.playerType = AudioStandard::PlayerType::PLAYER_TYPE_SOUND_POOL;
164     rendererOptions.rendererInfo.expectedPlaybackDurationBytes = static_cast<uint64_t>(cacheDataTotalSize_);
165 }
166 
CreateAudioRenderer(const AudioStandard::AudioRendererInfo & audioRendererInfo,const PlayParams & playParams)167 std::unique_ptr<AudioStandard::AudioRenderer> Stream::CreateAudioRenderer(
168     const AudioStandard::AudioRendererInfo &audioRendererInfo, const PlayParams &playParams)
169 {
170     MediaTrace trace("Stream::CreateAudioRenderer");
171     AudioStandard::AudioRendererOptions rendererOptions = {};
172     DealAudioRendererParams(rendererOptions, audioRendererInfo);
173     std::string cacheDir = "/data/storage/el2/base/temp";
174     if (playParams.cacheDir != "") {
175         cacheDir = playParams.cacheDir;
176     }
177 
178     SoundPoolXCollie soundPoolXCollie("AudioRenderer::Create time out",
179         [](void *) {
180             MEDIA_LOGI("AudioRenderer::Create time out");
181         });
182     std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer =
183         AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
184     soundPoolXCollie.CancelXCollieTimer();
185 
186     if (audioRenderer == nullptr) {
187         MEDIA_LOGE("create audiorenderer failed, try again.");
188         rendererFlags_ = NORMAL_PLAY_RENDERER_FLAGS;
189         rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
190         SoundPoolXCollie soundPoolXCollieNormal("AudioRenderer::Create normal time out",
191             [](void *) {
192                 MEDIA_LOGI("AudioRenderer::Create normal time out");
193             });
194         audioRenderer = AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
195         soundPoolXCollieNormal.CancelXCollieTimer();
196     }
197 
198     CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, nullptr, "Invalid audioRenderer.");
199     return audioRenderer;
200 }
201 
PrepareAudioRenderer(std::unique_ptr<AudioStandard::AudioRenderer> & audioRenderer)202 void Stream::PrepareAudioRenderer(std::unique_ptr<AudioStandard::AudioRenderer> &audioRenderer)
203 {
204     MediaTrace trace("Stream::PrepareAudioRenderer");
205     size_t targetSize = 0;
206     int32_t ret = audioRenderer->GetBufferSize(targetSize);
207     audioRenderer->SetRenderMode(AudioStandard::AudioRenderMode::RENDER_MODE_CALLBACK);
208     if (ret == 0 && targetSize != 0 && !audioRenderer->IsFastRenderer()) {
209         size_t bufferDuration = 20; // 20 -> 20ms
210         audioRenderer->SetBufferDuration(bufferDuration);
211         MEDIA_LOGI("Using buffer size:%{public}zu, duration %{public}zu", targetSize, bufferDuration);
212     }
213     int32_t retCallback = audioRenderer->SetRendererWriteCallback(shared_from_this());
214     int32_t retFirstCallback = audioRenderer->SetRendererFirstFrameWritingCallback(shared_from_this());
215     int32_t retRenderCallback = audioRenderer->SetRendererCallback(shared_from_this());
216     MEDIA_LOGI("Stream::PrepareAudioRenderer retCallback:%{public}d, retFirstCallback:%{public}d,"
217         " retRenderCallback:%{public}d", retCallback, retFirstCallback, retRenderCallback);
218 }
219 
CheckAndAlignRendererRate(const int32_t rate)220 AudioStandard::AudioRendererRate Stream::CheckAndAlignRendererRate(const int32_t rate)
221 {
222     AudioStandard::AudioRendererRate renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
223     switch (rate) {
224         case AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL:
225             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
226             break;
227         case AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE:
228             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE;
229             break;
230         case AudioStandard::AudioRendererRate::RENDER_RATE_HALF:
231             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_HALF;
232             break;
233         default:
234             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
235             break;
236     }
237     return renderRate;
238 }
239 
DealPlayParamsBeforePlay(const PlayParams & playParams)240 void Stream::DealPlayParamsBeforePlay(const PlayParams &playParams)
241 {
242     MediaTrace trace("Stream::DealPlayParamsBeforePlay");
243     audioRenderer_->SetOffloadAllowed(false);
244     loop_ = playParams.loop;
245     audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(playParams.rate));
246     audioRenderer_->SetVolume(playParams.leftVolume);
247     priority_ = playParams.priority;
248     audioRenderer_->SetParallelPlayFlag(playParams.parallelPlayFlag);
249     audioRenderer_->SetAudioHapticsSyncId(playParams.audioHapticsSyncId);
250 }
251 
DoPlay()252 int32_t Stream::DoPlay()
253 {
254     MediaTrace trace("Stream::DoPlay");
255     std::lock_guard lock(streamLock_);
256     PreparePlay();
257     if (fullCacheData_ == nullptr || audioRenderer_ == nullptr) {
258         MEDIA_LOGE("Stream::DoPlay failed, cacheData or audioRender nullptr, streamID:%{public}d", streamID_);
259         if (callback_ != nullptr) {
260             callback_->OnError(MSERR_INVALID_VAL);
261             SoundPoolUtils::ErrorInfo errorInfo{MSERR_INVALID_VAL, soundID_,
262                 streamID_, ERROR_TYPE::PLAY_ERROR, callback_};
263             SoundPoolUtils::SendErrorInfo(errorInfo);
264         }
265         if (streamCallback_ != nullptr) {
266             streamCallback_->OnError(MSERR_INVALID_VAL);
267         }
268         return MSERR_INVALID_VAL;
269     }
270     size_t bufferSize;
271     audioRenderer_->GetBufferSize(bufferSize);
272     MEDIA_LOGI("Stream::DoPlay, streamID_:%{public}d, bufferSize:%{public}zu, cacheDataFrameIndex_:%{public}zu,"
273         " cacheDataTotalSize_:%{public}zu", streamID_, bufferSize, cacheDataFrameIndex_, cacheDataTotalSize_);
274     cacheDataFrameIndex_ = 0;
275     havePlayedCount_ = 0;
276     isRunning_.store(true);
277     SoundPoolXCollie soundPoolXCollie("Stream audioRenderer::Start time out",
278         [](void *) {
279             MEDIA_LOGI("Stream audioRenderer::Start time out");
280         });
281     if (!audioRenderer_->Start()) {
282         soundPoolXCollie.CancelXCollieTimer();
283         MEDIA_LOGE("Stream::DoPlay audioRenderer start failed, streamID:%{public}d", streamID_);
284         isRunning_.store(false);
285         if (callback_ != nullptr) {
286             MEDIA_LOGE("Stream::DoPlay failed, call callback, streamID:%{public}d", streamID_);
287             callback_->OnError(MSERR_INVALID_VAL);
288             SoundPoolUtils::ErrorInfo errorInfo{MSERR_INVALID_VAL, soundID_,
289                 streamID_, ERROR_TYPE::PLAY_ERROR, callback_};
290             SoundPoolUtils::SendErrorInfo(errorInfo);
291         }
292         if (streamCallback_ != nullptr) {
293             streamCallback_->OnError(MSERR_INVALID_VAL);
294         }
295         return MSERR_INVALID_VAL;
296     }
297     soundPoolXCollie.CancelXCollieTimer();
298     MEDIA_LOGI("Stream::DoPlay success, streamID:%{public}d", streamID_);
299     return MSERR_OK;
300 }
301 
Stop()302 int32_t Stream::Stop()
303 {
304     MediaTrace trace("Stream::Stop");
305     std::lock_guard lock(streamLock_);
306     MEDIA_LOGI("Stream::Stop start streamID:%{public}d", streamID_);
307     if (audioRenderer_ != nullptr && isRunning_.load()) {
308         isRunning_.store(false);
309         SoundPoolXCollie soundPoolXCollie("Stream audioRenderer::Pause or Stop time out",
310             [](void *) {
311                 MEDIA_LOGI("Stream audioRenderer::Pause or Stop time out");
312             });
313         if (audioRenderer_->IsFastRenderer()) {
314             MEDIA_LOGI("Stream audioRenderer fast renderer pause.");
315             audioRenderer_->Pause();
316             audioRenderer_->Flush();
317         } else {
318             MEDIA_LOGI("Stream audioRenderer normal stop.");
319             audioRenderer_->Stop();
320         }
321         soundPoolXCollie.CancelXCollieTimer();
322         if (callback_ != nullptr) {
323             MEDIA_LOGI("Stream callback_ OnPlayFinished.");
324             callback_->OnPlayFinished(streamID_);
325         }
326         int32_t globalId = AudioRendererManager::GetInstance().GetGlobalId();
327         AudioRendererManager::GetInstance().SetAudioRendererInstance(globalId, std::move(audioRenderer_));
328         SetGlobalId(soundID_, globalId);
329         audioRenderer_ = nullptr;
330         fullCacheData_ = nullptr;
331         if (streamCallback_ != nullptr) {
332             MEDIA_LOGI("Stream streamCallback_ OnPlayFinished.");
333             streamCallback_->OnPlayFinished(streamID_);
334         }
335     }
336     MEDIA_LOGI("Stream::Stop end streamID:%{public}d", streamID_);
337     return MSERR_OK;
338 }
339 
OnWriteData(size_t length)340 void Stream::OnWriteData(size_t length)
341 {
342     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "audioRenderer is nullptr");
343     CHECK_AND_RETURN_LOG(isRunning_.load() == true, "audioRenderer is stop");
344     CHECK_AND_RETURN_LOG(startStopFlag_.load() == false,
345         "Stream::OnWriteData has start stop, streamID:%{public}d", streamID_);
346     if (cacheDataFrameIndex_ >= static_cast<size_t>(fullCacheData_->size)) {
347         streamLock_.lock();
348         if (loop_ >= 0 && havePlayedCount_ >= loop_) {
349             MEDIA_LOGI("Stream stream write finish, cacheDataFrameIndex_:%{public}zu,"
350                 " havePlayedCount_:%{public}d, loop:%{public}d, streamID_:%{public}d, length: %{public}zu",
351                 cacheDataFrameIndex_, havePlayedCount_, loop_, streamID_, length);
352             streamLock_.unlock();
353             AddStopTask();
354             return;
355         }
356         cacheDataFrameIndex_ = 0;
357         havePlayedCount_++;
358         streamLock_.unlock();
359     }
360     DealWriteData(length);
361 }
362 
AddStopTask()363 void Stream::AddStopTask()
364 {
365     if (auto ptr = streamStopThreadPool_.lock()) {
366         ThreadPool::Task streamStopTask = [weakThis = std::weak_ptr<Stream>(shared_from_this())] {
367             if (auto thisPtr = weakThis.lock()) {
368                 thisPtr->Stop();
369             } else {
370                 MEDIA_LOGI("Stream object has been destroyed, skipping Stop.");
371             }
372         };
373         ptr->AddTask(streamStopTask);
374         startStopFlag_.store(true);
375     } else {
376         MEDIA_LOGI("streamStopThreadPool_ is not available.");
377         startStopFlag_.store(true);
378     }
379 }
380 
DealWriteData(size_t length)381 void Stream::DealWriteData(size_t length)
382 {
383     std::lock_guard lock(streamLock_);
384     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "DealWriteData audioRenderer_ is nullptr");
385     AudioStandard::BufferDesc bufDesc;
386     audioRenderer_->GetBufferDesc(bufDesc);
387     if (bufDesc.buffer != nullptr && fullCacheData_ != nullptr && fullCacheData_->buffer != nullptr) {
388         if (static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_ >= length) {
389             int32_t ret = memcpy_s(bufDesc.buffer, length,
390                 fullCacheData_->buffer + cacheDataFrameIndex_, length);
391             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed total length.");
392             bufDesc.bufLength = length;
393             bufDesc.dataLength = length;
394             cacheDataFrameIndex_ += length;
395         } else {
396             size_t copyLength = static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_;
397             int32_t ret = AudioStandard::AudioRenderer::MuteAudioBuffer(bufDesc.buffer, 0, length, sampleFormat_);
398             CHECK_AND_RETURN_LOG(ret == AudioStandard::SUCCESS, "fill mute buffer failed.");
399             ret = memcpy_s(bufDesc.buffer, length, fullCacheData_->buffer + cacheDataFrameIndex_,
400                 copyLength);
401             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed not enough length.");
402             bufDesc.bufLength = length;
403             bufDesc.dataLength = length;
404             cacheDataFrameIndex_ += copyLength;
405         }
406         audioRenderer_->Enqueue(bufDesc);
407     } else if (fullCacheData_ != nullptr) {
408         MEDIA_LOGE("Stream OnWriteData, cacheDataFrameIndex_: %{public}zu, length: %{public}zu,"
409             " bufDesc.buffer:%{public}d, fullCacheData_:1, fullCacheData_->buffer:%{public}d,"
410             " streamID_:%{public}d",
411             cacheDataFrameIndex_, length, bufDesc.buffer != nullptr,
412             fullCacheData_->buffer != nullptr, streamID_);
413     } else {
414         MEDIA_LOGE("Stream OnWriteData, cacheDataFrameIndex_: %{public}zu, length: %{public}zu,"
415             " bufDesc.buffer:%{public}d, fullCacheData_:0, streamID_:%{public}d",
416             cacheDataFrameIndex_, length, bufDesc.buffer != nullptr, streamID_);
417     }
418 }
419 
OnFirstFrameWriting(uint64_t latency)420 void Stream::OnFirstFrameWriting(uint64_t latency)
421 {
422     MEDIA_LOGI("Stream::OnFirstFrameWriting, streamID_:%{public}d", streamID_);
423     CHECK_AND_RETURN_LOG(frameWriteCallback_ != nullptr, "frameWriteCallback is null.");
424     frameWriteCallback_->OnFirstAudioFrameWritingCallback(latency);
425 }
426 
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)427 void Stream::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
428 {
429     MEDIA_LOGI("Stream::OnInterrupt, streamID_:%{public}d, eventType:%{public}d, forceType:%{public}d,"
430         "hintType:%{public}d", streamID_, interruptEvent.eventType, interruptEvent.forceType,
431         interruptEvent.hintType);
432     if (interruptEvent.hintType == AudioStandard::InterruptHint::INTERRUPT_HINT_PAUSE ||
433         interruptEvent.hintType == AudioStandard::InterruptHint::INTERRUPT_HINT_STOP) {
434         MEDIA_LOGI("Stream::OnInterrupt, interrupt Stream, streamID_:%{public}d", streamID_);
435         AddStopTask();
436     }
437 }
438 
OnStateChange(const AudioStandard::RendererState state,const AudioStandard::StateChangeCmdType cmdType)439 void Stream::OnStateChange(const AudioStandard::RendererState state,
440     const AudioStandard::StateChangeCmdType cmdType)
441 {
442     MEDIA_LOGI("Stream::OnStateChange, state:%{public}d", state);
443 }
444 
SetVolume(const float leftVolume,const float rightVolume)445 int32_t Stream::SetVolume(const float leftVolume, const float rightVolume)
446 {
447     std::lock_guard lock(streamLock_);
448     CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "SetVolume Invalid audioRenderer");
449     (void) rightVolume;
450     int32_t ret = audioRenderer_->SetVolume(leftVolume);
451     MEDIA_LOGI("Stream::SetVolume, ret:%{public}d", ret);
452     return ret;
453 }
454 
SetRate(const AudioStandard::AudioRendererRate renderRate)455 int32_t Stream::SetRate(const AudioStandard::AudioRendererRate renderRate)
456 {
457     std::lock_guard lock(streamLock_);
458     CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "SetRate Invalid audioRenderer");
459     int32_t ret = audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(renderRate));
460     MEDIA_LOGI("Stream::SetRate, ret:%{public}d", ret);
461     return ret;
462 }
463 
SetPriority(const int32_t priority)464 int32_t Stream::SetPriority(const int32_t priority)
465 {
466     std::lock_guard lock(streamLock_);
467     priority_ = priority;
468     return MSERR_OK;
469 }
470 
SetLoop(const int32_t loop)471 int32_t Stream::SetLoop(const int32_t loop)
472 {
473     std::lock_guard lock(streamLock_);
474     loop_ = loop;
475     havePlayedCount_ = 0;
476     return MSERR_OK;
477 }
478 
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)479 int32_t Stream::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
480 {
481     callback_ = callback;
482     return MSERR_OK;
483 }
484 
SetStreamCallback(const std::shared_ptr<ISoundPoolCallback> & callback)485 int32_t Stream::SetStreamCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
486 {
487     streamCallback_ = callback;
488     return MSERR_OK;
489 }
490 
SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> & callback)491 int32_t Stream::SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> &callback)
492 {
493     frameWriteCallback_ = callback;
494     return MSERR_OK;
495 }
496 
GetSoundID()497 int32_t Stream::GetSoundID()
498 {
499     return soundID_;
500 }
501 
GetStreamID()502 int32_t Stream::GetStreamID()
503 {
504     return streamID_;
505 }
506 
GetPriority()507 int32_t Stream::GetPriority()
508 {
509     return priority_;
510 }
511 
512 } // namespace Media
513 } // namespace OHOS
514