Coverage Report

Created: 2018-09-25 14:53

/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