tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WaveDemuxer.h (5718B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * Licence, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef WAV_DEMUXER_H_
      6 #define WAV_DEMUXER_H_
      7 
      8 #include "MediaDataDemuxer.h"
      9 #include "MediaResource.h"
     10 
     11 namespace mozilla {
     12 class BufferReader;
     13 
     14 static const uint32_t FRMT_CODE = 0x666d7420;
     15 static const uint32_t DATA_CODE = 0x64617461;
     16 static const uint32_t LIST_CODE = 0x4c495354;
     17 static const uint32_t INFO_CODE = 0x494e464f;
     18 
     19 static const uint8_t RIFF[4] = {'R', 'I', 'F', 'F'};
     20 static const uint8_t WAVE[4] = {'W', 'A', 'V', 'E'};
     21 
     22 static const uint16_t RIFF_CHUNK_SIZE = 12;
     23 static const uint16_t CHUNK_HEAD_SIZE = 8;
     24 static const uint16_t FMT_CHUNK_MIN_SIZE = 16;
     25 static const uint16_t DATA_CHUNK_SIZE = 768;
     26 
     27 class WAVTrackDemuxer;
     28 
     29 DDLoggedTypeDeclNameAndBase(WAVDemuxer, MediaDataDemuxer);
     30 DDLoggedTypeNameAndBase(WAVTrackDemuxer, MediaTrackDemuxer);
     31 
     32 class WAVDemuxer : public MediaDataDemuxer,
     33                   public DecoderDoctorLifeLogger<WAVDemuxer> {
     34 public:
     35  // MediaDataDemuxer interface.
     36  explicit WAVDemuxer(MediaResource* aSource);
     37  RefPtr<InitPromise> Init() override;
     38  uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
     39  already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
     40      TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
     41  bool IsSeekable() const override;
     42 
     43 private:
     44  // Synchronous Initialization.
     45  bool InitInternal();
     46 
     47  MediaResourceIndex mSource;
     48  RefPtr<WAVTrackDemuxer> mTrackDemuxer;
     49 };
     50 
     51 class RIFFParser {
     52 private:
     53  class RIFFHeader;
     54 
     55 public:
     56  const RIFFHeader& RiffHeader() const;
     57 
     58  Result<uint32_t, nsresult> Parse(BufferReader& aReader);
     59 
     60  void Reset();
     61 
     62 private:
     63  class RIFFHeader {
     64   public:
     65    RIFFHeader();
     66    void Reset();
     67 
     68    bool IsValid() const;
     69    bool IsValid(int aPos) const;
     70 
     71    bool ParseNext(uint8_t c);
     72 
     73   private:
     74    bool Update(uint8_t c);
     75 
     76    uint8_t mRaw[RIFF_CHUNK_SIZE] = {};
     77 
     78    int mPos = 0;
     79  };
     80 
     81  RIFFHeader mRiffHeader;
     82 };
     83 
     84 class HeaderParser {
     85 private:
     86  class ChunkHeader;
     87 
     88 public:
     89  const ChunkHeader& GiveHeader() const;
     90 
     91  Result<uint32_t, nsresult> Parse(BufferReader& aReader);
     92 
     93  void Reset();
     94 
     95 private:
     96  class ChunkHeader {
     97   public:
     98    ChunkHeader();
     99    void Reset();
    100 
    101    bool IsValid() const;
    102 
    103    uint32_t ChunkName() const;
    104    uint32_t ChunkSize() const;
    105 
    106    bool ParseNext(uint8_t c);
    107 
    108   private:
    109    void Update(uint8_t c);
    110 
    111    uint8_t mRaw[CHUNK_HEAD_SIZE] = {};
    112 
    113    int mPos = 0;
    114  };
    115 
    116  ChunkHeader mHeader;
    117 };
    118 
    119 class FormatChunk {
    120 public:
    121  FormatChunk() = default;
    122  void Init(nsTArray<uint8_t>&& aData);
    123 
    124  uint16_t WaveFormat() const;
    125  uint16_t Channels() const;
    126  uint32_t SampleRate() const;
    127  uint16_t ExtraFormatInfoSize() const;
    128  uint16_t SampleFormat() const;
    129  uint16_t AverageBytesPerSec() const;
    130  uint16_t BlockAlign() const;
    131  uint16_t ValidBitsPerSamples() const;
    132  AudioConfig::ChannelLayout::ChannelMap ChannelMap() const;
    133 
    134 private:
    135  nsTArray<uint8_t> mRaw;
    136 };
    137 
    138 class DataParser {
    139 private:
    140  class DataChunk;
    141 
    142 public:
    143  DataParser();
    144 
    145  const DataChunk& CurrentChunk() const;
    146 
    147  void Reset();
    148 
    149 private:
    150  class DataChunk {
    151   public:
    152    void Reset();
    153 
    154   private:
    155    int mPos = 0;  // To Check Alignment
    156  };
    157 
    158  DataChunk mChunk;
    159 };
    160 
    161 class WAVTrackDemuxer : public MediaTrackDemuxer,
    162                        public DecoderDoctorLifeLogger<WAVTrackDemuxer> {
    163 public:
    164  explicit WAVTrackDemuxer(MediaResource* aSource);
    165 
    166  bool Init();
    167 
    168  int64_t StreamLength() const;
    169 
    170  media::TimeUnit Duration() const;
    171  media::TimeUnit Duration(int64_t aNumDataChunks) const;
    172  media::TimeUnit DurationFromBytes(uint32_t aNumBytes) const;
    173 
    174  media::TimeUnit SeekPosition() const;
    175 
    176  RefPtr<MediaRawData> DemuxSample();
    177 
    178  // MediaTrackDemuxer interface.
    179  UniquePtr<TrackInfo> GetInfo() const override;
    180  RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;
    181  RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples) override;
    182  void Reset() override;
    183  RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
    184      const media::TimeUnit& aTimeThreshold) override;
    185  int64_t GetResourceOffset() const override;
    186  media::TimeIntervals GetBuffered() override;
    187 
    188 private:
    189  ~WAVTrackDemuxer() = default;
    190 
    191  media::TimeUnit FastSeek(const media::TimeUnit& aTime);
    192  media::TimeUnit ScanUntil(const media::TimeUnit& aTime);
    193 
    194  MediaByteRange FindNextChunk();
    195 
    196  MediaByteRange FindChunkHeader();
    197  MediaByteRange FindRIFFHeader();
    198  MediaByteRange FindFmtChunk();
    199  MediaByteRange FindListChunk();
    200  MediaByteRange FindInfoTag();
    201 
    202  bool RIFFParserInit();
    203  bool HeaderParserInit();
    204  bool FmtChunkParserInit();
    205  bool ListChunkParserInit(uint32_t aChunkSize);
    206 
    207  bool SkipNextChunk(const MediaByteRange& aRange);
    208 
    209  already_AddRefed<MediaRawData> GetNextChunk(const MediaByteRange& aRange);
    210  already_AddRefed<MediaRawData> GetFileHeader(const MediaByteRange& aRange);
    211 
    212  void UpdateState(const MediaByteRange& aRange);
    213 
    214  uint64_t OffsetFromChunkIndex(uint32_t aChunkIndex) const;
    215  uint64_t ChunkIndexFromTime(const media::TimeUnit& aTime) const;
    216 
    217  int64_t Read(uint8_t* aBuffer, int64_t aOffset, int64_t aSize);
    218 
    219  MediaResourceIndex mSource;
    220 
    221  DataParser mParser;
    222  RIFFParser mRIFFParser;
    223  HeaderParser mHeaderParser;
    224 
    225  FormatChunk mFmtChunk;
    226  // ListChunkParser mListChunkParser;
    227 
    228  uint64_t mOffset;
    229  uint64_t mFirstChunkOffset;
    230 
    231  uint32_t mNumParsedChunks;
    232  uint32_t mChunkIndex;
    233 
    234  uint32_t mDataLength;
    235  uint64_t mTotalChunkLen;
    236 
    237  uint32_t mSamplesPerChunk;
    238  uint32_t mSamplesPerSecond;
    239 
    240  uint32_t mChannels;
    241  uint32_t mSampleFormat;
    242 
    243  UniquePtr<AudioInfo> mInfo;
    244 };
    245 
    246 }  // namespace mozilla
    247 
    248 #endif