Home | History | Annotate | Download | only in mp4
      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 
     11 namespace media {
     12 namespace mp4 {
     13 
     14 FileType::FileType() {}
     15 FileType::~FileType() {}
     16 FourCC FileType::BoxType() const { return FOURCC_FTYP; }
     17 
     18 bool 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 
     24 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
     25 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
     26 FourCC ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH; }
     27 
     28 bool 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 
     42 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
     43 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
     44 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; }
     45 
     46 bool 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 
     66 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
     67   : default_sample_info_size(0), sample_count(0) {
     68 }
     69 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
     70 FourCC SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ; }
     71 
     72 bool 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 
     84 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
     85 OriginalFormat::~OriginalFormat() {}
     86 FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; }
     87 
     88 bool OriginalFormat::Parse(BoxReader* reader) {
     89   return reader->ReadFourCC(&format);
     90 }
     91 
     92 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
     93 SchemeType::~SchemeType() {}
     94 FourCC SchemeType::BoxType() const { return FOURCC_SCHM; }
     95 
     96 bool SchemeType::Parse(BoxReader* reader) {
     97   RCHECK(reader->ReadFullBoxHeader() &&
     98          reader->ReadFourCC(&type) &&
     99          reader->Read4(&version));
    100   return true;
    101 }
    102 
    103 TrackEncryption::TrackEncryption()
    104   : is_encrypted(false), default_iv_size(0) {
    105 }
    106 TrackEncryption::~TrackEncryption() {}
    107 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }
    108 
    109 bool 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 
    125 SchemeInfo::SchemeInfo() {}
    126 SchemeInfo::~SchemeInfo() {}
    127 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; }
    128 
    129 bool SchemeInfo::Parse(BoxReader* reader) {
    130   return reader->ScanChildren() && reader->ReadChild(&track_encryption);
    131 }
    132 
    133 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
    134 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
    135 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; }
    136 
    137 bool 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 
    150 MovieHeader::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) {}
    158 MovieHeader::~MovieHeader() {}
    159 FourCC MovieHeader::BoxType() const { return FOURCC_MVHD; }
    160 
    161 bool 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 
    185 TrackHeader::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) {}
    195 TrackHeader::~TrackHeader() {}
    196 FourCC TrackHeader::BoxType() const { return FOURCC_TKHD; }
    197 
    198 bool 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 
    227 SampleDescription::SampleDescription() : type(kInvalid) {}
    228 SampleDescription::~SampleDescription() {}
    229 FourCC SampleDescription::BoxType() const { return FOURCC_STSD; }
    230 
    231 bool 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 
    248 SyncSample::SyncSample() : is_present(false) {}
    249 SyncSample::~SyncSample() {}
    250 FourCC SyncSample::BoxType() const { return FOURCC_STSS; }
    251 
    252 bool 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 
    270 bool 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 
    289 SampleTable::SampleTable() {}
    290 SampleTable::~SampleTable() {}
    291 FourCC SampleTable::BoxType() const { return FOURCC_STBL; }
    292 
    293 bool SampleTable::Parse(BoxReader* reader) {
    294   return reader->ScanChildren() &&
    295       reader->ReadChild(&description) &&
    296       reader->MaybeReadChild(&sync_sample);
    297 }
    298 
    299 EditList::EditList() {}
    300 EditList::~EditList() {}
    301 FourCC EditList::BoxType() const { return FOURCC_ELST; }
    302 
    303 bool 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 
    329 Edit::Edit() {}
    330 Edit::~Edit() {}
    331 FourCC Edit::BoxType() const { return FOURCC_EDTS; }
    332 
    333 bool Edit::Parse(BoxReader* reader) {
    334   return reader->ScanChildren() && reader->ReadChild(&list);
    335 }
    336 
    337 HandlerReference::HandlerReference() : type(kInvalid) {}
    338 HandlerReference::~HandlerReference() {}
    339 FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; }
    340 
    341 bool 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 
    355 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
    356     : version(0),
    357       profile_indication(0),
    358       profile_compatibility(0),
    359       avc_level(0),
    360       length_size(0) {}
    361 
    362 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {}
    363 FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; }
    364 
    365 bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
    366   return ParseInternal(reader, reader->log_cb());
    367 }
    368 
    369 bool AVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) {
    370   BufferReader reader(data, data_size);
    371   return ParseInternal(&reader, LogCB());
    372 }
    373 
    374 bool 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 
    419 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {}
    420 PixelAspectRatioBox::~PixelAspectRatioBox() {}
    421 FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; }
    422 
    423 bool PixelAspectRatioBox::Parse(BoxReader* reader) {
    424   RCHECK(reader->Read4(&h_spacing) &&
    425          reader->Read4(&v_spacing));
    426   return true;
    427 }
    428 
    429 VideoSampleEntry::VideoSampleEntry()
    430     : format(FOURCC_NULL),
    431       data_reference_index(0),
    432       width(0),
    433       height(0) {}
    434 
    435 VideoSampleEntry::~VideoSampleEntry() {}
    436 FourCC 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 
    442 bool 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 
    469 bool 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 
    475 ElementaryStreamDescriptor::ElementaryStreamDescriptor()
    476     : object_type(kForbidden) {}
    477 
    478 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
    479 
    480 FourCC ElementaryStreamDescriptor::BoxType() const {
    481   return FOURCC_ESDS;
    482 }
    483 
    484 bool 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 
    505 AudioSampleEntry::AudioSampleEntry()
    506     : format(FOURCC_NULL),
    507       data_reference_index(0),
    508       channelcount(0),
    509       samplesize(0),
    510       samplerate(0) {}
    511 
    512 AudioSampleEntry::~AudioSampleEntry() {}
    513 
    514 FourCC 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 
    520 bool 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 
    547 MediaHeader::MediaHeader()
    548     : creation_time(0),
    549       modification_time(0),
    550       timescale(0),
    551       duration(0) {}
    552 MediaHeader::~MediaHeader() {}
    553 FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; }
    554 
    555 bool 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 
    573 MediaInformation::MediaInformation() {}
    574 MediaInformation::~MediaInformation() {}
    575 FourCC MediaInformation::BoxType() const { return FOURCC_MINF; }
    576 
    577 bool MediaInformation::Parse(BoxReader* reader) {
    578   return reader->ScanChildren() &&
    579          reader->ReadChild(&sample_table);
    580 }
    581 
    582 Media::Media() {}
    583 Media::~Media() {}
    584 FourCC Media::BoxType() const { return FOURCC_MDIA; }
    585 
    586 bool 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 
    602 Track::Track() {}
    603 Track::~Track() {}
    604 FourCC Track::BoxType() const { return FOURCC_TRAK; }
    605 
    606 bool 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 
    614 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
    615 MovieExtendsHeader::~MovieExtendsHeader() {}
    616 FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; }
    617 
    618 bool 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 
    628 TrackExtends::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) {}
    634 TrackExtends::~TrackExtends() {}
    635 FourCC TrackExtends::BoxType() const { return FOURCC_TREX; }
    636 
    637 bool 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 
    647 MovieExtends::MovieExtends() {}
    648 MovieExtends::~MovieExtends() {}
    649 FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; }
    650 
    651 bool MovieExtends::Parse(BoxReader* reader) {
    652   header.fragment_duration = 0;
    653   return reader->ScanChildren() &&
    654          reader->MaybeReadChild(&header) &&
    655          reader->ReadChildren(&tracks);
    656 }
    657 
    658 Movie::Movie() : fragmented(false) {}
    659 Movie::~Movie() {}
    660 FourCC Movie::BoxType() const { return FOURCC_MOOV; }
    661 
    662 bool 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 
    671 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
    672 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
    673 FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; }
    674 
    675 bool 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 
    683 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
    684 MovieFragmentHeader::~MovieFragmentHeader() {}
    685 FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; }
    686 
    687 bool MovieFragmentHeader::Parse(BoxReader* reader) {
    688   return reader->SkipBytes(4) && reader->Read4(&sequence_number);
    689 }
    690 
    691 TrackFragmentHeader::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 
    699 TrackFragmentHeader::~TrackFragmentHeader() {}
    700 FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; }
    701 
    702 bool 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 
    741 TrackFragmentRun::TrackFragmentRun()
    742     : sample_count(0), data_offset(0) {}
    743 TrackFragmentRun::~TrackFragmentRun() {}
    744 FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; }
    745 
    746 bool 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;
    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 
    802 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
    803 SampleToGroup::~SampleToGroup() {}
    804 FourCC SampleToGroup::BoxType() const { return FOURCC_SBGP; }
    805 
    806 bool 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 
    829 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
    830     : is_encrypted(false), iv_size(0) {}
    831 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
    832 
    833 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
    834 SampleGroupDescription::~SampleGroupDescription() {}
    835 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }
    836 
    837 bool 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 
    885 TrackFragment::TrackFragment() {}
    886 TrackFragment::~TrackFragment() {}
    887 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }
    888 
    889 bool 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 
    914 MovieFragment::MovieFragment() {}
    915 MovieFragment::~MovieFragment() {}
    916 FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; }
    917 
    918 bool 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 
    926 IndependentAndDisposableSamples::IndependentAndDisposableSamples() {}
    927 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {}
    928 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; }
    929 
    930 bool 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 
    950 SampleDependsOn 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