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