• 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 <fcntl.h>
17 #include <functional>
18 #include <cstdio>
19 #include "isoundpool.h"
20 #include "sound_parser.h"
21 
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SOUNDPOOL, "SoundParser"};
24     static constexpr int32_t MAX_SOUND_BUFFER_SIZE = 1 * 1024 * 1024;
25     static const std::string AUDIO_RAW_MIMETYPE_INFO = "audio/raw";
26     static const std::string AUDIO_MPEG_MIMETYPE_INFO = "audio/mpeg";
27     static constexpr int32_t MAX_CODEC_BUFFER_SIZE = 5 * 1024 * 1024;
28 }
29 
30 namespace OHOS {
31 namespace Media {
SoundParser(int32_t soundID,std::string url)32 SoundParser::SoundParser(int32_t soundID, std::string url)
33 {
34     std::shared_ptr<MediaAVCodec::AVSource> source = MediaAVCodec::AVSourceFactory::CreateWithURI(url);
35     CHECK_AND_RETURN_LOG(source != nullptr, "Create AVSource failed");
36     std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer = MediaAVCodec::AVDemuxerFactory::CreateWithSource(source);
37     CHECK_AND_RETURN_LOG(demuxer != nullptr, "Create AVDemuxer failed");
38     soundID_ = soundID;
39     demuxer_ = demuxer;
40     source_ = source;
41 }
42 
SoundParser(int32_t soundID,int32_t fd,int64_t offset,int64_t length)43 SoundParser::SoundParser(int32_t soundID, int32_t fd, int64_t offset, int64_t length)
44 {
45     fdSource_ = fcntl(fd, F_DUPFD_CLOEXEC, MIN_FD); // dup(fd) + close on exec to prevent leaks.
46     offset = offset >= INT64_MAX ? INT64_MAX : offset;
47     length = length >= INT64_MAX ? INT64_MAX : length;
48     MEDIA_LOGI("SoundParser::SoundParser fd:%{public}d, fdSource_:%{public}d,", fd, fdSource_);
49     std::shared_ptr<MediaAVCodec::AVSource> source =
50         MediaAVCodec::AVSourceFactory::CreateWithFD(fdSource_, offset, length);
51     CHECK_AND_RETURN_LOG(source != nullptr, "Create AVSource failed");
52     std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer = MediaAVCodec::AVDemuxerFactory::CreateWithSource(source);
53     CHECK_AND_RETURN_LOG(demuxer != nullptr, "Create AVDemuxer failed");
54 
55     soundID_ = soundID;
56     demuxer_ = demuxer;
57     source_ = source;
58 }
59 
~SoundParser()60 SoundParser::~SoundParser()
61 {
62     MEDIA_LOGI("SoundParser Destruction, soundID:%{public}d", soundID_);
63     Release();
64 }
65 
DoParser()66 int32_t SoundParser::DoParser()
67 {
68     MediaTrace trace("SoundParser::DoParser");
69     MEDIA_LOGI("SoundParser::DoParser start, soundID:%{public}d", soundID_);
70     std::unique_lock<ffrt::mutex> lock(soundParserLock_);
71     CHECK_AND_RETURN_RET_LOG(source_ != nullptr, MSERR_INVALID_VAL, "DoParser source_ is nullptr");
72     CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, MSERR_INVALID_VAL, "DoParser demuxer_ is nullptr");
73     int32_t result = MSERR_OK;
74     result = DoDemuxer(&trackFormat_);
75     if (result != MSERR_OK && callback_ != nullptr) {
76         MEDIA_LOGI("DoDemuxer failed, call callback");
77         callback_->OnError(MSERR_UNSUPPORT_FILE);
78         SoundPoolUtils::ErrorInfo errorInfo{
79             .errorCode = MSERR_UNSUPPORT_FILE,
80             .soundId = soundID_,
81             .errorType = ERROR_TYPE::LOAD_ERROR,
82             .callback = callback_};
83         SoundPoolUtils::SendErrorInfo(errorInfo);
84         return MSERR_INVALID_VAL;
85     } else if (result != MSERR_OK && callback_ == nullptr) {
86         MEDIA_LOGI("DoDemuxer failed, callback is nullptr");
87         return MSERR_INVALID_VAL;
88     }
89     result = DoDecode(trackFormat_);
90     if (result != MSERR_OK && callback_ != nullptr) {
91         MEDIA_LOGI("DoDecode failed, call callback");
92         callback_->OnError(MSERR_UNSUPPORT_FILE);
93         SoundPoolUtils::ErrorInfo errorInfo{
94             .errorCode = MSERR_UNSUPPORT_FILE,
95             .soundId = soundID_,
96             .errorType = ERROR_TYPE::LOAD_ERROR,
97             .callback = callback_};
98         SoundPoolUtils::SendErrorInfo(errorInfo);
99         return MSERR_INVALID_VAL;
100     } else if (result != MSERR_OK && callback_ == nullptr) {
101         MEDIA_LOGI("DoDecode failed, callback is nullptr");
102         return MSERR_INVALID_VAL;
103     }
104     MEDIA_LOGI("SoundParser::DoParser end, soundID:%{public}d", soundID_);
105     return MSERR_OK;
106 }
107 
DoDemuxer(MediaAVCodec::Format * trackFormat)108 int32_t SoundParser::DoDemuxer(MediaAVCodec::Format *trackFormat)
109 {
110     MediaTrace trace("SoundParser::DoDemuxer");
111     MEDIA_LOGI("SoundParser::DoDemuxer start, soundID:%{public}d", soundID_);
112     MediaAVCodec::Format sourceFormat;
113     int32_t sourceTrackCountInfo = 0;
114     int64_t sourceDurationInfo = 0;
115     CHECK_AND_RETURN_RET_LOG(source_ != nullptr, MSERR_INVALID_VAL, "Failed to obtain av source");
116     CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, MSERR_INVALID_VAL, "Failed to obtain demuxer");
117     CHECK_AND_RETURN_RET_LOG(trackFormat != nullptr, MSERR_INVALID_VAL, "Invalid trackFormat.");
118     int32_t ret = source_->GetSourceFormat(sourceFormat);
119     if (ret != 0) {
120         MEDIA_LOGE("Get source format failed:%{public}d", ret);
121     }
122     sourceFormat.GetIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_TRACK_COUNT, sourceTrackCountInfo);
123     sourceFormat.GetLongValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_DURATION, sourceDurationInfo);
124 
125     sourceDurationInfo_ = sourceDurationInfo;
126 
127     MEDIA_LOGI("SoundParser sourceTrackCountInfo:%{public}d", sourceTrackCountInfo);
128     for (int32_t sourceTrackIndex = 0; sourceTrackIndex < sourceTrackCountInfo; sourceTrackIndex++) {
129         int32_t trackType = 0;
130         ret = source_->GetTrackFormat(*trackFormat, sourceTrackIndex);
131         if (ret != 0) {
132             MEDIA_LOGE("Get track format failed:%{public}d", ret);
133         }
134         trackFormat->GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_TYPE, trackType);
135         MEDIA_LOGI("SoundParser trackType:%{public}d", trackType);
136         if (trackType == MEDIA_TYPE_AUD) {
137             demuxer_->SelectTrackByID(sourceTrackIndex);
138             std::string trackMimeTypeInfo;
139             trackFormat->GetStringValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME, trackMimeTypeInfo);
140             if (AUDIO_RAW_MIMETYPE_INFO.compare(trackMimeTypeInfo) != 0) {
141                 // resample format
142                 trackFormat->PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT,
143                     MediaAVCodec::SAMPLE_S16LE);
144             } else {
145                 isRawFile_ = true;
146                 trackFormat->PutStringValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME,
147                     AUDIO_MPEG_MIMETYPE_INFO);
148             }
149             break;
150         }
151     }
152     MEDIA_LOGI("SoundParser::DoDemuxer end, soundID:%{public}d", soundID_);
153     return MSERR_OK;
154 }
155 
DoDecode(MediaAVCodec::Format & trackFormat)156 int32_t SoundParser::DoDecode(MediaAVCodec::Format &trackFormat)
157 {
158     MediaTrace trace("SoundParser::DoDecode");
159     MEDIA_LOGI("SoundParser::DoDecode start, soundID:%{public}d", soundID_);
160     int32_t trackTypeInfo;
161     trackFormat.GetIntValue(MediaDescriptionKey::MD_KEY_TRACK_TYPE, trackTypeInfo);
162     if (trackTypeInfo == MEDIA_TYPE_AUD) {
163         std::string trackMimeTypeInfo;
164         trackFormat.GetStringValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME, trackMimeTypeInfo);
165         MEDIA_LOGI("SoundParser mime type:%{public}s", trackMimeTypeInfo.c_str());
166         audioDec_ = MediaAVCodec::AudioDecoderFactory::CreateByMime(trackMimeTypeInfo);
167         CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, MSERR_INVALID_VAL, "Failed to obtain audioDecorder.");
168         int32_t ret = audioDec_->Configure(trackFormat);
169         CHECK_AND_RETURN_RET_LOG(ret == 0, MSERR_INVALID_VAL, "Failed to configure audioDecorder.");
170         audioDecCb_ = std::make_shared<SoundDecoderCallback>(soundID_, audioDec_, demuxer_, isRawFile_);
171         CHECK_AND_RETURN_RET_LOG(audioDecCb_ != nullptr, MSERR_INVALID_VAL, "Failed to obtain decode callback.");
172         ret = audioDec_->SetCallback(audioDecCb_);
173         CHECK_AND_RETURN_RET_LOG(ret == 0, MSERR_INVALID_VAL, "Failed to setCallback audioDecorder");
174         soundParserListener_ = std::make_shared<SoundParserListener>(weak_from_this());
175         CHECK_AND_RETURN_RET_LOG(soundParserListener_ != nullptr, MSERR_INVALID_VAL, "Invalid sound parser listener");
176         audioDecCb_->SetDecodeCallback(soundParserListener_);
177         if (callback_ != nullptr) audioDecCb_->SetCallback(callback_);
178         ret = audioDec_->Start();
179         CHECK_AND_RETURN_RET_LOG(ret == 0, MSERR_INVALID_VAL, "Failed to Start audioDecorder.");
180         MEDIA_LOGI("SoundParser::DoDecode, audioDec_ started, soundID:%{public}d", soundID_);
181     }
182     return MSERR_OK;
183 }
184 
GetSoundData(std::shared_ptr<AudioBufferEntry> & soundData) const185 int32_t SoundParser::GetSoundData(std::shared_ptr<AudioBufferEntry> &soundData) const
186 {
187     CHECK_AND_RETURN_RET_LOG(soundParserListener_ != nullptr, MSERR_INVALID_VAL, "Invalid sound parser listener");
188     return soundParserListener_->GetSoundData(soundData);
189 }
190 
GetSoundDataTotalSize() const191 size_t SoundParser::GetSoundDataTotalSize() const
192 {
193     CHECK_AND_RETURN_RET_LOG(soundParserListener_ != nullptr, 0, "Invalid sound parser listener");
194     return soundParserListener_->GetSoundDataTotalSize();
195 }
196 
IsSoundParserCompleted() const197 bool SoundParser::IsSoundParserCompleted() const
198 {
199     CHECK_AND_RETURN_RET_LOG(soundParserListener_ != nullptr, false, "Invalid sound parser listener");
200     return soundParserListener_->IsSoundParserCompleted();
201 }
202 
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)203 int32_t SoundParser::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
204 {
205     callback_ = callback;
206     return MSERR_OK;
207 }
208 
GetSourceDuration()209 int64_t SoundParser::GetSourceDuration()
210 {
211     return sourceDurationInfo_;
212 }
213 
Release()214 int32_t SoundParser::Release()
215 {
216     MediaTrace trace("SoundParser::Release");
217     MEDIA_LOGI("SoundParser::Release start, soundID:%{public}d", soundID_);
218     int32_t ret = MSERR_OK;
219     std::shared_ptr<SoundDecoderCallback> audioDecCbRelease;
220     {
221         std::unique_lock<ffrt::mutex> lock(soundParserLock_);
222         if (soundParserListener_ != nullptr) soundParserListener_.reset();
223         audioDecCbRelease = std::move(audioDecCb_);
224         audioDecCb_ = nullptr;
225     }
226     if (audioDecCbRelease != nullptr) {
227         ret = audioDecCbRelease->Release();
228         audioDecCbRelease.reset();
229     }
230     std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDecRelease;
231     {
232         std::unique_lock<ffrt::mutex> lock(soundParserLock_);
233         audioDecRelease = std::move(audioDec_);
234         audioDec_ = nullptr;
235     }
236     if (audioDecRelease != nullptr) {
237         ret = audioDecRelease->Release();
238         audioDecRelease.reset();
239     }
240     std::unique_lock<ffrt::mutex> lock(soundParserLock_);
241     if (demuxer_ != nullptr) demuxer_.reset();
242     if (source_ != nullptr) source_.reset();
243     if (callback_ != nullptr) callback_.reset();
244     if (fdSource_ > 0) {
245         MEDIA_LOGI("SoundParser::Release() fdSource_:%{public}d", fdSource_);
246         (void)close(fdSource_);
247         fdSource_ = -1;
248     }
249     MEDIA_LOGI("SoundParser::Release end, soundID:%{public}d", soundID_);
250     return ret;
251 }
252 
SoundDecoderCallback(const int32_t soundID,const std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> & audioDec,const std::shared_ptr<MediaAVCodec::AVDemuxer> & demuxer,const bool isRawFile)253 SoundDecoderCallback::SoundDecoderCallback(const int32_t soundID,
254     const std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> &audioDec,
255     const std::shared_ptr<MediaAVCodec::AVDemuxer> &demuxer,
256     const bool isRawFile) : soundID_(soundID), audioDec_(audioDec),
257     demuxer_(demuxer), isRawFile_(isRawFile), eosFlag_(false),
258     decodeShouldCompleted_(false), currentSoundBufferSize_(0)
259 {
260     MEDIA_LOGI("Construction SoundDecoderCallback");
261 }
262 
~SoundDecoderCallback()263 SoundDecoderCallback::~SoundDecoderCallback()
264 {
265     MEDIA_LOGI("Destruction SoundDecoderCallback");
266     Release();
267 }
OnError(AVCodecErrorType errorType,int32_t errorCode)268 void SoundDecoderCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
269 {
270     if (isRawFile_) {
271         MEDIA_LOGI("Recive error, errorType:%{public}d,errorCode:%{public}d", errorType, errorCode);
272     }
273 }
274 
OnOutputFormatChanged(const Format & format)275 void SoundDecoderCallback::OnOutputFormatChanged(const Format &format)
276 {
277     (void)format;
278 }
279 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)280 void SoundDecoderCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
281 {
282     amutex_.lock();
283     MediaAVCodec::AVCodecBufferFlag bufferFlag = MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE;
284     MediaAVCodec::AVCodecBufferInfo sampleInfo;
285     if (demuxer_ == nullptr || audioDec_ == nullptr) {
286         MEDIA_LOGE("SoundDecoderCallback Input demuxer_:%{public}d, audioDec_:%{public}d,",
287             demuxer_ == nullptr, audioDec_ == nullptr);
288         amutex_.unlock();
289         return;
290     }
291 
292     if (buffer != nullptr && isRawFile_ && !decodeShouldCompleted_) {
293         DealBufferRawFile(bufferFlag, sampleInfo, index, buffer);
294         amutex_.unlock();
295         return;
296     }
297 
298     if (buffer != nullptr && !eosFlag_ && !decodeShouldCompleted_) {
299         if (demuxer_->ReadSample(0, buffer, sampleInfo, bufferFlag) != AVCS_ERR_OK) {
300             MEDIA_LOGE("SoundDecoderCallback demuxer error.");
301             amutex_.unlock();
302             return;
303         }
304         if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
305             eosFlag_ = true;
306         }
307         audioDec_->QueueInputBuffer(index, sampleInfo, bufferFlag);
308     }
309     amutex_.unlock();
310 }
311 
DealBufferRawFile(MediaAVCodec::AVCodecBufferFlag bufferFlag,MediaAVCodec::AVCodecBufferInfo sampleInfo,uint32_t index,std::shared_ptr<AVSharedMemory> buffer)312 void SoundDecoderCallback::DealBufferRawFile(MediaAVCodec::AVCodecBufferFlag bufferFlag,
313     MediaAVCodec::AVCodecBufferInfo sampleInfo, uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
314 {
315     if (demuxer_->ReadSample(0, buffer, sampleInfo, bufferFlag) != AVCS_ERR_OK) {
316         MEDIA_LOGE("SoundDecoderCallback demuxer error.");
317         return;
318     }
319     if (!decodeShouldCompleted_ && (currentSoundBufferSize_ > MAX_SOUND_BUFFER_SIZE ||
320             bufferFlag == AVCODEC_BUFFER_FLAG_EOS)) {
321         decodeShouldCompleted_ = true;
322         ReCombineCacheData();
323         CHECK_AND_RETURN_LOG(listener_ != nullptr, "sound decode listener invalid.");
324         listener_->OnSoundDecodeCompleted(fullCacheData_);
325         listener_->SetSoundBufferTotalSize(static_cast<size_t>(currentSoundBufferSize_));
326         CHECK_AND_RETURN_LOG(callback_ != nullptr, "sound decode:soundpool callback invalid.");
327         callback_->OnLoadCompleted(soundID_);
328         return;
329     }
330     int32_t size = sampleInfo.size;
331     uint8_t *buf = new(std::nothrow) uint8_t[size];
332     if (buf != nullptr) {
333         if (memcpy_s(buf, size, buffer->GetBase(), size) != EOK) {
334             delete[] buf;
335             MEDIA_LOGI("audio buffer copy failed:%{public}s", strerror(errno));
336         } else {
337             availableAudioBuffers_.push_back(std::make_shared<AudioBufferEntry>(buf, size));
338         }
339     }
340     currentSoundBufferSize_ += size;
341     audioDec_->QueueInputBuffer(index, sampleInfo, bufferFlag);
342     return;
343 }
344 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)345 void SoundDecoderCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
346     std::shared_ptr<AVSharedMemory> buffer)
347 {
348     amutex_.lock();
349     if (demuxer_ == nullptr || audioDec_ == nullptr) {
350         MEDIA_LOGE("SoundDecoderCallback Output demuxer_:%{public}d, audioDec_:%{public}d,",
351             demuxer_ == nullptr, audioDec_ == nullptr);
352         amutex_.unlock();
353         return;
354     }
355     if (isRawFile_) {
356         audioDec_->ReleaseOutputBuffer(index);
357         amutex_.unlock();
358         return;
359     }
360     if (buffer != nullptr && !decodeShouldCompleted_) {
361         if (currentSoundBufferSize_ > MAX_SOUND_BUFFER_SIZE || flag == AVCODEC_BUFFER_FLAG_EOS) {
362             decodeShouldCompleted_ = true;
363             ReCombineCacheData();
364             if (listener_ != nullptr) {
365                 listener_->OnSoundDecodeCompleted(fullCacheData_);
366                 listener_->SetSoundBufferTotalSize(static_cast<size_t>(currentSoundBufferSize_));
367             }
368             if (callback_ != nullptr) {
369                 callback_->OnLoadCompleted(soundID_);
370             }
371             amutex_.unlock();
372             return;
373         }
374         int32_t size = info.size;
375         if (size <= 0 || size > MAX_CODEC_BUFFER_SIZE) {
376             MEDIA_LOGE("SoundDecoderCallback output size :%{public}d", size);
377             amutex_.unlock();
378             return;
379         }
380         uint8_t *buf = new(std::nothrow) uint8_t[size];
381         if (buf != nullptr) {
382             if (memcpy_s(buf, size, buffer->GetBase(), info.size) != EOK) {
383                 delete[] buf;
384                 MEDIA_LOGI("audio buffer copy failed:%{public}s", strerror(errno));
385             } else {
386                 availableAudioBuffers_.push_back(std::make_shared<AudioBufferEntry>(buf, size));
387             }
388         }
389         currentSoundBufferSize_ += size;
390     }
391     audioDec_->ReleaseOutputBuffer(index);
392     amutex_.unlock();
393 }
394 
ReCombineCacheData()395 int32_t SoundDecoderCallback::ReCombineCacheData()
396 {
397     MEDIA_LOGI("ReCombine start currentSoundBufferSize_:%{public}d", currentSoundBufferSize_);
398     uint8_t *fullBuffer = new(std::nothrow) uint8_t[currentSoundBufferSize_];
399     CHECK_AND_RETURN_RET_LOG(fullBuffer != nullptr, MSERR_INVALID_VAL, "Invalid fullBuffer");
400     int32_t copyIndex = 0;
401     int32_t remainBufferSize = static_cast<int32_t>(currentSoundBufferSize_);
402     MEDIA_LOGI("ReCombine start copyIndex:%{public}d, remainSize:%{public}d", copyIndex, remainBufferSize);
403     for (std::shared_ptr<AudioBufferEntry> bufferEntry : availableAudioBuffers_) {
404         if (bufferEntry != nullptr && bufferEntry->size > 0 && bufferEntry->buffer != nullptr) {
405             if (remainBufferSize < bufferEntry->size) {
406                 delete[] fullBuffer;
407                 MEDIA_LOGE("ReCombine not enough remainBufferSize:%{public}d, bufferEntry->size:%{public}d",
408                     remainBufferSize, bufferEntry->size);
409                 return MSERR_INVALID_VAL;
410             }
411             int32_t ret = memcpy_s(fullBuffer + copyIndex, remainBufferSize,
412                 bufferEntry->buffer, bufferEntry->size);
413             if (ret != MSERR_OK) {
414                 delete[] fullBuffer;
415                 MEDIA_LOGE("ReCombine memcpy failed");
416                 return MSERR_INVALID_VAL;
417             }
418             copyIndex += bufferEntry->size;
419             remainBufferSize -= bufferEntry->size;
420         } else if (bufferEntry != nullptr) {
421             MEDIA_LOGE("ReCombineCacheData, bufferEntry size:%{public}d, buffer:%{public}d",
422                 bufferEntry->size, bufferEntry->buffer != nullptr);
423         } else {
424             MEDIA_LOGE("ReCombineCacheData, bufferEntry is null !");
425         }
426     }
427     MEDIA_LOGI("ReCombine finish copyIndex:%{public}d, remainSize:%{public}d", copyIndex, remainBufferSize);
428 
429     fullCacheData_ = std::make_shared<AudioBufferEntry>(fullBuffer, currentSoundBufferSize_);
430 
431     if (!availableAudioBuffers_.empty()) {
432         availableAudioBuffers_.clear();
433     }
434     return MSERR_OK;
435 }
436 
SetCallback(const std::shared_ptr<ISoundPoolCallback> & callback)437 int32_t SoundDecoderCallback::SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback)
438 {
439     MEDIA_LOGI("SoundDecoderCallback::SetCallback");
440     callback_ = callback;
441     return MSERR_OK;
442 }
443 
Release()444 int32_t SoundDecoderCallback::Release()
445 {
446     int32_t ret = MSERR_OK;
447     MEDIA_LOGI("SoundDecoderCallback::Release");
448     //here use audioDec, the reason is the same reason in CacheBuffer::Release().please check it
449     //in CacheBuffer::Release()
450     std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDec;
451     {
452         std::lock_guard lock(amutex_);
453         audioDec = std::move(audioDec_);
454         audioDec_ = nullptr;
455     }
456     if (audioDec != nullptr) {
457         ret = audioDec->Release();
458         audioDec.reset();
459         audioDec = nullptr;
460     }
461     std::lock_guard lock(amutex_);
462     if (demuxer_ != nullptr) demuxer_.reset();
463     if (listener_ != nullptr) listener_.reset();
464     if (!availableAudioBuffers_.empty()) availableAudioBuffers_.clear();
465     if (callback_ != nullptr) callback_.reset();
466     if (fullCacheData_ != nullptr) fullCacheData_.reset();
467     return ret;
468 }
469 
OnSoundDecodeCompleted(const std::shared_ptr<AudioBufferEntry> & fullCacheData)470 void SoundParser::SoundParserListener::OnSoundDecodeCompleted(
471     const std::shared_ptr<AudioBufferEntry> &fullCacheData)
472 {
473     if (std::shared_ptr<SoundParser> soundPaser = soundParserInner_.lock()) {
474         std::unique_lock<ffrt::mutex> lock(soundPaser->soundParserLock_);
475         soundData_ = fullCacheData;
476         isSoundParserCompleted_.store(true);
477     }
478 }
479 
SetSoundBufferTotalSize(const size_t soundBufferTotalSize)480 void SoundParser::SoundParserListener::SetSoundBufferTotalSize(const size_t soundBufferTotalSize)
481 {
482     if (std::shared_ptr<SoundParser> soundPaser = soundParserInner_.lock()) {
483         std::unique_lock<ffrt::mutex> lock(soundPaser->soundParserLock_);
484         soundBufferTotalSize_ = soundBufferTotalSize;
485     }
486 }
487 
GetSoundData(std::shared_ptr<AudioBufferEntry> & soundData) const488 int32_t SoundParser::SoundParserListener::GetSoundData(
489     std::shared_ptr<AudioBufferEntry> &soundData) const
490 {
491     if (std::shared_ptr<SoundParser> soundPaser = soundParserInner_.lock()) {
492         std::unique_lock<ffrt::mutex> lock(soundPaser->soundParserLock_);
493         soundData = soundData_;
494     }
495     return MSERR_OK;
496 }
497 
GetSoundDataTotalSize() const498 size_t SoundParser::SoundParserListener::GetSoundDataTotalSize() const
499 {
500     return soundBufferTotalSize_;
501 }
502 
IsSoundParserCompleted() const503 bool SoundParser::SoundParserListener::IsSoundParserCompleted() const
504 {
505     return isSoundParserCompleted_.load();
506 }
507 
508 } // namespace Media
509 } // namespace OHOS
510