• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "CacheBuffer"};
24 }
25 
26 namespace OHOS {
27 namespace Media {
CacheBuffer(const Format & trackFormat,const std::deque<std::shared_ptr<AudioBufferEntry>> & cacheData,const size_t & cacheDataTotalSize,const int32_t & soundID,const int32_t & streamID,std::shared_ptr<ThreadPool> cacheBufferStopThreadPool)28 CacheBuffer::CacheBuffer(const Format &trackFormat,
29     const std::deque<std::shared_ptr<AudioBufferEntry>> &cacheData,
30     const size_t &cacheDataTotalSize, const int32_t &soundID, const int32_t &streamID,
31     std::shared_ptr<ThreadPool> cacheBufferStopThreadPool) : trackFormat_(trackFormat),
32     cacheData_(cacheData), cacheDataTotalSize_(cacheDataTotalSize), soundID_(soundID), streamID_(streamID),
33     cacheBufferStopThreadPool_(cacheBufferStopThreadPool), cacheDataFrameIndex_(0), havePlayedCount_(0)
34 
35 {
36     MEDIA_LOGI("Construction CacheBuffer soundID:%{public}d, streamID:%{public}d", soundID, streamID);
37 }
38 
~CacheBuffer()39 CacheBuffer::~CacheBuffer()
40 {
41     MEDIA_LOGI("Destruction CacheBuffer soundID:%{public}d, streamID:%{public}d", soundID_, streamID_);
42     Release();
43 }
44 
IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo & audioRendererInfo)45 bool CacheBuffer::IsAudioRendererCanMix(const AudioStandard::AudioRendererInfo &audioRendererInfo)
46 {
47     AudioStandard::AudioStreamType streamType = AudioStandard::AudioSystemManager::GetStreamType(
48         audioRendererInfo.contentType, audioRendererInfo.streamUsage);
49     if (streamType == AudioStandard::AudioStreamType::STREAM_MUSIC ||
50         streamType == AudioStandard::AudioStreamType::STREAM_MOVIE ||
51         streamType == AudioStandard::AudioStreamType::STREAM_SPEECH) {
52             return true;
53         }
54     return false;
55 }
56 
CreateAudioRenderer(const int32_t streamID,const AudioStandard::AudioRendererInfo audioRendererInfo,const PlayParams playParams)57 std::unique_ptr<AudioStandard::AudioRenderer> CacheBuffer::CreateAudioRenderer(const int32_t streamID,
58     const AudioStandard::AudioRendererInfo audioRendererInfo, const PlayParams playParams)
59 {
60     MediaTrace trace("CacheBuffer::CreateAudioRenderer");
61     CHECK_AND_RETURN_RET_LOG(streamID == streamID_, nullptr,
62         "Invalid streamID, failed to create normal audioRenderer.");
63     int32_t sampleRate;
64     int32_t sampleFormat;
65     int32_t channelCount;
66     AudioStandard::AudioRendererOptions rendererOptions = {};
67     // Set to PCM encoding
68     rendererOptions.streamInfo.encoding = AudioStandard::AudioEncodingType::ENCODING_PCM;
69     // Get sample rate from trackFormat and set it to audiorender.
70     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampleRate);
71     rendererOptions.streamInfo.samplingRate = static_cast<AudioStandard::AudioSamplingRate>(sampleRate);
72     // Get sample format from trackFormat and set it to audiorender.
73     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, sampleFormat);
74     // Align audiorender capability
75     rendererOptions.streamInfo.format = static_cast<AudioStandard::AudioSampleFormat>(sampleFormat);
76     // Get channel count from trackFormat and set it to audiorender.
77     trackFormat_.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channelCount);
78     rendererOptions.streamInfo.channels = static_cast<AudioStandard::AudioChannel>(channelCount);
79     // contentType streamUsage rendererFlags come from user.
80     if (IsAudioRendererCanMix(audioRendererInfo)) {
81         rendererOptions.strategy.concurrencyMode = AudioStandard::AudioConcurrencyMode::MIX_WITH_OTHERS;
82     }
83     rendererOptions.rendererInfo.contentType = audioRendererInfo.contentType;
84     rendererOptions.rendererInfo.streamUsage = audioRendererInfo.streamUsage;
85     rendererOptions.privacyType = AudioStandard::PRIVACY_TYPE_PUBLIC;
86     std::string cacheDir = "/data/storage/el2/base/temp";
87     if (playParams.cacheDir != "") {
88         cacheDir = playParams.cacheDir;
89     }
90 
91     rendererFlags_ = audioRendererInfo.rendererFlags;
92     rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
93     std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer =
94         AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
95 
96     if (audioRenderer == nullptr) {
97         MEDIA_LOGE("create audiorenderer failed, try again.");
98         rendererFlags_ = NORMAL_PLAY_RENDERER_FLAGS;
99         rendererOptions.rendererInfo.rendererFlags = rendererFlags_;
100         audioRenderer = AudioStandard::AudioRenderer::Create(cacheDir, rendererOptions);
101     }
102 
103     CHECK_AND_RETURN_RET_LOG(audioRenderer != nullptr, nullptr, "Invalid audioRenderer.");
104     size_t targetSize = 0;
105     int32_t ret = audioRenderer->GetBufferSize(targetSize);
106     audioRenderer->SetRenderMode(AudioStandard::AudioRenderMode::RENDER_MODE_CALLBACK);
107     if (ret == 0 && targetSize != 0 && !audioRenderer->IsFastRenderer()) {
108         size_t bufferDuration = 20; // 20 -> 20ms
109         audioRenderer->SetBufferDuration(bufferDuration);
110         MEDIA_LOGI("Using buffer size:%{public}zu, duration %{public}zu", targetSize, bufferDuration);
111     }
112     int32_t retCallback = audioRenderer->SetRendererWriteCallback(shared_from_this());
113     int32_t retFirstCallback = audioRenderer->SetRendererFirstFrameWritingCallback(shared_from_this());
114     MEDIA_LOGI("CacheBuffer::CreateAudioRenderer retCallback:%{public}d, retFirstCallback:%{public}d",
115         retCallback, retFirstCallback);
116     return audioRenderer;
117 }
118 
PreparePlay(const int32_t streamID,const AudioStandard::AudioRendererInfo audioRendererInfo,const PlayParams playParams)119 int32_t CacheBuffer::PreparePlay(const int32_t streamID, const AudioStandard::AudioRendererInfo audioRendererInfo,
120     const PlayParams playParams)
121 {
122     // create audioRenderer
123     if (audioRenderer_ == nullptr) {
124         MEDIA_LOGI("CacheBuffer::PreparePlay CreateAudioRenderer start streamID:%{public}d", streamID);
125         audioRenderer_ = CreateAudioRenderer(streamID, audioRendererInfo, playParams);
126         MEDIA_LOGI("CacheBuffer::PreparePlay CreateAudioRenderer end streamID:%{public}d", streamID);
127         ReCombineCacheData();
128     } else {
129         MEDIA_LOGI("CacheBuffer::PreparePlay audioRenderer inited, streamID:%{public}d", streamID);
130     }
131     // deal play params
132     DealPlayParamsBeforePlay(streamID, playParams);
133     return MSERR_OK;
134 }
135 
DoPlay(const int32_t streamID)136 int32_t CacheBuffer::DoPlay(const int32_t streamID)
137 {
138     MediaTrace trace("CacheBuffer::DoPlay");
139     CHECK_AND_RETURN_RET_LOG(streamID == streamID_, MSERR_INVALID_VAL, "Invalid streamID, failed to DoPlay.");
140     std::lock_guard lock(cacheBufferLock_);
141     CHECK_AND_RETURN_RET_LOG(fullCacheData_ != nullptr, MSERR_INVALID_VAL, "fullCacheData_ is nullptr.");
142     CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "Invalid audioRenderer.");
143     cacheDataFrameIndex_ = 0;
144     havePlayedCount_ = 0;
145     isRunning_.store(true);
146     if (!audioRenderer_->Start()) {
147         OHOS::AudioStandard::RendererState state = audioRenderer_->GetStatus();
148         if (state == OHOS::AudioStandard::RendererState::RENDERER_RUNNING) {
149             MEDIA_LOGI("CacheBuffer::DoPlay audioRenderer has started, streamID:%{public}d", streamID);
150             isRunning_.store(true);
151             if (callback_ != nullptr) {
152                 MEDIA_LOGI("CacheBuffer::DoPlay callback_ OnPlayFinished, streamID:%{public}d", streamID);
153                 callback_->OnPlayFinished();
154             }
155             return MSERR_OK;
156         } else {
157             MEDIA_LOGE("CacheBuffer::DoPlay audioRenderer start failed, streamID:%{public}d", streamID);
158             isRunning_.store(false);
159             if (callback_ != nullptr) {
160                 MEDIA_LOGI("CacheBuffer::DoPlay failed, call callback, streamID:%{public}d", streamID);
161                 callback_->OnError(MSERR_INVALID_VAL);
162             }
163             if (cacheBufferCallback_ != nullptr) cacheBufferCallback_->OnError(MSERR_INVALID_VAL);
164             return MSERR_INVALID_VAL;
165         }
166     }
167     MEDIA_LOGI("CacheBuffer::DoPlay success, streamID:%{public}d", streamID);
168     return MSERR_OK;
169 }
170 
ReCombineCacheData()171 int32_t CacheBuffer::ReCombineCacheData()
172 {
173     std::lock_guard lock(cacheBufferLock_);
174     CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "Invalid audioRenderer.");
175     CHECK_AND_RETURN_RET_LOG(!cacheData_.empty(), MSERR_INVALID_VAL, "empty cache data.");
176 
177     uint8_t *fullBuffer = new(std::nothrow) uint8_t[cacheDataTotalSize_];
178     CHECK_AND_RETURN_RET_LOG(fullBuffer != nullptr, MSERR_INVALID_VAL, "Invalid fullBuffer");
179     int32_t copyIndex = 0;
180     int32_t remainBufferSize = static_cast<int32_t>(cacheDataTotalSize_);
181     MEDIA_LOGI("ReCombine start copyIndex:%{public}d, remainSize:%{public}d", copyIndex, remainBufferSize);
182     for (std::shared_ptr<AudioBufferEntry> bufferEntry : cacheData_) {
183         if (bufferEntry != nullptr && bufferEntry->size > 0 && bufferEntry->buffer != nullptr) {
184             if (remainBufferSize < bufferEntry->size) {
185                 delete[] fullBuffer;
186                 MEDIA_LOGE("ReCombine not enough remainBufferSize:%{public}d, bufferEntry->size:%{public}d",
187                     remainBufferSize, bufferEntry->size);
188                 return MSERR_INVALID_VAL;
189             }
190             int32_t ret = memcpy_s(fullBuffer + copyIndex, remainBufferSize,
191                 bufferEntry->buffer, bufferEntry->size);
192             if (ret != MSERR_OK) {
193                 delete[] fullBuffer;
194                 MEDIA_LOGE("ReCombine memcpy failed");
195                 return MSERR_INVALID_VAL;
196             }
197             copyIndex += bufferEntry->size;
198             remainBufferSize -= bufferEntry->size;
199         } else {
200             MEDIA_LOGE("ReCombineCacheData, bufferEntry size:%{public}d, buffer:%{public}d",
201                 bufferEntry->size, bufferEntry->buffer != nullptr);
202         }
203     }
204     MEDIA_LOGI("ReCombine finish copyIndex:%{public}d, remainSize:%{public}d", copyIndex, remainBufferSize);
205 
206     fullCacheData_ = std::make_shared<AudioBufferEntry>(fullBuffer, cacheDataTotalSize_);
207 
208     if (!cacheData_.empty()) {
209         cacheData_.clear();
210     }
211 
212     return MSERR_OK;
213 }
214 
DealPlayParamsBeforePlay(const int32_t streamID,const PlayParams playParams)215 int32_t CacheBuffer::DealPlayParamsBeforePlay(const int32_t streamID, const PlayParams playParams)
216 {
217     std::lock_guard lock(cacheBufferLock_);
218     CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, MSERR_INVALID_VAL, "Invalid audioRenderer.");
219     audioRenderer_->SetOffloadAllowed(false);
220     loop_ = playParams.loop;
221     audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(playParams.rate));
222     audioRenderer_->SetVolume(playParams.leftVolume);
223     priority_ = playParams.priority;
224     audioRenderer_->SetParallelPlayFlag(playParams.parallelPlayFlag);
225     return MSERR_OK;
226 }
227 
CheckAndAlignRendererRate(const int32_t rate)228 AudioStandard::AudioRendererRate CacheBuffer::CheckAndAlignRendererRate(const int32_t rate)
229 {
230     AudioStandard::AudioRendererRate renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
231     switch (rate) {
232         case AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL:
233             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
234             break;
235         case AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE:
236             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_DOUBLE;
237             break;
238         case AudioStandard::AudioRendererRate::RENDER_RATE_HALF:
239             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_HALF;
240             break;
241         default:
242             renderRate = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
243             break;
244     }
245     return renderRate;
246 }
247 
OnWriteData(size_t length)248 void CacheBuffer::OnWriteData(size_t length)
249 {
250     if (audioRenderer_ == nullptr) {
251         MEDIA_LOGE("audioRenderer is nullptr.");
252         return;
253     }
254     if (!isRunning_.load()) {
255         MEDIA_LOGE("audioRenderer is stop.");
256         return;
257     }
258     if (cacheDataFrameIndex_ >= static_cast<size_t>(fullCacheData_->size)) {
259         cacheBufferLock_.lock();
260         if (loop_ >= 0 && havePlayedCount_ >= loop_) {
261             MEDIA_LOGI("CacheBuffer stream write finish, cacheDataFrameIndex_:%{public}zu,"
262                 " havePlayedCount_:%{public}d, loop:%{public}d, streamID_:%{public}d, length: %{public}zu",
263                 cacheDataFrameIndex_, havePlayedCount_, loop_, streamID_, length);
264             cacheBufferLock_.unlock();
265             int32_t streamIDStop = streamID_;
266             ThreadPool::Task cacheBufferStopTask = [this, streamIDStop] { this->Stop(streamIDStop); };
267             if (auto ptr = cacheBufferStopThreadPool_.lock()) {
268                 ptr->AddTask(cacheBufferStopTask);
269             }
270             return;
271         }
272         cacheDataFrameIndex_ = 0;
273         havePlayedCount_++;
274         cacheBufferLock_.unlock();
275     }
276     DealWriteData(length);
277 }
278 
DealWriteData(size_t length)279 void CacheBuffer::DealWriteData(size_t length)
280 {
281     std::lock_guard lock(cacheBufferLock_);
282     CHECK_AND_RETURN_LOG(audioRenderer_ != nullptr, "DealWriteData audioRenderer_ is nullptr");
283     AudioStandard::BufferDesc bufDesc;
284     audioRenderer_->GetBufferDesc(bufDesc);
285     if (bufDesc.buffer != nullptr && fullCacheData_ != nullptr && fullCacheData_->buffer != nullptr) {
286         if (static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_ >= length) {
287             int32_t ret = memcpy_s(bufDesc.buffer, length,
288                 fullCacheData_->buffer + cacheDataFrameIndex_, length);
289             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed total length.");
290             bufDesc.bufLength = length;
291             bufDesc.dataLength = length;
292             cacheDataFrameIndex_ += length;
293         } else {
294             size_t copyLength = static_cast<size_t>(fullCacheData_->size) - cacheDataFrameIndex_;
295             int32_t ret = memset_s(bufDesc.buffer, length, 0, length);
296             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memset failed.");
297             ret = memcpy_s(bufDesc.buffer, length, fullCacheData_->buffer + cacheDataFrameIndex_,
298                 copyLength);
299             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "memcpy failed not enough length.");
300             bufDesc.bufLength = length;
301             bufDesc.dataLength = length;
302             cacheDataFrameIndex_ += copyLength;
303         }
304         audioRenderer_->Enqueue(bufDesc);
305     } else {
306         MEDIA_LOGE("OnWriteData, cacheDataFrameIndex_: %{public}zu, length: %{public}zu,"
307             " bufDesc.buffer:%{public}d, fullCacheData_:%{public}d, fullCacheData_->buffer:%{public}d,"
308             " streamID_:%{public}d",
309             cacheDataFrameIndex_, length, bufDesc.buffer != nullptr, fullCacheData_ != nullptr,
310             fullCacheData_->buffer != nullptr, streamID_);
311     }
312 }
313 
OnFirstFrameWriting(uint64_t latency)314 void CacheBuffer::OnFirstFrameWriting(uint64_t latency)
315 {
316     MEDIA_LOGI("CacheBuffer::OnFirstFrameWriting, streamID_:%{public}d", streamID_);
317     CHECK_AND_RETURN_LOG(frameWriteCallback_ != nullptr, "frameWriteCallback is null.");
318     frameWriteCallback_->OnFirstAudioFrameWritingCallback(latency);
319 }
320 
Stop(const int32_t streamID)321 int32_t CacheBuffer::Stop(const int32_t streamID)
322 {
323     MediaTrace trace("CacheBuffer::Stop");
324     std::lock_guard lock(cacheBufferLock_);
325     if (streamID == streamID_) {
326         MEDIA_LOGI("CacheBuffer::Stop streamID:%{public}d", streamID_);
327         if (audioRenderer_ != nullptr && isRunning_.load()) {
328             isRunning_.store(false);
329             if (audioRenderer_->IsFastRenderer()) {
330                 MEDIA_LOGI("audioRenderer fast renderer pause.");
331                 audioRenderer_->Pause();
332                 audioRenderer_->Flush();
333             } else {
334                 MEDIA_LOGI("audioRenderer normal stop.");
335                 audioRenderer_->Stop();
336             }
337             cacheDataFrameIndex_ = 0;
338             havePlayedCount_ = 0;
339             if (callback_ != nullptr) {
340                 MEDIA_LOGI("cachebuffer callback_ OnPlayFinished.");
341                 callback_->OnPlayFinished();
342             }
343             if (cacheBufferCallback_ != nullptr) {
344                 MEDIA_LOGI("cachebuffer cacheBufferCallback_ OnPlayFinished.");
345                 cacheBufferCallback_->OnPlayFinished();
346             }
347         }
348         return MSERR_OK;
349     }
350     return MSERR_INVALID_VAL;
351 }
352 
SetVolume(const int32_t streamID,const float leftVolume,const float rightVolume)353 int32_t CacheBuffer::SetVolume(const int32_t streamID, const float leftVolume, const float rightVolume)
354 {
355     std::lock_guard lock(cacheBufferLock_);
356     int32_t ret = MSERR_OK;
357     if (streamID == streamID_) {
358         if (audioRenderer_ != nullptr) {
359             // audio cannot support left & right volume, all use left volume.
360             (void) rightVolume;
361             ret = audioRenderer_->SetVolume(leftVolume);
362         }
363     }
364     return ret;
365 }
366 
SetRate(const int32_t streamID,const AudioStandard::AudioRendererRate renderRate)367 int32_t CacheBuffer::SetRate(const int32_t streamID, const AudioStandard::AudioRendererRate renderRate)
368 {
369     std::lock_guard lock(cacheBufferLock_);
370     int32_t ret = MSERR_INVALID_VAL;
371     if (streamID == streamID_) {
372         if (audioRenderer_ != nullptr) {
373             ret = audioRenderer_->SetRenderRate(CheckAndAlignRendererRate(renderRate));
374         }
375     }
376     return ret;
377 }
378 
SetPriority(const int32_t streamID,const int32_t priority)379 int32_t CacheBuffer::SetPriority(const int32_t streamID, const int32_t priority)
380 {
381     std::lock_guard lock(cacheBufferLock_);
382     if (streamID == streamID_) {
383         priority_ = priority;
384     }
385     return MSERR_OK;
386 }
387 
SetLoop(const int32_t streamID,const int32_t loop)388 int32_t CacheBuffer::SetLoop(const int32_t streamID, const int32_t loop)
389 {
390     std::lock_guard lock(cacheBufferLock_);
391     if (streamID == streamID_) {
392         loop_ = loop;
393         havePlayedCount_ = 0;
394     }
395     return MSERR_OK;
396 }
397 
SetParallelPlayFlag(const int32_t streamID,const bool parallelPlayFlag)398 int32_t CacheBuffer::SetParallelPlayFlag(const int32_t streamID, const bool parallelPlayFlag)
399 {
400     std::lock_guard lock(cacheBufferLock_);
401     if (streamID == streamID_) {
402         MEDIA_LOGI("CacheBuffer parallelPlayFlag:%{public}d.", parallelPlayFlag);
403         if (audioRenderer_ != nullptr) {
404             audioRenderer_->SetParallelPlayFlag(parallelPlayFlag);
405         }
406     }
407     return MSERR_OK;
408 }
409 
Release()410 int32_t CacheBuffer::Release()
411 {
412     MediaTrace trace("CacheBuffer::Release");
413     // Define a temporary variable.Let audioRenderer_ to audioRenderer can protect audioRenderer_ concurrently
414     // modified.So will not cause null pointers.
415     std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer;
416     {
417         std::lock_guard lock(cacheBufferLock_);
418         audioRenderer = std::move(audioRenderer_);
419         audioRenderer_ = nullptr;
420         isRunning_.store(false);
421     }
422 
423     MEDIA_LOGI("CacheBuffer::Release start, streamID:%{public}d", streamID_);
424     // Use audioRenderer to release and don't lock, so it will not cause dead lock. if here locked, audioRenderer
425     // will wait callback thread stop, and the callback thread can't get the lock, it will cause dead lock
426     if (audioRenderer != nullptr) {
427         audioRenderer->Stop();
428         audioRenderer->Release();
429         audioRenderer = nullptr;
430     }
431 
432     std::lock_guard lock(cacheBufferLock_);
433     if (!cacheData_.empty()) cacheData_.clear();
434     if (fullCacheData_ != nullptr) fullCacheData_.reset();
435     if (callback_ != nullptr) callback_.reset();
436     if (cacheBufferCallback_ != nullptr) cacheBufferCallback_.reset();
437     if (frameWriteCallback_ != nullptr) frameWriteCallback_.reset();
438     MEDIA_LOGI("CacheBuffer::Release end, streamID:%{public}d", streamID_);
439     return MSERR_OK;
440 }
441 
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)442 int32_t CacheBuffer::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
443 {
444     callback_ = callback;
445     return MSERR_OK;
446 }
447 
SetCacheBufferCallback(const std::shared_ptr<ISoundPoolCallback> & callback)448 int32_t CacheBuffer::SetCacheBufferCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
449 {
450     cacheBufferCallback_ = callback;
451     return MSERR_OK;
452 }
453 
SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> & callback)454 int32_t CacheBuffer::SetFrameWriteCallback(const std::shared_ptr<ISoundPoolFrameWriteCallback> &callback)
455 {
456     frameWriteCallback_ = callback;
457     return MSERR_OK;
458 }
459 } // namespace Media
460 } // namespace OHOS
461