1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/formats/mp4/box_definitions.h"
6
7#include "base/logging.h"
8#include "media/formats/mp4/es_descriptor.h"
9#include "media/formats/mp4/rcheck.h"
10
11namespace media {
12namespace mp4 {
13
14FileType::FileType() {}
15FileType::~FileType() {}
16FourCC FileType::BoxType() const { return FOURCC_FTYP; }
17
18bool FileType::Parse(BoxReader* reader) {
19  RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version));
20  size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC);
21  return reader->SkipBytes(sizeof(FourCC) * num_brands);  // compatible_brands
22}
23
24ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
25ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
26FourCC ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH; }
27
28bool ProtectionSystemSpecificHeader::Parse(BoxReader* reader) {
29  // Validate the box's contents and hang on to the system ID.
30  uint32 size;
31  RCHECK(reader->ReadFullBoxHeader() &&
32         reader->ReadVec(&system_id, 16) &&
33         reader->Read4(&size) &&
34         reader->HasBytes(size));
35
36  // Copy the entire box, including the header, for passing to EME as initData.
37  DCHECK(raw_box.empty());
38  raw_box.assign(reader->data(), reader->data() + reader->size());
39  return true;
40}
41
42SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
43SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
44FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; }
45
46bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) {
47  RCHECK(reader->ReadFullBoxHeader());
48  if (reader->flags() & 1)
49    RCHECK(reader->SkipBytes(8));
50
51  uint32 count;
52  RCHECK(reader->Read4(&count) &&
53         reader->HasBytes(count * (reader->version() == 1 ? 8 : 4)));
54  offsets.resize(count);
55
56  for (uint32 i = 0; i < count; i++) {
57    if (reader->version() == 1) {
58      RCHECK(reader->Read8(&offsets[i]));
59    } else {
60      RCHECK(reader->Read4Into8(&offsets[i]));
61    }
62  }
63  return true;
64}
65
66SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
67  : default_sample_info_size(0), sample_count(0) {
68}
69SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
70FourCC SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ; }
71
72bool SampleAuxiliaryInformationSize::Parse(BoxReader* reader) {
73  RCHECK(reader->ReadFullBoxHeader());
74  if (reader->flags() & 1)
75    RCHECK(reader->SkipBytes(8));
76
77  RCHECK(reader->Read1(&default_sample_info_size) &&
78         reader->Read4(&sample_count));
79  if (default_sample_info_size == 0)
80    return reader->ReadVec(&sample_info_sizes, sample_count);
81  return true;
82}
83
84OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
85OriginalFormat::~OriginalFormat() {}
86FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; }
87
88bool OriginalFormat::Parse(BoxReader* reader) {
89  return reader->ReadFourCC(&format);
90}
91
92SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
93SchemeType::~SchemeType() {}
94FourCC SchemeType::BoxType() const { return FOURCC_SCHM; }
95
96bool SchemeType::Parse(BoxReader* reader) {
97  RCHECK(reader->ReadFullBoxHeader() &&
98         reader->ReadFourCC(&type) &&
99         reader->Read4(&version));
100  return true;
101}
102
103TrackEncryption::TrackEncryption()
104  : is_encrypted(false), default_iv_size(0) {
105}
106TrackEncryption::~TrackEncryption() {}
107FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }
108
109bool TrackEncryption::Parse(BoxReader* reader) {
110  uint8 flag;
111  RCHECK(reader->ReadFullBoxHeader() &&
112         reader->SkipBytes(2) &&
113         reader->Read1(&flag) &&
114         reader->Read1(&default_iv_size) &&
115         reader->ReadVec(&default_kid, 16));
116  is_encrypted = (flag != 0);
117  if (is_encrypted) {
118    RCHECK(default_iv_size == 8 || default_iv_size == 16);
119  } else {
120    RCHECK(default_iv_size == 0);
121  }
122  return true;
123}
124
125SchemeInfo::SchemeInfo() {}
126SchemeInfo::~SchemeInfo() {}
127FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; }
128
129bool SchemeInfo::Parse(BoxReader* reader) {
130  return reader->ScanChildren() && reader->ReadChild(&track_encryption);
131}
132
133ProtectionSchemeInfo::ProtectionSchemeInfo() {}
134ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
135FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; }
136
137bool ProtectionSchemeInfo::Parse(BoxReader* reader) {
138  RCHECK(reader->ScanChildren() &&
139         reader->ReadChild(&format) &&
140         reader->ReadChild(&type));
141  if (type.type == FOURCC_CENC)
142    RCHECK(reader->ReadChild(&info));
143  // Other protection schemes are silently ignored. Since the protection scheme
144  // type can't be determined until this box is opened, we return 'true' for
145  // non-CENC protection scheme types. It is the parent box's responsibility to
146  // ensure that this scheme type is a supported one.
147  return true;
148}
149
150MovieHeader::MovieHeader()
151    : creation_time(0),
152      modification_time(0),
153      timescale(0),
154      duration(0),
155      rate(-1),
156      volume(-1),
157      next_track_id(0) {}
158MovieHeader::~MovieHeader() {}
159FourCC MovieHeader::BoxType() const { return FOURCC_MVHD; }
160
161bool MovieHeader::Parse(BoxReader* reader) {
162  RCHECK(reader->ReadFullBoxHeader());
163
164  if (reader->version() == 1) {
165    RCHECK(reader->Read8(&creation_time) &&
166           reader->Read8(&modification_time) &&
167           reader->Read4(&timescale) &&
168           reader->Read8(&duration));
169  } else {
170    RCHECK(reader->Read4Into8(&creation_time) &&
171           reader->Read4Into8(&modification_time) &&
172           reader->Read4(&timescale) &&
173           reader->Read4Into8(&duration));
174  }
175
176  RCHECK(reader->Read4s(&rate) &&
177         reader->Read2s(&volume) &&
178         reader->SkipBytes(10) &&  // reserved
179         reader->SkipBytes(36) &&  // matrix
180         reader->SkipBytes(24) &&  // predefined zero
181         reader->Read4(&next_track_id));
182  return true;
183}
184
185TrackHeader::TrackHeader()
186    : creation_time(0),
187      modification_time(0),
188      track_id(0),
189      duration(0),
190      layer(-1),
191      alternate_group(-1),
192      volume(-1),
193      width(0),
194      height(0) {}
195TrackHeader::~TrackHeader() {}
196FourCC TrackHeader::BoxType() const { return FOURCC_TKHD; }
197
198bool TrackHeader::Parse(BoxReader* reader) {
199  RCHECK(reader->ReadFullBoxHeader());
200  if (reader->version() == 1) {
201    RCHECK(reader->Read8(&creation_time) &&
202           reader->Read8(&modification_time) &&
203           reader->Read4(&track_id) &&
204           reader->SkipBytes(4) &&    // reserved
205           reader->Read8(&duration));
206  } else {
207    RCHECK(reader->Read4Into8(&creation_time) &&
208           reader->Read4Into8(&modification_time) &&
209           reader->Read4(&track_id) &&
210           reader->SkipBytes(4) &&   // reserved
211           reader->Read4Into8(&duration));
212  }
213
214  RCHECK(reader->SkipBytes(8) &&  // reserved
215         reader->Read2s(&layer) &&
216         reader->Read2s(&alternate_group) &&
217         reader->Read2s(&volume) &&
218         reader->SkipBytes(2) &&  // reserved
219         reader->SkipBytes(36) &&  // matrix
220         reader->Read4(&width) &&
221         reader->Read4(&height));
222  width >>= 16;
223  height >>= 16;
224  return true;
225}
226
227SampleDescription::SampleDescription() : type(kInvalid) {}
228SampleDescription::~SampleDescription() {}
229FourCC SampleDescription::BoxType() const { return FOURCC_STSD; }
230
231bool SampleDescription::Parse(BoxReader* reader) {
232  uint32 count;
233  RCHECK(reader->SkipBytes(4) &&
234         reader->Read4(&count));
235  video_entries.clear();
236  audio_entries.clear();
237
238  // Note: this value is preset before scanning begins. See comments in the
239  // Parse(Media*) function.
240  if (type == kVideo) {
241    RCHECK(reader->ReadAllChildren(&video_entries));
242  } else if (type == kAudio) {
243    RCHECK(reader->ReadAllChildren(&audio_entries));
244  }
245  return true;
246}
247
248SyncSample::SyncSample() : is_present(false) {}
249SyncSample::~SyncSample() {}
250FourCC SyncSample::BoxType() const { return FOURCC_STSS; }
251
252bool SyncSample::Parse(BoxReader* reader) {
253  uint32 entry_count;
254  RCHECK(reader->ReadFullBoxHeader() &&
255         reader->Read4(&entry_count));
256
257  is_present = true;
258
259  entries.resize(entry_count);
260
261  if (entry_count == 0)
262    return true;
263
264  for (size_t i = 0; i < entry_count; ++i)
265    RCHECK(reader->Read4(&entries[i]));
266
267  return true;
268}
269
270bool SyncSample::IsSyncSample(size_t k) const {
271  // ISO/IEC 14496-12 Section 8.6.2.1 : If the sync sample box is not present,
272  // every sample is a sync sample.
273  if (!is_present)
274    return true;
275
276  // ISO/IEC 14496-12  Section 8.6.2.3 : If entry_count is zero, there are no
277  // sync samples within the stream.
278  if (entries.size() == 0u)
279    return false;
280
281  for (size_t i = 0; i < entries.size(); ++i) {
282    if (entries[i] == k)
283      return true;
284  }
285
286  return false;
287}
288
289SampleTable::SampleTable() {}
290SampleTable::~SampleTable() {}
291FourCC SampleTable::BoxType() const { return FOURCC_STBL; }
292
293bool SampleTable::Parse(BoxReader* reader) {
294  return reader->ScanChildren() &&
295      reader->ReadChild(&description) &&
296      reader->MaybeReadChild(&sync_sample);
297}
298
299EditList::EditList() {}
300EditList::~EditList() {}
301FourCC EditList::BoxType() const { return FOURCC_ELST; }
302
303bool EditList::Parse(BoxReader* reader) {
304  uint32 count;
305  RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count));
306
307  if (reader->version() == 1) {
308    RCHECK(reader->HasBytes(count * 20));
309  } else {
310    RCHECK(reader->HasBytes(count * 12));
311  }
312  edits.resize(count);
313
314  for (std::vector<EditListEntry>::iterator edit = edits.begin();
315       edit != edits.end(); ++edit) {
316    if (reader->version() == 1) {
317      RCHECK(reader->Read8(&edit->segment_duration) &&
318             reader->Read8s(&edit->media_time));
319    } else {
320      RCHECK(reader->Read4Into8(&edit->segment_duration) &&
321             reader->Read4sInto8s(&edit->media_time));
322    }
323    RCHECK(reader->Read2s(&edit->media_rate_integer) &&
324           reader->Read2s(&edit->media_rate_fraction));
325  }
326  return true;
327}
328
329Edit::Edit() {}
330Edit::~Edit() {}
331FourCC Edit::BoxType() const { return FOURCC_EDTS; }
332
333bool Edit::Parse(BoxReader* reader) {
334  return reader->ScanChildren() && reader->ReadChild(&list);
335}
336
337HandlerReference::HandlerReference() : type(kInvalid) {}
338HandlerReference::~HandlerReference() {}
339FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; }
340
341bool HandlerReference::Parse(BoxReader* reader) {
342  FourCC hdlr_type;
343  RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type));
344  // Note: remaining fields in box ignored
345  if (hdlr_type == FOURCC_VIDE) {
346    type = kVideo;
347  } else if (hdlr_type == FOURCC_SOUN) {
348    type = kAudio;
349  } else {
350    type = kInvalid;
351  }
352  return true;
353}
354
355AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
356    : version(0),
357      profile_indication(0),
358      profile_compatibility(0),
359      avc_level(0),
360      length_size(0) {}
361
362AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {}
363FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; }
364
365bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
366  return ParseInternal(reader, reader->log_cb());
367}
368
369bool AVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) {
370  BufferReader reader(data, data_size);
371  return ParseInternal(&reader, LogCB());
372}
373
374bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
375                                                  const LogCB& log_cb) {
376  RCHECK(reader->Read1(&version) && version == 1 &&
377         reader->Read1(&profile_indication) &&
378         reader->Read1(&profile_compatibility) &&
379         reader->Read1(&avc_level));
380
381  uint8 length_size_minus_one;
382  RCHECK(reader->Read1(&length_size_minus_one));
383  length_size = (length_size_minus_one & 0x3) + 1;
384
385  RCHECK(length_size != 3); // Only values of 1, 2, and 4 are valid.
386
387  uint8 num_sps;
388  RCHECK(reader->Read1(&num_sps));
389  num_sps &= 0x1f;
390
391  sps_list.resize(num_sps);
392  for (int i = 0; i < num_sps; i++) {
393    uint16 sps_length;
394    RCHECK(reader->Read2(&sps_length) &&
395           reader->ReadVec(&sps_list[i], sps_length));
396    RCHECK(sps_list[i].size() > 4);
397
398    if (!log_cb.is_null()) {
399      MEDIA_LOG(log_cb) << "Video codec: avc1." << std::hex
400                        << static_cast<int>(sps_list[i][1])
401                        << static_cast<int>(sps_list[i][2])
402                        << static_cast<int>(sps_list[i][3]);
403    }
404  }
405
406  uint8 num_pps;
407  RCHECK(reader->Read1(&num_pps));
408
409  pps_list.resize(num_pps);
410  for (int i = 0; i < num_pps; i++) {
411    uint16 pps_length;
412    RCHECK(reader->Read2(&pps_length) &&
413           reader->ReadVec(&pps_list[i], pps_length));
414  }
415
416  return true;
417}
418
419PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {}
420PixelAspectRatioBox::~PixelAspectRatioBox() {}
421FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; }
422
423bool PixelAspectRatioBox::Parse(BoxReader* reader) {
424  RCHECK(reader->Read4(&h_spacing) &&
425         reader->Read4(&v_spacing));
426  return true;
427}
428
429VideoSampleEntry::VideoSampleEntry()
430    : format(FOURCC_NULL),
431      data_reference_index(0),
432      width(0),
433      height(0) {}
434
435VideoSampleEntry::~VideoSampleEntry() {}
436FourCC VideoSampleEntry::BoxType() const {
437  DCHECK(false) << "VideoSampleEntry should be parsed according to the "
438                << "handler type recovered in its Media ancestor.";
439  return FOURCC_NULL;
440}
441
442bool VideoSampleEntry::Parse(BoxReader* reader) {
443  format = reader->type();
444  RCHECK(reader->SkipBytes(6) &&
445         reader->Read2(&data_reference_index) &&
446         reader->SkipBytes(16) &&
447         reader->Read2(&width) &&
448         reader->Read2(&height) &&
449         reader->SkipBytes(50));
450
451  RCHECK(reader->ScanChildren() &&
452         reader->MaybeReadChild(&pixel_aspect));
453
454  if (format == FOURCC_ENCV) {
455    // Continue scanning until a recognized protection scheme is found, or until
456    // we run out of protection schemes.
457    while (sinf.type.type != FOURCC_CENC) {
458      if (!reader->ReadChild(&sinf))
459        return false;
460    }
461  }
462
463  if (IsFormatValid())
464    RCHECK(reader->ReadChild(&avcc));
465
466  return true;
467}
468
469bool VideoSampleEntry::IsFormatValid() const {
470  return format == FOURCC_AVC1 || format == FOURCC_AVC3 ||
471      (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 ||
472                                 sinf.format.format == FOURCC_AVC3));
473}
474
475ElementaryStreamDescriptor::ElementaryStreamDescriptor()
476    : object_type(kForbidden) {}
477
478ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
479
480FourCC ElementaryStreamDescriptor::BoxType() const {
481  return FOURCC_ESDS;
482}
483
484bool ElementaryStreamDescriptor::Parse(BoxReader* reader) {
485  std::vector<uint8> data;
486  ESDescriptor es_desc;
487
488  RCHECK(reader->ReadFullBoxHeader());
489  RCHECK(reader->ReadVec(&data, reader->size() - reader->pos()));
490  RCHECK(es_desc.Parse(data));
491
492  object_type = es_desc.object_type();
493
494  if (object_type != 0x40) {
495    MEDIA_LOG(reader->log_cb()) << "Audio codec: mp4a."
496                                << std::hex << static_cast<int>(object_type);
497  }
498
499  if (es_desc.IsAAC(object_type))
500    RCHECK(aac.Parse(es_desc.decoder_specific_info(), reader->log_cb()));
501
502  return true;
503}
504
505AudioSampleEntry::AudioSampleEntry()
506    : format(FOURCC_NULL),
507      data_reference_index(0),
508      channelcount(0),
509      samplesize(0),
510      samplerate(0) {}
511
512AudioSampleEntry::~AudioSampleEntry() {}
513
514FourCC AudioSampleEntry::BoxType() const {
515  DCHECK(false) << "AudioSampleEntry should be parsed according to the "
516                << "handler type recovered in its Media ancestor.";
517  return FOURCC_NULL;
518}
519
520bool AudioSampleEntry::Parse(BoxReader* reader) {
521  format = reader->type();
522  RCHECK(reader->SkipBytes(6) &&
523         reader->Read2(&data_reference_index) &&
524         reader->SkipBytes(8) &&
525         reader->Read2(&channelcount) &&
526         reader->Read2(&samplesize) &&
527         reader->SkipBytes(4) &&
528         reader->Read4(&samplerate));
529  // Convert from 16.16 fixed point to integer
530  samplerate >>= 16;
531
532  RCHECK(reader->ScanChildren());
533  if (format == FOURCC_ENCA) {
534    // Continue scanning until a recognized protection scheme is found, or until
535    // we run out of protection schemes.
536    while (sinf.type.type != FOURCC_CENC) {
537      if (!reader->ReadChild(&sinf))
538        return false;
539    }
540  }
541
542  // ESDS is not valid in case of EAC3.
543  RCHECK(reader->MaybeReadChild(&esds));
544  return true;
545}
546
547MediaHeader::MediaHeader()
548    : creation_time(0),
549      modification_time(0),
550      timescale(0),
551      duration(0) {}
552MediaHeader::~MediaHeader() {}
553FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; }
554
555bool MediaHeader::Parse(BoxReader* reader) {
556  RCHECK(reader->ReadFullBoxHeader());
557
558  if (reader->version() == 1) {
559    RCHECK(reader->Read8(&creation_time) &&
560           reader->Read8(&modification_time) &&
561           reader->Read4(&timescale) &&
562           reader->Read8(&duration));
563  } else {
564    RCHECK(reader->Read4Into8(&creation_time) &&
565           reader->Read4Into8(&modification_time) &&
566           reader->Read4(&timescale) &&
567           reader->Read4Into8(&duration));
568  }
569  // Skip language information
570  return reader->SkipBytes(4);
571}
572
573MediaInformation::MediaInformation() {}
574MediaInformation::~MediaInformation() {}
575FourCC MediaInformation::BoxType() const { return FOURCC_MINF; }
576
577bool MediaInformation::Parse(BoxReader* reader) {
578  return reader->ScanChildren() &&
579         reader->ReadChild(&sample_table);
580}
581
582Media::Media() {}
583Media::~Media() {}
584FourCC Media::BoxType() const { return FOURCC_MDIA; }
585
586bool Media::Parse(BoxReader* reader) {
587  RCHECK(reader->ScanChildren() &&
588         reader->ReadChild(&header) &&
589         reader->ReadChild(&handler));
590
591  // Maddeningly, the HandlerReference box specifies how to parse the
592  // SampleDescription box, making the latter the only box (of those that we
593  // support) which cannot be parsed correctly on its own (or even with
594  // information from its strict ancestor tree). We thus copy the handler type
595  // to the sample description box *before* parsing it to provide this
596  // information while parsing.
597  information.sample_table.description.type = handler.type;
598  RCHECK(reader->ReadChild(&information));
599  return true;
600}
601
602Track::Track() {}
603Track::~Track() {}
604FourCC Track::BoxType() const { return FOURCC_TRAK; }
605
606bool Track::Parse(BoxReader* reader) {
607  RCHECK(reader->ScanChildren() &&
608         reader->ReadChild(&header) &&
609         reader->ReadChild(&media) &&
610         reader->MaybeReadChild(&edit));
611  return true;
612}
613
614MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
615MovieExtendsHeader::~MovieExtendsHeader() {}
616FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; }
617
618bool MovieExtendsHeader::Parse(BoxReader* reader) {
619  RCHECK(reader->ReadFullBoxHeader());
620  if (reader->version() == 1) {
621    RCHECK(reader->Read8(&fragment_duration));
622  } else {
623    RCHECK(reader->Read4Into8(&fragment_duration));
624  }
625  return true;
626}
627
628TrackExtends::TrackExtends()
629    : track_id(0),
630      default_sample_description_index(0),
631      default_sample_duration(0),
632      default_sample_size(0),
633      default_sample_flags(0) {}
634TrackExtends::~TrackExtends() {}
635FourCC TrackExtends::BoxType() const { return FOURCC_TREX; }
636
637bool TrackExtends::Parse(BoxReader* reader) {
638  RCHECK(reader->ReadFullBoxHeader() &&
639         reader->Read4(&track_id) &&
640         reader->Read4(&default_sample_description_index) &&
641         reader->Read4(&default_sample_duration) &&
642         reader->Read4(&default_sample_size) &&
643         reader->Read4(&default_sample_flags));
644  return true;
645}
646
647MovieExtends::MovieExtends() {}
648MovieExtends::~MovieExtends() {}
649FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; }
650
651bool MovieExtends::Parse(BoxReader* reader) {
652  header.fragment_duration = 0;
653  return reader->ScanChildren() &&
654         reader->MaybeReadChild(&header) &&
655         reader->ReadChildren(&tracks);
656}
657
658Movie::Movie() : fragmented(false) {}
659Movie::~Movie() {}
660FourCC Movie::BoxType() const { return FOURCC_MOOV; }
661
662bool Movie::Parse(BoxReader* reader) {
663  return reader->ScanChildren() &&
664         reader->ReadChild(&header) &&
665         reader->ReadChildren(&tracks) &&
666         // Media Source specific: 'mvex' required
667         reader->ReadChild(&extends) &&
668         reader->MaybeReadChildren(&pssh);
669}
670
671TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
672TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
673FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; }
674
675bool TrackFragmentDecodeTime::Parse(BoxReader* reader) {
676  RCHECK(reader->ReadFullBoxHeader());
677  if (reader->version() == 1)
678    return reader->Read8(&decode_time);
679  else
680    return reader->Read4Into8(&decode_time);
681}
682
683MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
684MovieFragmentHeader::~MovieFragmentHeader() {}
685FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; }
686
687bool MovieFragmentHeader::Parse(BoxReader* reader) {
688  return reader->SkipBytes(4) && reader->Read4(&sequence_number);
689}
690
691TrackFragmentHeader::TrackFragmentHeader()
692    : track_id(0),
693      sample_description_index(0),
694      default_sample_duration(0),
695      default_sample_size(0),
696      default_sample_flags(0),
697      has_default_sample_flags(false) {}
698
699TrackFragmentHeader::~TrackFragmentHeader() {}
700FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; }
701
702bool TrackFragmentHeader::Parse(BoxReader* reader) {
703  RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&track_id));
704
705  // Media Source specific: reject tracks that set 'base-data-offset-present'.
706  // Although the Media Source requires that 'default-base-is-moof' (14496-12
707  // Amendment 2) be set, we omit this check as many otherwise-valid files in
708  // the wild don't set it.
709  //
710  //  RCHECK((flags & 0x020000) && !(flags & 0x1));
711  RCHECK(!(reader->flags() & 0x1));
712
713  if (reader->flags() & 0x2) {
714    RCHECK(reader->Read4(&sample_description_index));
715  } else {
716    sample_description_index = 0;
717  }
718
719  if (reader->flags() & 0x8) {
720    RCHECK(reader->Read4(&default_sample_duration));
721  } else {
722    default_sample_duration = 0;
723  }
724
725  if (reader->flags() & 0x10) {
726    RCHECK(reader->Read4(&default_sample_size));
727  } else {
728    default_sample_size = 0;
729  }
730
731  if (reader->flags() & 0x20) {
732    RCHECK(reader->Read4(&default_sample_flags));
733    has_default_sample_flags = true;
734  } else {
735    has_default_sample_flags = false;
736  }
737
738  return true;
739}
740
741TrackFragmentRun::TrackFragmentRun()
742    : sample_count(0), data_offset(0) {}
743TrackFragmentRun::~TrackFragmentRun() {}
744FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; }
745
746bool TrackFragmentRun::Parse(BoxReader* reader) {
747  RCHECK(reader->ReadFullBoxHeader() &&
748         reader->Read4(&sample_count));
749  const uint32 flags = reader->flags();
750
751  bool data_offset_present = (flags & 0x1) != 0;
752  bool first_sample_flags_present = (flags & 0x4) != 0;
753  bool sample_duration_present = (flags & 0x100) != 0;
754  bool sample_size_present = (flags & 0x200) != 0;
755  bool sample_flags_present = (flags & 0x400) != 0;
756  bool sample_composition_time_offsets_present = (flags & 0x800) != 0;
757
758  if (data_offset_present) {
759    RCHECK(reader->Read4(&data_offset));
760  } else {
761    data_offset = 0;
762  }
763
764  uint32 first_sample_flags = 0;
765  if (first_sample_flags_present)
766    RCHECK(reader->Read4(&first_sample_flags));
767
768  int fields = sample_duration_present + sample_size_present +
769      sample_flags_present + sample_composition_time_offsets_present;
770  RCHECK(reader->HasBytes(fields * sample_count));
771
772  if (sample_duration_present)
773    sample_durations.resize(sample_count);
774  if (sample_size_present)
775    sample_sizes.resize(sample_count);
776  if (sample_flags_present)
777    sample_flags.resize(sample_count);
778  if (sample_composition_time_offsets_present)
779    sample_composition_time_offsets.resize(sample_count);
780
781  for (uint32 i = 0; i < sample_count; ++i) {
782    if (sample_duration_present)
783      RCHECK(reader->Read4(&sample_durations[i]));
784    if (sample_size_present)
785      RCHECK(reader->Read4(&sample_sizes[i]));
786    if (sample_flags_present)
787      RCHECK(reader->Read4(&sample_flags[i]));
788    if (sample_composition_time_offsets_present)
789      RCHECK(reader->Read4s(&sample_composition_time_offsets[i]));
790  }
791
792  if (first_sample_flags_present) {
793    if (sample_flags.size() == 0) {
794      sample_flags.push_back(first_sample_flags);
795    } else {
796      sample_flags[0] = first_sample_flags;
797    }
798  }
799  return true;
800}
801
802SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
803SampleToGroup::~SampleToGroup() {}
804FourCC SampleToGroup::BoxType() const { return FOURCC_SBGP; }
805
806bool SampleToGroup::Parse(BoxReader* reader) {
807  RCHECK(reader->ReadFullBoxHeader() &&
808         reader->Read4(&grouping_type));
809
810  if (reader->version() == 1)
811    RCHECK(reader->Read4(&grouping_type_parameter));
812
813  if (grouping_type != FOURCC_SEIG) {
814    DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type
815                  << "' is not supported.";
816    return true;
817  }
818
819  uint32 count;
820  RCHECK(reader->Read4(&count));
821  entries.resize(count);
822  for (uint32 i = 0; i < count; ++i) {
823    RCHECK(reader->Read4(&entries[i].sample_count) &&
824           reader->Read4(&entries[i].group_description_index));
825  }
826  return true;
827}
828
829CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
830    : is_encrypted(false), iv_size(0) {}
831CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
832
833SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
834SampleGroupDescription::~SampleGroupDescription() {}
835FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }
836
837bool SampleGroupDescription::Parse(BoxReader* reader) {
838  RCHECK(reader->ReadFullBoxHeader() &&
839         reader->Read4(&grouping_type));
840
841  if (grouping_type != FOURCC_SEIG) {
842    DLOG(WARNING) << "SampleGroupDescription box with grouping_type '"
843                  << grouping_type << "' is not supported.";
844    return true;
845  }
846
847  const uint8 version = reader->version();
848
849  const size_t kKeyIdSize = 16;
850  const size_t kEntrySize = sizeof(uint32) + kKeyIdSize;
851  uint32 default_length = 0;
852  if (version == 1) {
853      RCHECK(reader->Read4(&default_length));
854      RCHECK(default_length == 0 || default_length >= kEntrySize);
855  }
856
857  uint32 count;
858  RCHECK(reader->Read4(&count));
859  entries.resize(count);
860  for (uint32 i = 0; i < count; ++i) {
861    if (version == 1) {
862      if (default_length == 0) {
863        uint32 description_length = 0;
864        RCHECK(reader->Read4(&description_length));
865        RCHECK(description_length >= kEntrySize);
866      }
867    }
868
869    uint8 flag;
870    RCHECK(reader->SkipBytes(2) &&  // reserved.
871           reader->Read1(&flag) &&
872           reader->Read1(&entries[i].iv_size) &&
873           reader->ReadVec(&entries[i].key_id, kKeyIdSize));
874
875    entries[i].is_encrypted = (flag != 0);
876    if (entries[i].is_encrypted) {
877      RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
878    } else {
879      RCHECK(entries[i].iv_size == 0);
880    }
881  }
882  return true;
883}
884
885TrackFragment::TrackFragment() {}
886TrackFragment::~TrackFragment() {}
887FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }
888
889bool TrackFragment::Parse(BoxReader* reader) {
890  RCHECK(reader->ScanChildren() &&
891         reader->ReadChild(&header) &&
892         // Media Source specific: 'tfdt' required
893         reader->ReadChild(&decode_time) &&
894         reader->MaybeReadChildren(&runs) &&
895         reader->MaybeReadChild(&auxiliary_offset) &&
896         reader->MaybeReadChild(&auxiliary_size) &&
897         reader->MaybeReadChild(&sdtp));
898
899  // There could be multiple SampleGroupDescription and SampleToGroup boxes with
900  // different grouping types. For common encryption, the relevant grouping type
901  // is 'seig'. Continue reading until 'seig' is found, or until running out of
902  // child boxes.
903  while (sample_group_description.grouping_type != FOURCC_SEIG &&
904         reader->HasChild(&sample_group_description)) {
905    RCHECK(reader->ReadChild(&sample_group_description));
906  }
907  while (sample_to_group.grouping_type != FOURCC_SEIG &&
908         reader->HasChild(&sample_to_group)) {
909    RCHECK(reader->ReadChild(&sample_to_group));
910  }
911  return true;
912}
913
914MovieFragment::MovieFragment() {}
915MovieFragment::~MovieFragment() {}
916FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; }
917
918bool MovieFragment::Parse(BoxReader* reader) {
919  RCHECK(reader->ScanChildren() &&
920         reader->ReadChild(&header) &&
921         reader->ReadChildren(&tracks) &&
922         reader->MaybeReadChildren(&pssh));
923  return true;
924}
925
926IndependentAndDisposableSamples::IndependentAndDisposableSamples() {}
927IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {}
928FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; }
929
930bool IndependentAndDisposableSamples::Parse(BoxReader* reader) {
931  RCHECK(reader->ReadFullBoxHeader());
932  RCHECK(reader->version() == 0);
933  RCHECK(reader->flags() == 0);
934
935  int sample_count = reader->size() - reader->pos();
936  sample_depends_on_.resize(sample_count);
937  for (int i = 0; i < sample_count; ++i) {
938    uint8 sample_info;
939    RCHECK(reader->Read1(&sample_info));
940
941    sample_depends_on_[i] =
942        static_cast<SampleDependsOn>((sample_info >> 4) & 0x3);
943
944    RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved);
945  }
946
947  return true;
948}
949
950SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
951    size_t i) const {
952  if (i >= sample_depends_on_.size())
953    return kSampleDependsOnUnknown;
954
955  return sample_depends_on_[i];
956}
957
958}  // namespace mp4
959}  // namespace media
960