1 /*
2 * Copyright (C) 2023 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 <algorithm>
17 #include "parameter.h"
18 #include "soundpool.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "stream_id_manager.h"
22 #include "audio_renderer_manager.h"
23
24 namespace {
25 // audiorender max concurrency.
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "StreamIDManager"};
27 static const std::string THREAD_POOL_NAME = "OS_StreamMgr";
28 static const std::string THREAD_POOL_NAME_CACHE_BUFFER = "OS_CacheBuf";
29 static const int32_t MAX_THREADS_NUM = std::thread::hardware_concurrency() >= 4 ? 2 : 1;
30 static const int32_t ERROE_GLOBAL_ID = -1;
31 }
32
33 namespace OHOS {
34 namespace Media {
StreamIDManager(int32_t maxStreams,AudioStandard::AudioRendererInfo audioRenderInfo)35 StreamIDManager::StreamIDManager(int32_t maxStreams,
36 AudioStandard::AudioRendererInfo audioRenderInfo) : audioRendererInfo_(audioRenderInfo), maxStreams_(maxStreams)
37 {
38 MEDIA_LOGI("Construction StreamIDManager.");
39 audioRendererInfo_.playerType = AudioStandard::PlayerType::PLAYER_TYPE_SOUND_POOL;
40 }
41
~StreamIDManager()42 StreamIDManager::~StreamIDManager()
43 {
44 MEDIA_LOGI("Destruction StreamIDManager");
45 if (callback_ != nullptr) {
46 callback_.reset();
47 }
48 if (frameWriteCallback_ != nullptr) {
49 frameWriteCallback_.reset();
50 }
51 for (auto cacheBuffer : cacheBuffers_) {
52 if (cacheBuffer.second != nullptr) {
53 int32_t streamID = cacheBuffer.second->GetStreamID();
54 cacheBuffer.second->Stop(streamID);
55 cacheBuffer.second->Release();
56 }
57 }
58 cacheBuffers_.clear();
59 if (isStreamPlayingThreadPoolStarted_.load()) {
60 if (streamPlayingThreadPool_ != nullptr) {
61 streamPlayingThreadPool_->Stop();
62 }
63 isStreamPlayingThreadPoolStarted_.store(false);
64 }
65 if (isCacheBufferStopThreadPoolStarted_.load()) {
66 if (cacheBufferStopThreadPool_ != nullptr) {
67 cacheBufferStopThreadPool_->Stop();
68 }
69 isCacheBufferStopThreadPoolStarted_.store(false);
70 }
71 }
72
InitThreadPool()73 int32_t StreamIDManager::InitThreadPool()
74 {
75 if (isStreamPlayingThreadPoolStarted_.load()) {
76 return MSERR_OK;
77 }
78 streamPlayingThreadPool_ = std::make_unique<ThreadPool>(THREAD_POOL_NAME);
79 CHECK_AND_RETURN_RET_LOG(streamPlayingThreadPool_ != nullptr, MSERR_INVALID_VAL,
80 "Failed to obtain playing ThreadPool");
81 if (maxStreams_ > MAX_PLAY_STREAMS_NUMBER) {
82 maxStreams_ = MAX_PLAY_STREAMS_NUMBER;
83 MEDIA_LOGI("more than max play stream number, align to max play strem number.");
84 }
85 if (maxStreams_ < MIN_PLAY_STREAMS_NUMBER) {
86 maxStreams_ = MIN_PLAY_STREAMS_NUMBER;
87 MEDIA_LOGI("less than min play stream number, align to min play strem number.");
88 }
89 MEDIA_LOGI("stream playing thread pool maxStreams_:%{public}d", maxStreams_);
90 // For stream priority logic, thread num need align to task num.
91 streamPlayingThreadPool_->Start(maxStreams_);
92 streamPlayingThreadPool_->SetMaxTaskNum(maxStreams_);
93 isStreamPlayingThreadPoolStarted_.store(true);
94
95 cacheBufferStopThreadPool_ = std::make_shared<ThreadPool>(THREAD_POOL_NAME_CACHE_BUFFER);
96 CHECK_AND_RETURN_RET_LOG(cacheBufferStopThreadPool_ != nullptr, MSERR_INVALID_VAL,
97 "Failed to obtain stop ThreadPool");
98 cacheBufferStopThreadPool_->Start(CACHE_BUFFER_THREAD_NUMBER);
99 cacheBufferStopThreadPool_->SetMaxTaskNum(CACHE_BUFFER_THREAD_NUMBER);
100 isCacheBufferStopThreadPoolStarted_.store(true);
101
102 OHOS::Media::AudioRendererManager::GetInstance().SetStreamIDManager(weak_from_this());
103 return MSERR_OK;
104 }
105
GetGlobalId(int32_t soundId)106 int32_t StreamIDManager::GetGlobalId(int32_t soundId)
107 {
108 std::lock_guard lock(globalIdMutex_);
109 for (auto it = globalIdVector_.begin(); it != globalIdVector_.end();) {
110 if (it->first == soundId) {
111 return it->second;
112 } else {
113 ++it;
114 }
115 }
116 return ERROE_GLOBAL_ID;
117 }
118
DelGlobalId(int32_t globalId)119 void StreamIDManager::DelGlobalId(int32_t globalId)
120 {
121 std::lock_guard lock(globalIdMutex_);
122 for (auto it = globalIdVector_.begin(); it != globalIdVector_.end();) {
123 if (it->second == globalId) {
124 globalIdVector_.erase(it);
125 break;
126 } else {
127 ++it;
128 }
129 }
130 }
131
SetGlobalId(int32_t soundId,int32_t globalId)132 void StreamIDManager::SetGlobalId(int32_t soundId, int32_t globalId)
133 {
134 std::lock_guard lock(globalIdMutex_);
135 globalIdVector_.push_back(std::make_pair(soundId, globalId));
136 }
137
DelSoundId(int32_t soundId)138 void StreamIDManager::DelSoundId(int32_t soundId)
139 {
140 std::lock_guard lock(globalIdMutex_);
141 for (auto it = globalIdVector_.begin(); it != globalIdVector_.end();) {
142 if (it->first == soundId) {
143 OHOS::Media::AudioRendererManager::GetInstance().DelAudioRenderer(it->second);
144 it = globalIdVector_.erase(it);
145 } else {
146 ++it;
147 }
148 }
149 }
150
Play(std::shared_ptr<SoundParser> & soundParser,PlayParams & playParameters)151 int32_t StreamIDManager::Play(std::shared_ptr<SoundParser> &soundParser, PlayParams &playParameters)
152 {
153 MediaTrace trace("StreamIDManager::Play");
154 CHECK_AND_RETURN_RET_LOG(soundParser != nullptr, -1, "Invalid soundParser.");
155 int32_t soundID = soundParser->GetSoundID();
156 int32_t streamID = GetFreshStreamID(soundID, playParameters);
157 {
158 std::lock_guard lock(streamIDManagerLock_);
159 if (streamID <= 0) {
160 do {
161 nextStreamID_ = nextStreamID_ == INT32_MAX ? 1 : nextStreamID_ + 1;
162 } while (FindCacheBuffer(nextStreamID_) != nullptr);
163 streamID = nextStreamID_;
164 std::shared_ptr<AudioBufferEntry> cacheData;
165 soundParser->GetSoundData(cacheData);
166 size_t cacheDataTotalSize = soundParser->GetSoundDataTotalSize();
167 auto cacheBuffer = std::make_shared<OHOS::Media::CacheBuffer>(soundParser->GetSoundTrackFormat(),
168 soundID, streamID, cacheBufferStopThreadPool_);
169 CHECK_AND_RETURN_RET_LOG(cacheBuffer != nullptr, -1, "failed to create cache buffer");
170 cacheBuffer->SetSoundData(cacheData, cacheDataTotalSize);
171 cacheBuffer->SetManager(weak_from_this());
172 CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, MSERR_INVALID_VAL, "Invalid callback.");
173 cacheBuffer->SetCallback(callback_);
174 cacheBufferCallback_ = std::make_shared<CacheBufferCallBack>(weak_from_this());
175 CHECK_AND_RETURN_RET_LOG(cacheBufferCallback_ != nullptr, MSERR_INVALID_VAL,
176 "Invalid cachebuffer callback");
177 cacheBuffer->SetCacheBufferCallback(cacheBufferCallback_);
178 if (frameWriteCallback_ != nullptr) {
179 cacheBuffer->SetFrameWriteCallback(frameWriteCallback_);
180 }
181 std::chrono::microseconds duration(soundParser->GetSourceDuration());
182 int64_t durationMs = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
183 cacheBuffer->SetSourceDuration(durationMs);
184 cacheBuffers_.emplace(streamID, cacheBuffer);
185 }
186 }
187 MEDIA_LOGI("StreamIDManager::SetPlay start soundID:%{public}d, streamID:%{public}d", soundID, streamID);
188 int32_t result = SetPlay(soundID, streamID, playParameters);
189 CHECK_AND_RETURN_RET_LOG(result == MSERR_OK, errorStreamId, "Invalid SetPlay");
190 return streamID;
191 }
192
SetPlay(const int32_t soundID,const int32_t streamID,const PlayParams playParameters)193 int32_t StreamIDManager::SetPlay(const int32_t soundID, const int32_t streamID, const PlayParams playParameters)
194 {
195 MediaTrace trace("StreamIDManager::SetPlay");
196 if (!isStreamPlayingThreadPoolStarted_.load()) {
197 InitThreadPool();
198 }
199
200 CHECK_AND_RETURN_RET_LOG(streamPlayingThreadPool_ != nullptr, MSERR_INVALID_VAL,
201 "Failed to obtain stream play threadpool.");
202 // CacheBuffer must prepare before play.
203 std::shared_ptr<CacheBuffer> freshCacheBuffer;
204 {
205 std::lock_guard lock(streamIDManagerLock_);
206 freshCacheBuffer = FindCacheBuffer(streamID);
207 }
208 CHECK_AND_RETURN_RET_LOG(freshCacheBuffer != nullptr, MSERR_INVALID_VAL, "Invalid fresh cache buffer");
209 int32_t result = freshCacheBuffer->PreparePlay(audioRendererInfo_, playParameters);
210 CHECK_AND_RETURN_RET_LOG(result == MSERR_OK, MSERR_INVALID_VAL, "Invalid PreparePlay");
211 int32_t tempMaxStream = maxStreams_;
212 MEDIA_LOGI("StreamIDManager cur task num:%{public}zu, maxStreams_:%{public}d",
213 playingStreamIDs_.size(), maxStreams_);
214 if (playingStreamIDs_.size() < static_cast<size_t>(tempMaxStream)) {
215 AddPlayTask(streamID, playParameters);
216 } else {
217 int32_t playingStreamID = playingStreamIDs_.back();
218 std::shared_ptr<CacheBuffer> playingCacheBuffer;
219 {
220 std::lock_guard lock(streamIDManagerLock_);
221 playingCacheBuffer = FindCacheBuffer(playingStreamID);
222 }
223 CHECK_AND_RETURN_RET_LOG(freshCacheBuffer != nullptr, MSERR_INVALID_VAL, "Invalid fresh cache buffer");
224 CHECK_AND_RETURN_RET_LOG(playingCacheBuffer != nullptr, MSERR_INVALID_VAL, "Invalid playingCacheBuffer");
225 MEDIA_LOGI("StreamIDManager fresh sound priority:%{public}d, playing stream priority:%{public}d",
226 freshCacheBuffer->GetPriority(), playingCacheBuffer->GetPriority());
227 if (freshCacheBuffer->GetPriority() >= playingCacheBuffer->GetPriority()) {
228 MEDIA_LOGI("StreamIDManager stop playing low priority sound:%{public}d", playingStreamID);
229 playingCacheBuffer->Stop(playingStreamID);
230 MEDIA_LOGI("StreamIDManager to playing fresh streamID:%{public}d.", streamID);
231 AddPlayTask(streamID, playParameters);
232 } else {
233 std::lock_guard lock(streamIDManagerLock_);
234 MEDIA_LOGI("StreamIDManager queue will play streams, streamID:%{public}d.", streamID);
235 StreamIDAndPlayParamsInfo freshStreamIDAndPlayParamsInfo;
236 freshStreamIDAndPlayParamsInfo.streamID = streamID;
237 freshStreamIDAndPlayParamsInfo.playParameters = playParameters;
238 QueueAndSortWillPlayStreamID(freshStreamIDAndPlayParamsInfo);
239 }
240 }
241 return MSERR_OK;
242 }
243
244 // Sort in descending order
245 // 0 has the lowest priority, and the higher the value, the higher the priority
246 // The queue head has the highest value and priority
QueueAndSortPlayingStreamID(int32_t streamID)247 void StreamIDManager::QueueAndSortPlayingStreamID(int32_t streamID)
248 {
249 if (playingStreamIDs_.empty()) {
250 playingStreamIDs_.emplace_back(streamID);
251 } else {
252 bool shouldReCombinePlayingQueue = false;
253 for (size_t i = 0; i < playingStreamIDs_.size(); i++) {
254 int32_t playingStreamID = playingStreamIDs_[i];
255 std::shared_ptr<CacheBuffer> freshCacheBuffer = FindCacheBuffer(streamID);
256 std::shared_ptr<CacheBuffer> playingCacheBuffer = FindCacheBuffer(playingStreamID);
257 if (playingCacheBuffer == nullptr) {
258 playingStreamIDs_.erase(playingStreamIDs_.begin() + i);
259 shouldReCombinePlayingQueue = true;
260 break;
261 }
262 if (freshCacheBuffer == nullptr) {
263 break;
264 }
265 if (freshCacheBuffer->GetPriority() >= playingCacheBuffer->GetPriority()) {
266 playingStreamIDs_.insert(playingStreamIDs_.begin() + i, streamID);
267 break;
268 }
269 if (playingStreamIDs_.size() >= 1 && i == playingStreamIDs_.size() - 1 &&
270 freshCacheBuffer->GetPriority() < playingCacheBuffer->GetPriority()) {
271 playingStreamIDs_.push_back(streamID);
272 break;
273 }
274 }
275 if (shouldReCombinePlayingQueue) {
276 QueueAndSortPlayingStreamID(streamID);
277 }
278 }
279 }
280
281 // Sort in descending order.
282 // 0 has the lowest priority, and the higher the value, the higher the priority
283 // The queue head has the highest value and priority
QueueAndSortWillPlayStreamID(StreamIDAndPlayParamsInfo freshStreamIDAndPlayParamsInfo)284 void StreamIDManager::QueueAndSortWillPlayStreamID(StreamIDAndPlayParamsInfo freshStreamIDAndPlayParamsInfo)
285 {
286 if (willPlayStreamInfos_.empty()) {
287 willPlayStreamInfos_.emplace_back(freshStreamIDAndPlayParamsInfo);
288 } else {
289 bool shouldReCombineWillPlayQueue = false;
290 for (size_t i = 0; i < willPlayStreamInfos_.size(); i++) {
291 std::shared_ptr<CacheBuffer> freshCacheBuffer = FindCacheBuffer(freshStreamIDAndPlayParamsInfo.streamID);
292 std::shared_ptr<CacheBuffer> willPlayCacheBuffer = FindCacheBuffer(willPlayStreamInfos_[i].streamID);
293 if (willPlayCacheBuffer == nullptr) {
294 willPlayStreamInfos_.erase(willPlayStreamInfos_.begin() + i);
295 shouldReCombineWillPlayQueue = true;
296 break;
297 }
298 if (freshCacheBuffer == nullptr) {
299 break;
300 }
301 if (freshCacheBuffer->GetPriority() >= willPlayCacheBuffer->GetPriority()) {
302 willPlayStreamInfos_.insert(willPlayStreamInfos_.begin() + i, freshStreamIDAndPlayParamsInfo);
303 break;
304 }
305 if (willPlayStreamInfos_.size() >= 1 && i == willPlayStreamInfos_.size() - 1 &&
306 freshCacheBuffer->GetPriority() < willPlayCacheBuffer->GetPriority()) {
307 willPlayStreamInfos_.push_back(freshStreamIDAndPlayParamsInfo);
308 break;
309 }
310 }
311 if (shouldReCombineWillPlayQueue) {
312 QueueAndSortWillPlayStreamID(freshStreamIDAndPlayParamsInfo);
313 }
314 }
315 }
316
AddPlayTask(const int32_t streamID,const PlayParams playParameters)317 int32_t StreamIDManager::AddPlayTask(const int32_t streamID, const PlayParams playParameters)
318 {
319 ThreadPool::Task streamPlayTask = [this, streamID] { this->DoPlay(streamID); };
320 CHECK_AND_RETURN_RET_LOG(streamPlayingThreadPool_ != nullptr, MSERR_INVALID_VAL,
321 "Failed to obtain playing ThreadPool");
322 CHECK_AND_RETURN_RET_LOG(streamPlayTask != nullptr, MSERR_INVALID_VAL, "Failed to obtain stream play Task");
323 streamPlayingThreadPool_->AddTask(streamPlayTask);
324 std::lock_guard lock(streamIDManagerLock_);
325 QueueAndSortPlayingStreamID(streamID);
326 return MSERR_OK;
327 }
328
DoPlay(const int32_t streamID)329 int32_t StreamIDManager::DoPlay(const int32_t streamID)
330 {
331 MEDIA_LOGI("StreamIDManager::DoPlay start streamID:%{public}d", streamID);
332 std::shared_ptr<CacheBuffer> cacheBuffer;
333 {
334 std::lock_guard lock(streamIDManagerLock_);
335 cacheBuffer = FindCacheBuffer(streamID);
336 }
337 CHECK_AND_RETURN_RET_LOG(cacheBuffer.get() != nullptr, MSERR_INVALID_VAL, "cachebuffer invalid.");
338 if (cacheBuffer->DoPlay(streamID) == MSERR_OK) {
339 MEDIA_LOGI("StreamIDManager::DoPlay success streamID:%{public}d", streamID);
340 return MSERR_OK;
341 }
342 MEDIA_LOGI("StreamIDManager::DoPlay failed streamID:%{public}d", streamID);
343 {
344 std::lock_guard lock(streamIDManagerLock_);
345 for (int32_t i = 0; i < static_cast<int32_t>(playingStreamIDs_.size()); i++) {
346 int32_t playingStreamID = playingStreamIDs_[i];
347 std::shared_ptr<CacheBuffer> playingCacheBuffer = FindCacheBuffer(playingStreamID);
348 if (playingCacheBuffer != nullptr && !playingCacheBuffer->IsRunning()) {
349 MEDIA_LOGI("StreamIDManager::DoPlay fail erase playingStreamID:%{public}d", playingStreamID);
350 playingStreamIDs_.erase(playingStreamIDs_.begin() + i);
351 i--;
352 }
353 }
354 }
355 return MSERR_INVALID_VAL;
356 }
357
FindCacheBuffer(const int32_t streamID)358 std::shared_ptr<CacheBuffer> StreamIDManager::FindCacheBuffer(const int32_t streamID)
359 {
360 if (cacheBuffers_.empty()) {
361 MEDIA_LOGI("StreamIDManager::FindCacheBuffer cacheBuffers_ empty");
362 return nullptr;
363 }
364 CHECK_AND_RETURN_RET_LOG(streamID >= 0, nullptr, "streamID invalid.");
365 auto it = cacheBuffers_.find(streamID);
366 if (it != cacheBuffers_.end()) {
367 return it->second;
368 }
369 return nullptr;
370 }
371
FindCacheBufferLock(const int32_t streamID)372 std::shared_ptr<CacheBuffer> StreamIDManager::FindCacheBufferLock(const int32_t streamID)
373 {
374 std::lock_guard lock(streamIDManagerLock_);
375 return FindCacheBuffer(streamID);
376 }
377
GetStreamIDBySoundID(const int32_t soundID)378 int32_t StreamIDManager::GetStreamIDBySoundID(const int32_t soundID)
379 {
380 PlayParams playParameters;
381 return GetFreshStreamID(soundID, playParameters);
382 }
383
ReorderStream(int32_t streamID,int32_t priority)384 int32_t StreamIDManager::ReorderStream(int32_t streamID, int32_t priority)
385 {
386 std::lock_guard lock(streamIDManagerLock_);
387 int32_t playingSize = static_cast<int32_t>(playingStreamIDs_.size());
388 for (int32_t i = 0; i < playingSize - 1; ++i) {
389 for (int32_t j = 0; j < playingSize - 1 - i; ++j) {
390 std::shared_ptr<CacheBuffer> left = FindCacheBuffer(playingStreamIDs_[j]);
391 std::shared_ptr<CacheBuffer> right = FindCacheBuffer(playingStreamIDs_[j + 1]);
392 if (left != nullptr && right != nullptr && left->GetPriority() < right->GetPriority()) {
393 int32_t streamIdTemp = playingStreamIDs_[j];
394 playingStreamIDs_[j] = playingStreamIDs_[j + 1];
395 playingStreamIDs_[j + 1] = streamIdTemp;
396 }
397 }
398 }
399 for (size_t i = 0; i < playingStreamIDs_.size(); i++) {
400 int32_t playingStreamID = playingStreamIDs_[i];
401 MEDIA_LOGD("StreamIDManager::ReorderStream playingStreamID:%{public}d", playingStreamID);
402 }
403
404 int32_t willPlaySize = static_cast<int32_t>(willPlayStreamInfos_.size());
405 for (int32_t i = 0; i < willPlaySize - 1; ++i) {
406 for (int32_t j = 0; j < willPlaySize - 1 - i; ++j) {
407 std::shared_ptr<CacheBuffer> left = FindCacheBuffer(willPlayStreamInfos_[j].streamID);
408 std::shared_ptr<CacheBuffer> right = FindCacheBuffer(willPlayStreamInfos_[j + 1].streamID);
409 if (left != nullptr && right != nullptr && left->GetPriority() < right->GetPriority()) {
410 StreamIDAndPlayParamsInfo willPlayInfoTemp = willPlayStreamInfos_[j];
411 willPlayStreamInfos_[j] = willPlayStreamInfos_[j + 1];
412 willPlayStreamInfos_[j + 1] = willPlayInfoTemp;
413 }
414 }
415 }
416 for (size_t i = 0; i < willPlayStreamInfos_.size(); i++) {
417 StreamIDAndPlayParamsInfo willPlayInfo = willPlayStreamInfos_[i];
418 MEDIA_LOGD("StreamIDManager::ReorderStream willPlayStreamID:%{public}d", willPlayInfo.streamID);
419 }
420 return MSERR_OK;
421 }
422
ClearStreamIDInDeque(int32_t streamID,int32_t soundID)423 int32_t StreamIDManager::ClearStreamIDInDeque(int32_t streamID, int32_t soundID)
424 {
425 {
426 std::lock_guard lock(streamIDManagerLock_);
427 for (auto it = playingStreamIDs_.begin(); it != playingStreamIDs_.end();) {
428 if (*it == streamID) {
429 MEDIA_LOGI("StreamIDManager::ClearStreamIDInDeque playingDel streamID:%{public}d", streamID);
430 it = playingStreamIDs_.erase(it);
431 } else {
432 ++it;
433 }
434 }
435 for (auto it = willPlayStreamInfos_.begin(); it != willPlayStreamInfos_.end();) {
436 if (it->streamID == streamID) {
437 MEDIA_LOGI("StreamIDManager::ClearStreamIDInDeque willPlayDel streamID:%{public}d", streamID);
438 it = willPlayStreamInfos_.erase(it);
439 } else {
440 ++it;
441 }
442 }
443 cacheBuffers_.erase(streamID);
444 }
445 DelSoundId(soundID);
446 return MSERR_OK;
447 }
448
GetFreshStreamID(const int32_t soundID,PlayParams playParameters)449 int32_t StreamIDManager::GetFreshStreamID(const int32_t soundID, PlayParams playParameters)
450 {
451 int32_t streamID = 0;
452 if (cacheBuffers_.empty()) {
453 MEDIA_LOGI("StreamIDManager::GetFreshStreamID cacheBuffers_ empty");
454 return streamID;
455 }
456 for (auto cacheBuffer : cacheBuffers_) {
457 if (cacheBuffer.second == nullptr) {
458 MEDIA_LOGE("Invalid cacheBuffer, soundID:%{public}d", soundID);
459 continue;
460 }
461 if (soundID == cacheBuffer.second->GetSoundID()) {
462 streamID = cacheBuffer.second->GetStreamID();
463 MEDIA_LOGI("Have cache soundID:%{public}d, streamID:%{public}d", soundID, streamID);
464 break;
465 }
466 }
467 return streamID;
468 }
469
OnPlayFinished()470 void StreamIDManager::OnPlayFinished()
471 {
472 {
473 std::lock_guard lock(streamIDManagerLock_);
474 for (int32_t i = 0; i < static_cast<int32_t>(playingStreamIDs_.size()); i++) {
475 int32_t playingStreamID = playingStreamIDs_[i];
476 std::shared_ptr<CacheBuffer> playingCacheBuffer = FindCacheBuffer(playingStreamID);
477 if (playingCacheBuffer != nullptr && !playingCacheBuffer->IsRunning()) {
478 MEDIA_LOGI("StreamIDManager::OnPlayFinished erase playingStreamID:%{public}d", playingStreamID);
479 playingStreamIDs_.erase(playingStreamIDs_.begin() + i);
480 i--;
481 }
482 }
483 }
484 if (!willPlayStreamInfos_.empty()) {
485 MEDIA_LOGI("StreamIDManager OnPlayFinished will play streams non empty, get the front.");
486 StreamIDAndPlayParamsInfo willPlayStreamInfo = willPlayStreamInfos_.front();
487 AddPlayTask(willPlayStreamInfo.streamID, willPlayStreamInfo.playParameters);
488 std::lock_guard lock(streamIDManagerLock_);
489 willPlayStreamInfos_.pop_front();
490 }
491 }
492
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)493 int32_t StreamIDManager::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
494 {
495 callback_ = callback;
496 return MSERR_OK;
497 }
498
SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> & callback)499 int32_t StreamIDManager::SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> &callback)
500 {
501 frameWriteCallback_ = callback;
502 return MSERR_OK;
503 }
504
OnLoadCompleted(int32_t soundID)505 void StreamIDManager::CacheBufferCallBack::OnLoadCompleted(int32_t soundID)
506 {
507 (void)soundID;
508 }
509
OnPlayFinished(int32_t streamID)510 void StreamIDManager::CacheBufferCallBack::OnPlayFinished(int32_t streamID)
511 {
512 (void)streamID;
513 if (std::shared_ptr<StreamIDManager> ptr = streamIDManagerInner_.lock()) {
514 ptr->OnPlayFinished();
515 }
516 }
517
OnError(int32_t errorCode)518 void StreamIDManager::CacheBufferCallBack::OnError(int32_t errorCode)
519 {
520 (void)errorCode;
521 }
522
523 } // namespace Media
524 } // namespace OHOS
525