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