• 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 #ifndef SOUND_PARSER_H
17 #define SOUND_PARSER_H
18 
19 #include <atomic>
20 #include <deque>
21 #include <memory>
22 #include <mutex>
23 #include "ashmem.h"
24 #include "avcodec_audio_decoder.h"
25 #include "avcodec_errors.h"
26 #include "avdemuxer.h"
27 #include "avsource.h"
28 #include "buffer/avsharedmemory.h"
29 #include "avcodec_codec_name.h"
30 #include "cache_buffer.h"
31 #include "isoundpool.h"
32 #include "media_description.h"
33 #include "media_errors.h"
34 #include "media_log.h"
35 #include "securec.h"
36 
37 namespace OHOS {
38 namespace Media {
39 using namespace MediaAVCodec;
40 
41 namespace {
42     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "SoundPool"};
43 }
44 
45 class SoundDecoderCallback : public AVCodecCallback, public NoCopyable {
46 public:
47     class SoundDecodeListener {
48     public:
SoundDecodeListener()49         SoundDecodeListener()
50         {
51             MEDIA_LOGI("Construction SoundDecodeListener");
52         }
~SoundDecodeListener()53         virtual ~SoundDecodeListener()
54         {
55             MEDIA_LOGI("Destruction SoundDecodeListener");
56         }
57         virtual void OnSoundDecodeCompleted(const std::deque<std::shared_ptr<AudioBufferEntry>>
58             &availableAudioBuffers) = 0;
59         virtual void SetSoundBufferTotalSize(const size_t soundBufferTotalSize) = 0;
60     };
61 
62     SoundDecoderCallback(const int32_t soundID, const std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> &audioDec,
63         const std::shared_ptr<MediaAVCodec::AVDemuxer> &demuxer, const bool isRawFile);
64     ~SoundDecoderCallback();
SetDecodeCallback(const std::shared_ptr<SoundDecodeListener> & listener)65     int32_t SetDecodeCallback(const std::shared_ptr<SoundDecodeListener> &listener)
66     {
67         MEDIA_LOGI("%{public}s:%{public}d", __func__, __LINE__);
68         CHECK_AND_RETURN_RET_LOG(listener != nullptr, MSERR_INVALID_VAL, "Invalid listener.");
69         listener_ = listener;
70         return MSERR_OK;
71     }
72     void OnError(AVCodecErrorType errorType, int32_t errorCode) override;
73     void OnOutputFormatChanged(const Format &format) override;
74     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override;
75     void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
76         std::shared_ptr<AVSharedMemory> buffer) override;
77 
78     int32_t SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback);
79     int32_t Release();
80 
81 private:
82     const int32_t soundID_;
83     std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDec_;
84     std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer_;
85     std::shared_ptr<SoundDecodeListener> listener_;
86     std::string trackMimeTypeInfo_;
87     bool isRawFile_ = false;
88     bool eosFlag_;
89     std::deque<std::shared_ptr<AudioBufferEntry>> availableAudioBuffers_;
90     bool decodeShouldCompleted_;
91     int32_t currentSoundBufferSize_;
92     std::condition_variable bufferCond_;
93     std::shared_ptr<ISoundPoolCallback> callback_ = nullptr;
94     std::mutex amutex_;
95 };
96 
97 class SoundParser : public std::enable_shared_from_this<SoundParser> {
98 public:
99     SoundParser(int32_t soundID, std::string url);
100     SoundParser(int32_t soundID, int32_t fd, int64_t offset, int64_t length);
101     ~SoundParser();
102     int32_t DoParser();
GetSoundID()103     int32_t GetSoundID() const
104     {
105         return soundID_;
106     }
107     int32_t GetSoundData(std::deque<std::shared_ptr<AudioBufferEntry>> &soundData) const;
108     size_t GetSoundDataTotalSize() const;
GetSoundTrackFormat()109     MediaAVCodec::Format GetSoundTrackFormat() const
110     {
111         return trackFormat_;
112     }
113     bool IsSoundParserCompleted() const;
114 
115     int32_t SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback);
116     int32_t Release();
117 
118 private:
119     class SoundParserListener : public SoundDecoderCallback::SoundDecodeListener {
120     public:
SoundParserListener(const std::weak_ptr<SoundParser> soundParser)121         explicit SoundParserListener(const std::weak_ptr<SoundParser> soundParser) : soundParserInner_(soundParser) {}
122 
OnSoundDecodeCompleted(const std::deque<std::shared_ptr<AudioBufferEntry>> & availableAudioBuffers)123         void OnSoundDecodeCompleted(const std::deque<std::shared_ptr<AudioBufferEntry>> &availableAudioBuffers) override
124         {
125             if (!soundParserInner_.expired()) {
126                 while (!soundParserInner_.lock()->soundParserLock_.try_lock()) {
127                     if (!soundParserInner_.lock()->isParsing_.load()) {
128                         return;
129                     }
130                 }
131                 soundData_ = availableAudioBuffers;
132                 isSoundParserCompleted_.store(true);
133                 soundParserInner_.lock()->soundParserLock_.unlock();
134             }
135         }
SetSoundBufferTotalSize(const size_t soundBufferTotalSize)136         void SetSoundBufferTotalSize(const size_t soundBufferTotalSize) override
137         {
138             if (!soundParserInner_.expired()) {
139                 while (!soundParserInner_.lock()->soundParserLock_.try_lock()) {
140                     if (!soundParserInner_.lock()->isParsing_.load()) {
141                         return;
142                     }
143                 }
144                 soundBufferTotalSize_ = soundBufferTotalSize;
145                 soundParserInner_.lock()->soundParserLock_.unlock();
146             }
147         }
GetSoundData(std::deque<std::shared_ptr<AudioBufferEntry>> & soundData)148         int32_t GetSoundData(std::deque<std::shared_ptr<AudioBufferEntry>> &soundData) const
149         {
150             std::unique_lock<std::mutex> lock(soundParserInner_.lock()->soundParserLock_);
151             soundData = soundData_;
152             return MSERR_OK;
153         }
154 
GetSoundDataTotalSize()155         size_t GetSoundDataTotalSize() const
156         {
157             std::unique_lock<std::mutex> lock(soundParserInner_.lock()->soundParserLock_);
158             return soundBufferTotalSize_;
159         }
IsSoundParserCompleted()160         bool IsSoundParserCompleted() const
161         {
162             std::unique_lock<std::mutex> lock(soundParserInner_.lock()->soundParserLock_);
163             return isSoundParserCompleted_.load();
164         }
165 
166     private:
167         std::weak_ptr<SoundParser> soundParserInner_;
168         std::deque<std::shared_ptr<AudioBufferEntry>> soundData_;
169         size_t soundBufferTotalSize_ = 0;
170         std::atomic<bool> isSoundParserCompleted_ = false;
171     };
172 
173     int32_t DoDemuxer(MediaAVCodec::Format *trackFormat);
174     int32_t DoDecode(MediaAVCodec::Format trackFormat);
175     int32_t soundID_;
176     std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer_;
177     std::shared_ptr<MediaAVCodec::AVSource> source_;
178     std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDec_;
179     std::shared_ptr<SoundDecoderCallback> audioDecCb_;
180     std::mutex soundParserLock_;
181     std::shared_ptr<SoundParserListener> soundParserListener_;
182     std::shared_ptr<ISoundPoolCallback> callback_ = nullptr;
183     bool isRawFile_ = false;
184     std::atomic<bool> isParsing_ = false;
185 
186     MediaAVCodec::Format trackFormat_;
187 
188     static constexpr int32_t AUDIO_SOURCE_TRACK_COUNT = 1;
189     static constexpr int32_t AUDIO_SOURCE_TRACK_INDEX = 0;
190     static constexpr int64_t MIN_FD = 0;
191 };
192 } // namespace Media
193 } // namespace OHOS
194 #endif // SOUND_PARSER_H
195