Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, 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 MOOF_PARSER_H_
6 : #define MOOF_PARSER_H_
7 :
8 : #include "mp4_demuxer/Atom.h"
9 : #include "mp4_demuxer/AtomType.h"
10 : #include "mp4_demuxer/SinfParser.h"
11 : #include "mp4_demuxer/Stream.h"
12 : #include "mp4_demuxer/Interval.h"
13 : #include "MediaResource.h"
14 :
15 : namespace mp4_demuxer {
16 : typedef int64_t Microseconds;
17 :
18 : class Box;
19 : class BoxContext;
20 : class BoxReader;
21 : class Moof;
22 :
23 0 : class Mvhd : public Atom
24 : {
25 : public:
26 0 : Mvhd()
27 0 : : mCreationTime(0)
28 : , mModificationTime(0)
29 : , mTimescale(0)
30 0 : , mDuration(0)
31 : {
32 0 : }
33 : explicit Mvhd(Box& aBox);
34 :
35 0 : Microseconds ToMicroseconds(int64_t aTimescaleUnits)
36 : {
37 0 : int64_t major = aTimescaleUnits / mTimescale;
38 0 : int64_t remainder = aTimescaleUnits % mTimescale;
39 0 : return major * 1000000ll + remainder * 1000000ll / mTimescale;
40 : }
41 :
42 : uint64_t mCreationTime;
43 : uint64_t mModificationTime;
44 : uint32_t mTimescale;
45 : uint64_t mDuration;
46 : };
47 :
48 0 : class Tkhd : public Mvhd
49 : {
50 : public:
51 0 : Tkhd()
52 0 : : mTrackId(0)
53 : {
54 0 : }
55 : explicit Tkhd(Box& aBox);
56 :
57 : uint32_t mTrackId;
58 : };
59 :
60 0 : class Mdhd : public Mvhd
61 : {
62 : public:
63 0 : Mdhd() = default;
64 : explicit Mdhd(Box& aBox);
65 : };
66 :
67 0 : class Trex : public Atom
68 : {
69 : public:
70 0 : explicit Trex(uint32_t aTrackId)
71 0 : : mFlags(0)
72 : , mTrackId(aTrackId)
73 : , mDefaultSampleDescriptionIndex(0)
74 : , mDefaultSampleDuration(0)
75 : , mDefaultSampleSize(0)
76 0 : , mDefaultSampleFlags(0)
77 : {
78 0 : }
79 :
80 : explicit Trex(Box& aBox);
81 :
82 : uint32_t mFlags;
83 : uint32_t mTrackId;
84 : uint32_t mDefaultSampleDescriptionIndex;
85 : uint32_t mDefaultSampleDuration;
86 : uint32_t mDefaultSampleSize;
87 : uint32_t mDefaultSampleFlags;
88 : };
89 :
90 0 : class Tfhd : public Trex
91 : {
92 : public:
93 0 : explicit Tfhd(Trex& aTrex)
94 0 : : Trex(aTrex)
95 0 : , mBaseDataOffset(0)
96 : {
97 0 : mValid = aTrex.IsValid();
98 0 : }
99 : Tfhd(Box& aBox, Trex& aTrex);
100 :
101 : uint64_t mBaseDataOffset;
102 : };
103 :
104 0 : class Tfdt : public Atom
105 : {
106 : public:
107 0 : Tfdt()
108 0 : : mBaseMediaDecodeTime(0)
109 : {
110 0 : }
111 : explicit Tfdt(Box& aBox);
112 :
113 : uint64_t mBaseMediaDecodeTime;
114 : };
115 :
116 0 : class Edts : public Atom
117 : {
118 : public:
119 0 : Edts()
120 0 : : mMediaStart(0)
121 0 : , mEmptyOffset(0)
122 : {
123 0 : }
124 : explicit Edts(Box& aBox);
125 0 : virtual bool IsValid()
126 : {
127 : // edts is optional
128 0 : return true;
129 : }
130 :
131 : int64_t mMediaStart;
132 : int64_t mEmptyOffset;
133 : };
134 :
135 0 : struct Sample
136 : {
137 : mozilla::MediaByteRange mByteRange;
138 : mozilla::MediaByteRange mCencRange;
139 : Microseconds mDecodeTime;
140 : Interval<Microseconds> mCompositionRange;
141 : bool mSync;
142 : };
143 :
144 0 : class Saiz final : public Atom
145 : {
146 : public:
147 : Saiz(Box& aBox, AtomType aDefaultType);
148 :
149 : AtomType mAuxInfoType;
150 : uint32_t mAuxInfoTypeParameter;
151 : FallibleTArray<uint8_t> mSampleInfoSize;
152 : };
153 :
154 0 : class Saio final : public Atom
155 : {
156 : public:
157 : Saio(Box& aBox, AtomType aDefaultType);
158 :
159 : AtomType mAuxInfoType;
160 : uint32_t mAuxInfoTypeParameter;
161 : FallibleTArray<uint64_t> mOffsets;
162 : };
163 :
164 : struct SampleToGroupEntry
165 : {
166 : public:
167 : static const uint32_t kTrackGroupDescriptionIndexBase = 0;
168 : static const uint32_t kFragmentGroupDescriptionIndexBase = 0x10000;
169 :
170 0 : SampleToGroupEntry(uint32_t aSampleCount, uint32_t aGroupDescriptionIndex)
171 0 : : mSampleCount(aSampleCount)
172 0 : , mGroupDescriptionIndex(aGroupDescriptionIndex)
173 : {
174 0 : }
175 :
176 : uint32_t mSampleCount;
177 : uint32_t mGroupDescriptionIndex;
178 : };
179 :
180 0 : class Sbgp final : public Atom // SampleToGroup box.
181 : {
182 : public:
183 : explicit Sbgp(Box& aBox);
184 :
185 : AtomType mGroupingType;
186 : uint32_t mGroupingTypeParam;
187 : nsTArray<SampleToGroupEntry> mEntries;
188 : };
189 :
190 0 : struct CencSampleEncryptionInfoEntry final
191 : {
192 : public:
193 0 : CencSampleEncryptionInfoEntry() { }
194 :
195 : bool Init(BoxReader& aReader);
196 :
197 : bool mIsEncrypted = false;
198 : uint8_t mIVSize = 0;
199 : nsTArray<uint8_t> mKeyId;
200 : };
201 :
202 0 : class Sgpd final : public Atom // SampleGroupDescription box.
203 : {
204 : public:
205 : explicit Sgpd(Box& aBox);
206 :
207 : AtomType mGroupingType;
208 : nsTArray<CencSampleEncryptionInfoEntry> mEntries;
209 : };
210 :
211 : class AuxInfo {
212 : public:
213 : AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
214 :
215 : private:
216 : int64_t mMoofOffset;
217 : Saiz& mSaiz;
218 : Saio& mSaio;
219 : };
220 :
221 0 : class Moof final : public Atom
222 : {
223 : public:
224 : Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, uint64_t* aDecoderTime, bool aIsAudio);
225 : bool GetAuxInfo(AtomType aType, nsTArray<MediaByteRange>* aByteRanges);
226 : void FixRounding(const Moof& aMoof);
227 :
228 : mozilla::MediaByteRange mRange;
229 : mozilla::MediaByteRange mMdatRange;
230 : Interval<Microseconds> mTimeRange;
231 : FallibleTArray<Sample> mIndex;
232 :
233 : nsTArray<CencSampleEncryptionInfoEntry> mFragmentSampleEncryptionInfoEntries;
234 : nsTArray<SampleToGroupEntry> mFragmentSampleToGroupEntries;
235 :
236 : nsTArray<Saiz> mSaizs;
237 : nsTArray<Saio> mSaios;
238 :
239 : private:
240 : // aDecodeTime is updated to the end of the parsed TRAF on return.
241 : void ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio);
242 : // aDecodeTime is updated to the end of the parsed TRUN on return.
243 : bool ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio);
244 : void ParseSaiz(Box& aBox);
245 : void ParseSaio(Box& aBox);
246 : bool ProcessCenc();
247 : uint64_t mMaxRoundingError;
248 : };
249 :
250 0 : class MoofParser
251 : {
252 : public:
253 0 : MoofParser(Stream* aSource, uint32_t aTrackId, bool aIsAudio)
254 0 : : mSource(aSource)
255 : , mOffset(0)
256 : , mTrex(aTrackId)
257 : , mIsAudio(aIsAudio)
258 0 : , mLastDecodeTime(0)
259 : {
260 : // Setting the mTrex.mTrackId to 0 is a nasty work around for calculating
261 : // the composition range for MSE. We need an array of tracks.
262 0 : }
263 : bool RebuildFragmentedIndex(
264 : const mozilla::MediaByteRangeSet& aByteRanges);
265 : // If *aCanEvict is set to true. then will remove all moofs already parsed
266 : // from index then rebuild the index. *aCanEvict is set to true upon return if
267 : // some moofs were removed.
268 : bool RebuildFragmentedIndex(
269 : const mozilla::MediaByteRangeSet& aByteRanges, bool* aCanEvict);
270 : bool RebuildFragmentedIndex(BoxContext& aContext);
271 : Interval<Microseconds> GetCompositionRange(
272 : const mozilla::MediaByteRangeSet& aByteRanges);
273 : bool ReachedEnd();
274 : void ParseMoov(Box& aBox);
275 : void ParseTrak(Box& aBox);
276 : void ParseMdia(Box& aBox, Tkhd& aTkhd);
277 : void ParseMvex(Box& aBox);
278 :
279 : void ParseMinf(Box& aBox);
280 : void ParseStbl(Box& aBox);
281 : void ParseStsd(Box& aBox);
282 : void ParseEncrypted(Box& aBox);
283 : void ParseSinf(Box& aBox);
284 :
285 : bool BlockingReadNextMoof();
286 : bool HasMetadata();
287 : already_AddRefed<mozilla::MediaByteBuffer> Metadata();
288 : MediaByteRange FirstCompleteMediaSegment();
289 : MediaByteRange FirstCompleteMediaHeader();
290 :
291 : mozilla::MediaByteRange mInitRange;
292 : RefPtr<Stream> mSource;
293 : uint64_t mOffset;
294 : Mvhd mMvhd;
295 : Mdhd mMdhd;
296 : Trex mTrex;
297 : Tfdt mTfdt;
298 : Edts mEdts;
299 : Sinf mSinf;
300 :
301 : nsTArray<CencSampleEncryptionInfoEntry> mTrackSampleEncryptionInfoEntries;
302 : nsTArray<SampleToGroupEntry> mTrackSampleToGroupEntries;
303 :
304 0 : nsTArray<Moof>& Moofs() { return mMoofs; }
305 : private:
306 : void ScanForMetadata(mozilla::MediaByteRange& aFtyp,
307 : mozilla::MediaByteRange& aMoov);
308 : nsTArray<Moof> mMoofs;
309 : nsTArray<MediaByteRange> mMediaRanges;
310 : bool mIsAudio;
311 : uint64_t mLastDecodeTime;
312 : };
313 : }
314 :
315 : #endif
|