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 "cpp/mutex.h"
24  #include "ashmem.h"
25  #include "avcodec_audio_decoder.h"
26  #include "avcodec_errors.h"
27  #include "avdemuxer.h"
28  #include "avsource.h"
29  #include "buffer/avsharedmemory.h"
30  #include "avcodec_codec_name.h"
31  #include "cache_buffer.h"
32  #include "isoundpool.h"
33  #include "media_description.h"
34  #include "media_dfx.h"
35  #include "media_errors.h"
36  #include "media_log.h"
37  #include "securec.h"
38  
39  namespace OHOS {
40  namespace Media {
41  using namespace MediaAVCodec;
42  
43  class SoundDecoderCallback : public AVCodecCallback, public NoCopyable {
44  public:
45      class SoundDecodeListener {
46      public:
SoundDecodeListener()47          SoundDecodeListener()
48          {
49              (void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN_SOUNDPOOL, "SoundDecodeListener",
50                  "Construction SoundDecodeListener");
51          }
~SoundDecodeListener()52          virtual ~SoundDecodeListener()
53          {
54              (void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN_SOUNDPOOL, "SoundDecodeListener",
55                  "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          (void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN_SOUNDPOOL, "SoundDecoderCallback",
68              "%{public}s:%{public}d", __func__, __LINE__);
69          if (listener == nullptr) {
70              (void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN_SOUNDPOOL, "SoundDecodeListener", "Invalid listener");
71              return MSERR_INVALID_VAL;
72          }
73          listener_ = listener;
74          return MSERR_OK;
75      }
76      void OnError(AVCodecErrorType errorType, int32_t errorCode) override;
77      void OnOutputFormatChanged(const Format &format) override;
78      void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override;
79      void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
80          std::shared_ptr<AVSharedMemory> buffer) override;
81  
82      int32_t SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback);
83      int32_t Release();
84  
85  private:
86      void DealBufferRawFile(MediaAVCodec::AVCodecBufferFlag bufferFlag, MediaAVCodec::AVCodecBufferInfo sampleInfo,
87          uint32_t index, std::shared_ptr<AVSharedMemory> buffer);
88  
89      const int32_t soundID_;
90      std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDec_;
91      std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer_;
92      std::shared_ptr<SoundDecodeListener> listener_;
93      std::string trackMimeTypeInfo_;
94      bool isRawFile_ = false;
95      bool eosFlag_;
96      std::deque<std::shared_ptr<AudioBufferEntry>> availableAudioBuffers_;
97      bool decodeShouldCompleted_;
98      int32_t currentSoundBufferSize_;
99      std::condition_variable bufferCond_;
100      std::shared_ptr<ISoundPoolCallback> callback_ = nullptr;
101      std::mutex amutex_;
102  };
103  
104  class SoundParser : public std::enable_shared_from_this<SoundParser> {
105  public:
106      SoundParser(int32_t soundID, std::string url);
107      SoundParser(int32_t soundID, int32_t fd, int64_t offset, int64_t length);
108      ~SoundParser();
109      int32_t DoParser();
GetSoundID()110      int32_t GetSoundID() const
111      {
112          return soundID_;
113      }
114      int32_t GetSoundData(std::deque<std::shared_ptr<AudioBufferEntry>> &soundData) const;
115      size_t GetSoundDataTotalSize() const;
GetSoundTrackFormat()116      MediaAVCodec::Format GetSoundTrackFormat() const
117      {
118          return trackFormat_;
119      }
120      bool IsSoundParserCompleted() const;
121  
122      int32_t SetCallback(const std::shared_ptr<ISoundPoolCallback> &callback);
123      int32_t Release();
124  
125  private:
126      class SoundParserListener : public SoundDecoderCallback::SoundDecodeListener {
127      public:
SoundParserListener(const std::weak_ptr<SoundParser> soundParser)128          explicit SoundParserListener(const std::weak_ptr<SoundParser> soundParser) : soundParserInner_(soundParser) {}
129          void OnSoundDecodeCompleted(
130              const std::deque<std::shared_ptr<AudioBufferEntry>> &availableAudioBuffers) override;
131          void SetSoundBufferTotalSize(const size_t soundBufferTotalSize) override;
132          int32_t GetSoundData(std::deque<std::shared_ptr<AudioBufferEntry>> &soundData) const;
133          size_t GetSoundDataTotalSize() const;
134          bool IsSoundParserCompleted() const;
135  
136      private:
137          std::weak_ptr<SoundParser> soundParserInner_;
138          std::deque<std::shared_ptr<AudioBufferEntry>> soundData_;
139          size_t soundBufferTotalSize_ = 0;
140          std::atomic<bool> isSoundParserCompleted_ = false;
141      };
142  
143      int32_t DoDemuxer(MediaAVCodec::Format *trackFormat);
144      int32_t DoDecode(MediaAVCodec::Format trackFormat);
145      int32_t soundID_ = 0;
146      std::shared_ptr<MediaAVCodec::AVDemuxer> demuxer_;
147      std::shared_ptr<MediaAVCodec::AVSource> source_;
148      std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> audioDec_;
149      std::shared_ptr<SoundDecoderCallback> audioDecCb_;
150      ffrt::mutex soundParserLock_;
151      std::shared_ptr<SoundParserListener> soundParserListener_;
152      std::shared_ptr<ISoundPoolCallback> callback_ = nullptr;
153      bool isRawFile_ = false;
154      int32_t fdSource_ = -1;
155  
156      MediaAVCodec::Format trackFormat_;
157  
158      static constexpr int32_t AUDIO_SOURCE_TRACK_COUNT = 1;
159      static constexpr int32_t AUDIO_SOURCE_TRACK_INDEX = 0;
160      static constexpr int64_t MIN_FD = 3;
161  };
162  } // namespace Media
163  } // namespace OHOS
164  #endif // SOUND_PARSER_H
165