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