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.
5 #include "media/formats/mp4/box_definitions.h"
7 #include "base/logging.h"
8 #include "media/base/video_types.h"
9 #include "media/base/video_util.h"
10 #include "media/formats/mp4/avc.h"
11 #include "media/formats/mp4/es_descriptor.h"
12 #include "media/formats/mp4/rcheck.h"
14 #if defined(ENABLE_HEVC_DEMUXING)
15 #include "media/formats/mp4/hevc.h"
21 FileType::FileType() {}
22 FileType::~FileType() {}
23 FourCC
FileType::BoxType() const { return FOURCC_FTYP
; }
25 bool FileType::Parse(BoxReader
* reader
) {
26 RCHECK(reader
->ReadFourCC(&major_brand
) && reader
->Read4(&minor_version
));
27 size_t num_brands
= (reader
->size() - reader
->pos()) / sizeof(FourCC
);
28 return reader
->SkipBytes(sizeof(FourCC
) * num_brands
); // compatible_brands
31 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
32 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
33 FourCC
ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH
; }
35 bool ProtectionSystemSpecificHeader::Parse(BoxReader
* reader
) {
36 // Don't bother validating the box's contents.
37 // Copy the entire box, including the header, for passing to EME as initData.
38 DCHECK(raw_box
.empty());
39 raw_box
.assign(reader
->data(), reader
->data() + reader
->size());
43 FullProtectionSystemSpecificHeader::FullProtectionSystemSpecificHeader() {}
44 FullProtectionSystemSpecificHeader::~FullProtectionSystemSpecificHeader() {}
45 FourCC
FullProtectionSystemSpecificHeader::BoxType() const {
49 // The format of a 'pssh' box is as follows:
50 // unsigned int(32) size;
51 // unsigned int(32) type = "pssh";
53 // unsigned int(64) largesize;
54 // } else if (size==0) {
55 // -- box extends to end of file
57 // unsigned int(8) version;
59 // unsigned int(8)[16] SystemID;
62 // unsigned int(32) KID_count;
64 // unsigned int(8)[16] KID;
67 // unsigned int(32) DataSize;
68 // unsigned int(8)[DataSize] Data;
70 bool FullProtectionSystemSpecificHeader::Parse(mp4::BoxReader
* reader
) {
71 RCHECK(reader
->type() == BoxType() && reader
->ReadFullBoxHeader());
73 // Only versions 0 and 1 of the 'pssh' boxes are supported. Any other
74 // versions are ignored.
75 RCHECK(reader
->version() == 0 || reader
->version() == 1);
76 RCHECK(reader
->flags() == 0);
77 RCHECK(reader
->ReadVec(&system_id
, 16));
79 if (reader
->version() > 0) {
81 RCHECK(reader
->Read4(&kid_count
));
82 for (uint32_t i
= 0; i
< kid_count
; ++i
) {
83 std::vector
<uint8_t> kid
;
84 RCHECK(reader
->ReadVec(&kid
, 16));
85 key_ids
.push_back(kid
);
90 RCHECK(reader
->Read4(&data_size
));
91 RCHECK(reader
->ReadVec(&data
, data_size
));
95 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
96 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
97 FourCC
SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO
; }
99 bool SampleAuxiliaryInformationOffset::Parse(BoxReader
* reader
) {
100 RCHECK(reader
->ReadFullBoxHeader());
101 if (reader
->flags() & 1)
102 RCHECK(reader
->SkipBytes(8));
105 RCHECK(reader
->Read4(&count
) &&
106 reader
->HasBytes(count
* (reader
->version() == 1 ? 8 : 4)));
107 offsets
.resize(count
);
109 for (uint32 i
= 0; i
< count
; i
++) {
110 if (reader
->version() == 1) {
111 RCHECK(reader
->Read8(&offsets
[i
]));
113 RCHECK(reader
->Read4Into8(&offsets
[i
]));
119 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
120 : default_sample_info_size(0), sample_count(0) {
122 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
123 FourCC
SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ
; }
125 bool SampleAuxiliaryInformationSize::Parse(BoxReader
* reader
) {
126 RCHECK(reader
->ReadFullBoxHeader());
127 if (reader
->flags() & 1)
128 RCHECK(reader
->SkipBytes(8));
130 RCHECK(reader
->Read1(&default_sample_info_size
) &&
131 reader
->Read4(&sample_count
));
132 if (default_sample_info_size
== 0)
133 return reader
->ReadVec(&sample_info_sizes
, sample_count
);
137 OriginalFormat::OriginalFormat() : format(FOURCC_NULL
) {}
138 OriginalFormat::~OriginalFormat() {}
139 FourCC
OriginalFormat::BoxType() const { return FOURCC_FRMA
; }
141 bool OriginalFormat::Parse(BoxReader
* reader
) {
142 return reader
->ReadFourCC(&format
);
145 SchemeType::SchemeType() : type(FOURCC_NULL
), version(0) {}
146 SchemeType::~SchemeType() {}
147 FourCC
SchemeType::BoxType() const { return FOURCC_SCHM
; }
149 bool SchemeType::Parse(BoxReader
* reader
) {
150 RCHECK(reader
->ReadFullBoxHeader() &&
151 reader
->ReadFourCC(&type
) &&
152 reader
->Read4(&version
));
156 TrackEncryption::TrackEncryption()
157 : is_encrypted(false), default_iv_size(0) {
159 TrackEncryption::~TrackEncryption() {}
160 FourCC
TrackEncryption::BoxType() const { return FOURCC_TENC
; }
162 bool TrackEncryption::Parse(BoxReader
* reader
) {
164 RCHECK(reader
->ReadFullBoxHeader() &&
165 reader
->SkipBytes(2) &&
166 reader
->Read1(&flag
) &&
167 reader
->Read1(&default_iv_size
) &&
168 reader
->ReadVec(&default_kid
, 16));
169 is_encrypted
= (flag
!= 0);
171 RCHECK(default_iv_size
== 8 || default_iv_size
== 16);
173 RCHECK(default_iv_size
== 0);
178 SchemeInfo::SchemeInfo() {}
179 SchemeInfo::~SchemeInfo() {}
180 FourCC
SchemeInfo::BoxType() const { return FOURCC_SCHI
; }
182 bool SchemeInfo::Parse(BoxReader
* reader
) {
183 return reader
->ScanChildren() && reader
->ReadChild(&track_encryption
);
186 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
187 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
188 FourCC
ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF
; }
190 bool ProtectionSchemeInfo::Parse(BoxReader
* reader
) {
191 RCHECK(reader
->ScanChildren() &&
192 reader
->ReadChild(&format
) &&
193 reader
->ReadChild(&type
));
194 if (type
.type
== FOURCC_CENC
)
195 RCHECK(reader
->ReadChild(&info
));
196 // Other protection schemes are silently ignored. Since the protection scheme
197 // type can't be determined until this box is opened, we return 'true' for
198 // non-CENC protection scheme types. It is the parent box's responsibility to
199 // ensure that this scheme type is a supported one.
203 MovieHeader::MovieHeader()
205 modification_time(0),
211 MovieHeader::~MovieHeader() {}
212 FourCC
MovieHeader::BoxType() const { return FOURCC_MVHD
; }
214 bool MovieHeader::Parse(BoxReader
* reader
) {
215 RCHECK(reader
->ReadFullBoxHeader());
217 if (reader
->version() == 1) {
218 RCHECK(reader
->Read8(&creation_time
) &&
219 reader
->Read8(&modification_time
) &&
220 reader
->Read4(×cale
) &&
221 reader
->Read8(&duration
));
223 RCHECK(reader
->Read4Into8(&creation_time
) &&
224 reader
->Read4Into8(&modification_time
) &&
225 reader
->Read4(×cale
) &&
226 reader
->Read4Into8(&duration
));
229 RCHECK(reader
->Read4s(&rate
) &&
230 reader
->Read2s(&volume
) &&
231 reader
->SkipBytes(10) && // reserved
232 reader
->SkipBytes(36) && // matrix
233 reader
->SkipBytes(24) && // predefined zero
234 reader
->Read4(&next_track_id
));
238 TrackHeader::TrackHeader()
240 modification_time(0),
248 TrackHeader::~TrackHeader() {}
249 FourCC
TrackHeader::BoxType() const { return FOURCC_TKHD
; }
251 bool TrackHeader::Parse(BoxReader
* reader
) {
252 RCHECK(reader
->ReadFullBoxHeader());
253 if (reader
->version() == 1) {
254 RCHECK(reader
->Read8(&creation_time
) &&
255 reader
->Read8(&modification_time
) &&
256 reader
->Read4(&track_id
) &&
257 reader
->SkipBytes(4) && // reserved
258 reader
->Read8(&duration
));
260 RCHECK(reader
->Read4Into8(&creation_time
) &&
261 reader
->Read4Into8(&modification_time
) &&
262 reader
->Read4(&track_id
) &&
263 reader
->SkipBytes(4) && // reserved
264 reader
->Read4Into8(&duration
));
267 RCHECK(reader
->SkipBytes(8) && // reserved
268 reader
->Read2s(&layer
) &&
269 reader
->Read2s(&alternate_group
) &&
270 reader
->Read2s(&volume
) &&
271 reader
->SkipBytes(2) && // reserved
272 reader
->SkipBytes(36) && // matrix
273 reader
->Read4(&width
) &&
274 reader
->Read4(&height
));
276 // Round width and height to the nearest number.
277 // Note: width and height are fixed-point 16.16 values. The following code
278 // rounds a.1x to a + 1, and a.0x to a.
289 SampleDescription::SampleDescription() : type(kInvalid
) {}
290 SampleDescription::~SampleDescription() {}
291 FourCC
SampleDescription::BoxType() const { return FOURCC_STSD
; }
293 bool SampleDescription::Parse(BoxReader
* reader
) {
295 RCHECK(reader
->SkipBytes(4) &&
296 reader
->Read4(&count
));
297 video_entries
.clear();
298 audio_entries
.clear();
300 // Note: this value is preset before scanning begins. See comments in the
301 // Parse(Media*) function.
302 if (type
== kVideo
) {
303 RCHECK(reader
->ReadAllChildren(&video_entries
));
304 } else if (type
== kAudio
) {
305 RCHECK(reader
->ReadAllChildren(&audio_entries
));
310 SampleTable::SampleTable() {}
311 SampleTable::~SampleTable() {}
312 FourCC
SampleTable::BoxType() const { return FOURCC_STBL
; }
314 bool SampleTable::Parse(BoxReader
* reader
) {
315 RCHECK(reader
->ScanChildren() &&
316 reader
->ReadChild(&description
));
317 // There could be multiple SampleGroupDescription boxes with different
318 // grouping types. For common encryption, the relevant grouping type is
319 // 'seig'. Continue reading until 'seig' is found, or until running out of
321 while (reader
->HasChild(&sample_group_description
)) {
322 RCHECK(reader
->ReadChild(&sample_group_description
));
323 if (sample_group_description
.grouping_type
== FOURCC_SEIG
)
325 sample_group_description
.entries
.clear();
330 EditList::EditList() {}
331 EditList::~EditList() {}
332 FourCC
EditList::BoxType() const { return FOURCC_ELST
; }
334 bool EditList::Parse(BoxReader
* reader
) {
336 RCHECK(reader
->ReadFullBoxHeader() && reader
->Read4(&count
));
338 if (reader
->version() == 1) {
339 RCHECK(reader
->HasBytes(count
* 20));
341 RCHECK(reader
->HasBytes(count
* 12));
345 for (std::vector
<EditListEntry
>::iterator edit
= edits
.begin();
346 edit
!= edits
.end(); ++edit
) {
347 if (reader
->version() == 1) {
348 RCHECK(reader
->Read8(&edit
->segment_duration
) &&
349 reader
->Read8s(&edit
->media_time
));
351 RCHECK(reader
->Read4Into8(&edit
->segment_duration
) &&
352 reader
->Read4sInto8s(&edit
->media_time
));
354 RCHECK(reader
->Read2s(&edit
->media_rate_integer
) &&
355 reader
->Read2s(&edit
->media_rate_fraction
));
362 FourCC
Edit::BoxType() const { return FOURCC_EDTS
; }
364 bool Edit::Parse(BoxReader
* reader
) {
365 return reader
->ScanChildren() && reader
->ReadChild(&list
);
368 HandlerReference::HandlerReference() : type(kInvalid
) {}
369 HandlerReference::~HandlerReference() {}
370 FourCC
HandlerReference::BoxType() const { return FOURCC_HDLR
; }
372 bool HandlerReference::Parse(BoxReader
* reader
) {
374 RCHECK(reader
->SkipBytes(8) && reader
->ReadFourCC(&hdlr_type
));
375 // Note: remaining fields in box ignored
376 if (hdlr_type
== FOURCC_VIDE
) {
378 } else if (hdlr_type
== FOURCC_SOUN
) {
386 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
388 profile_indication(0),
389 profile_compatibility(0),
393 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {}
394 FourCC
AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC
; }
396 bool AVCDecoderConfigurationRecord::Parse(BoxReader
* reader
) {
397 return ParseInternal(reader
, reader
->media_log());
400 bool AVCDecoderConfigurationRecord::Parse(const uint8
* data
, int data_size
) {
401 BufferReader
reader(data
, data_size
);
402 return ParseInternal(&reader
, new MediaLog());
405 bool AVCDecoderConfigurationRecord::ParseInternal(
406 BufferReader
* reader
,
407 const scoped_refptr
<MediaLog
>& media_log
) {
408 RCHECK(reader
->Read1(&version
) && version
== 1 &&
409 reader
->Read1(&profile_indication
) &&
410 reader
->Read1(&profile_compatibility
) &&
411 reader
->Read1(&avc_level
));
413 uint8 length_size_minus_one
;
414 RCHECK(reader
->Read1(&length_size_minus_one
));
415 length_size
= (length_size_minus_one
& 0x3) + 1;
417 RCHECK(length_size
!= 3); // Only values of 1, 2, and 4 are valid.
420 RCHECK(reader
->Read1(&num_sps
));
423 sps_list
.resize(num_sps
);
424 for (int i
= 0; i
< num_sps
; i
++) {
426 RCHECK(reader
->Read2(&sps_length
) &&
427 reader
->ReadVec(&sps_list
[i
], sps_length
));
428 RCHECK(sps_list
[i
].size() > 4);
430 if (media_log
.get()) {
431 MEDIA_LOG(INFO
, media_log
) << "Video codec: avc1." << std::hex
432 << static_cast<int>(sps_list
[i
][1])
433 << static_cast<int>(sps_list
[i
][2])
434 << static_cast<int>(sps_list
[i
][3]);
439 RCHECK(reader
->Read1(&num_pps
));
441 pps_list
.resize(num_pps
);
442 for (int i
= 0; i
< num_pps
; i
++) {
444 RCHECK(reader
->Read2(&pps_length
) &&
445 reader
->ReadVec(&pps_list
[i
], pps_length
));
451 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {}
452 PixelAspectRatioBox::~PixelAspectRatioBox() {}
453 FourCC
PixelAspectRatioBox::BoxType() const { return FOURCC_PASP
; }
455 bool PixelAspectRatioBox::Parse(BoxReader
* reader
) {
456 RCHECK(reader
->Read4(&h_spacing
) &&
457 reader
->Read4(&v_spacing
));
461 VideoSampleEntry::VideoSampleEntry()
462 : format(FOURCC_NULL
),
463 data_reference_index(0),
466 video_codec(kUnknownVideoCodec
),
467 video_codec_profile(VIDEO_CODEC_PROFILE_UNKNOWN
) {}
469 VideoSampleEntry::~VideoSampleEntry() {}
470 FourCC
VideoSampleEntry::BoxType() const {
471 DCHECK(false) << "VideoSampleEntry should be parsed according to the "
472 << "handler type recovered in its Media ancestor.";
478 bool IsFormatValidH264(const FourCC
& format
,
479 const ProtectionSchemeInfo
& sinf
) {
480 return format
== FOURCC_AVC1
|| format
== FOURCC_AVC3
||
481 (format
== FOURCC_ENCV
&& (sinf
.format
.format
== FOURCC_AVC1
||
482 sinf
.format
.format
== FOURCC_AVC3
));
485 #if defined(ENABLE_HEVC_DEMUXING)
486 bool IsFormatValidHEVC(const FourCC
& format
,
487 const ProtectionSchemeInfo
& sinf
) {
488 return format
== FOURCC_HEV1
|| format
== FOURCC_HVC1
||
489 (format
== FOURCC_ENCV
&& (sinf
.format
.format
== FOURCC_HEV1
||
490 sinf
.format
.format
== FOURCC_HVC1
));
496 bool VideoSampleEntry::Parse(BoxReader
* reader
) {
497 format
= reader
->type();
498 RCHECK(reader
->SkipBytes(6) &&
499 reader
->Read2(&data_reference_index
) &&
500 reader
->SkipBytes(16) &&
501 reader
->Read2(&width
) &&
502 reader
->Read2(&height
) &&
503 reader
->SkipBytes(50));
505 RCHECK(reader
->ScanChildren() &&
506 reader
->MaybeReadChild(&pixel_aspect
));
508 if (format
== FOURCC_ENCV
) {
509 // Continue scanning until a recognized protection scheme is found, or until
510 // we run out of protection schemes.
511 while (sinf
.type
.type
!= FOURCC_CENC
) {
512 if (!reader
->ReadChild(&sinf
))
517 if (IsFormatValidH264(format
, sinf
)) {
518 DVLOG(2) << __FUNCTION__
519 << " reading AVCDecoderConfigurationRecord (avcC)";
520 scoped_ptr
<AVCDecoderConfigurationRecord
> avcConfig(
521 new AVCDecoderConfigurationRecord());
522 RCHECK(reader
->ReadChild(avcConfig
.get()));
523 frame_bitstream_converter
= make_scoped_refptr(
524 new AVCBitstreamConverter(avcConfig
.Pass()));
525 video_codec
= kCodecH264
;
526 video_codec_profile
= H264PROFILE_MAIN
;
527 #if defined(ENABLE_HEVC_DEMUXING)
528 } else if (IsFormatValidHEVC(format
, sinf
)) {
529 DVLOG(2) << __FUNCTION__
530 << " parsing HEVCDecoderConfigurationRecord (hvcC)";
531 scoped_ptr
<HEVCDecoderConfigurationRecord
> hevcConfig(
532 new HEVCDecoderConfigurationRecord());
533 RCHECK(reader
->ReadChild(hevcConfig
.get()));
534 frame_bitstream_converter
= make_scoped_refptr(
535 new HEVCBitstreamConverter(hevcConfig
.Pass()));
536 video_codec
= kCodecHEVC
;
539 // Unknown/unsupported format
540 MEDIA_LOG(ERROR
, reader
->media_log()) << __FUNCTION__
541 << " unsupported video format "
542 << FourCCToString(format
);
549 bool VideoSampleEntry::IsFormatValid() const {
550 #if defined(ENABLE_HEVC_DEMUXING)
551 if (IsFormatValidHEVC(format
, sinf
))
554 return IsFormatValidH264(format
, sinf
);
557 ElementaryStreamDescriptor::ElementaryStreamDescriptor()
558 : object_type(kForbidden
) {}
560 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
562 FourCC
ElementaryStreamDescriptor::BoxType() const {
566 bool ElementaryStreamDescriptor::Parse(BoxReader
* reader
) {
567 std::vector
<uint8
> data
;
568 ESDescriptor es_desc
;
570 RCHECK(reader
->ReadFullBoxHeader());
571 RCHECK(reader
->ReadVec(&data
, reader
->size() - reader
->pos()));
572 RCHECK(es_desc
.Parse(data
));
574 object_type
= es_desc
.object_type();
576 if (object_type
!= 0x40) {
577 MEDIA_LOG(INFO
, reader
->media_log()) << "Audio codec: mp4a." << std::hex
578 << static_cast<int>(object_type
);
581 if (es_desc
.IsAAC(object_type
))
582 RCHECK(aac
.Parse(es_desc
.decoder_specific_info(), reader
->media_log()));
587 AudioSampleEntry::AudioSampleEntry()
588 : format(FOURCC_NULL
),
589 data_reference_index(0),
594 AudioSampleEntry::~AudioSampleEntry() {}
596 FourCC
AudioSampleEntry::BoxType() const {
597 DCHECK(false) << "AudioSampleEntry should be parsed according to the "
598 << "handler type recovered in its Media ancestor.";
602 bool AudioSampleEntry::Parse(BoxReader
* reader
) {
603 format
= reader
->type();
604 RCHECK(reader
->SkipBytes(6) &&
605 reader
->Read2(&data_reference_index
) &&
606 reader
->SkipBytes(8) &&
607 reader
->Read2(&channelcount
) &&
608 reader
->Read2(&samplesize
) &&
609 reader
->SkipBytes(4) &&
610 reader
->Read4(&samplerate
));
611 // Convert from 16.16 fixed point to integer
614 RCHECK(reader
->ScanChildren());
615 if (format
== FOURCC_ENCA
) {
616 // Continue scanning until a recognized protection scheme is found, or until
617 // we run out of protection schemes.
618 while (sinf
.type
.type
!= FOURCC_CENC
) {
619 if (!reader
->ReadChild(&sinf
))
624 // ESDS is not valid in case of EAC3.
625 RCHECK(reader
->MaybeReadChild(&esds
));
629 MediaHeader::MediaHeader()
631 modification_time(0),
634 MediaHeader::~MediaHeader() {}
635 FourCC
MediaHeader::BoxType() const { return FOURCC_MDHD
; }
637 bool MediaHeader::Parse(BoxReader
* reader
) {
638 RCHECK(reader
->ReadFullBoxHeader());
640 if (reader
->version() == 1) {
641 RCHECK(reader
->Read8(&creation_time
) &&
642 reader
->Read8(&modification_time
) &&
643 reader
->Read4(×cale
) &&
644 reader
->Read8(&duration
));
646 RCHECK(reader
->Read4Into8(&creation_time
) &&
647 reader
->Read4Into8(&modification_time
) &&
648 reader
->Read4(×cale
) &&
649 reader
->Read4Into8(&duration
));
651 // Skip language information
652 return reader
->SkipBytes(4);
655 MediaInformation::MediaInformation() {}
656 MediaInformation::~MediaInformation() {}
657 FourCC
MediaInformation::BoxType() const { return FOURCC_MINF
; }
659 bool MediaInformation::Parse(BoxReader
* reader
) {
660 return reader
->ScanChildren() &&
661 reader
->ReadChild(&sample_table
);
666 FourCC
Media::BoxType() const { return FOURCC_MDIA
; }
668 bool Media::Parse(BoxReader
* reader
) {
669 RCHECK(reader
->ScanChildren() &&
670 reader
->ReadChild(&header
) &&
671 reader
->ReadChild(&handler
));
673 // Maddeningly, the HandlerReference box specifies how to parse the
674 // SampleDescription box, making the latter the only box (of those that we
675 // support) which cannot be parsed correctly on its own (or even with
676 // information from its strict ancestor tree). We thus copy the handler type
677 // to the sample description box *before* parsing it to provide this
678 // information while parsing.
679 information
.sample_table
.description
.type
= handler
.type
;
680 RCHECK(reader
->ReadChild(&information
));
686 FourCC
Track::BoxType() const { return FOURCC_TRAK
; }
688 bool Track::Parse(BoxReader
* reader
) {
689 RCHECK(reader
->ScanChildren() &&
690 reader
->ReadChild(&header
) &&
691 reader
->ReadChild(&media
) &&
692 reader
->MaybeReadChild(&edit
));
696 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
697 MovieExtendsHeader::~MovieExtendsHeader() {}
698 FourCC
MovieExtendsHeader::BoxType() const { return FOURCC_MEHD
; }
700 bool MovieExtendsHeader::Parse(BoxReader
* reader
) {
701 RCHECK(reader
->ReadFullBoxHeader());
702 if (reader
->version() == 1) {
703 RCHECK(reader
->Read8(&fragment_duration
));
705 RCHECK(reader
->Read4Into8(&fragment_duration
));
710 TrackExtends::TrackExtends()
712 default_sample_description_index(0),
713 default_sample_duration(0),
714 default_sample_size(0),
715 default_sample_flags(0) {}
716 TrackExtends::~TrackExtends() {}
717 FourCC
TrackExtends::BoxType() const { return FOURCC_TREX
; }
719 bool TrackExtends::Parse(BoxReader
* reader
) {
720 RCHECK(reader
->ReadFullBoxHeader() &&
721 reader
->Read4(&track_id
) &&
722 reader
->Read4(&default_sample_description_index
) &&
723 reader
->Read4(&default_sample_duration
) &&
724 reader
->Read4(&default_sample_size
) &&
725 reader
->Read4(&default_sample_flags
));
729 MovieExtends::MovieExtends() {}
730 MovieExtends::~MovieExtends() {}
731 FourCC
MovieExtends::BoxType() const { return FOURCC_MVEX
; }
733 bool MovieExtends::Parse(BoxReader
* reader
) {
734 header
.fragment_duration
= 0;
735 return reader
->ScanChildren() &&
736 reader
->MaybeReadChild(&header
) &&
737 reader
->ReadChildren(&tracks
);
740 Movie::Movie() : fragmented(false) {}
742 FourCC
Movie::BoxType() const { return FOURCC_MOOV
; }
744 bool Movie::Parse(BoxReader
* reader
) {
745 RCHECK(reader
->ScanChildren() && reader
->ReadChild(&header
) &&
746 reader
->ReadChildren(&tracks
));
748 RCHECK_MEDIA_LOGGED(reader
->ReadChild(&extends
), reader
->media_log(),
749 "Detected unfragmented MP4. Media Source Extensions "
750 "require ISO BMFF moov to contain mvex to indicate that "
751 "Movie Fragments are to be expected.");
753 return reader
->MaybeReadChildren(&pssh
);
756 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
757 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
758 FourCC
TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT
; }
760 bool TrackFragmentDecodeTime::Parse(BoxReader
* reader
) {
761 RCHECK(reader
->ReadFullBoxHeader());
762 if (reader
->version() == 1)
763 return reader
->Read8(&decode_time
);
765 return reader
->Read4Into8(&decode_time
);
768 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
769 MovieFragmentHeader::~MovieFragmentHeader() {}
770 FourCC
MovieFragmentHeader::BoxType() const { return FOURCC_MFHD
; }
772 bool MovieFragmentHeader::Parse(BoxReader
* reader
) {
773 return reader
->SkipBytes(4) && reader
->Read4(&sequence_number
);
776 TrackFragmentHeader::TrackFragmentHeader()
778 sample_description_index(0),
779 default_sample_duration(0),
780 default_sample_size(0),
781 default_sample_flags(0),
782 has_default_sample_flags(false) {}
784 TrackFragmentHeader::~TrackFragmentHeader() {}
785 FourCC
TrackFragmentHeader::BoxType() const { return FOURCC_TFHD
; }
787 bool TrackFragmentHeader::Parse(BoxReader
* reader
) {
788 RCHECK(reader
->ReadFullBoxHeader() && reader
->Read4(&track_id
));
790 // Media Source specific: reject tracks that set 'base-data-offset-present'.
791 // Although the Media Source requires that 'default-base-is-moof' (14496-12
792 // Amendment 2) be set, we omit this check as many otherwise-valid files in
793 // the wild don't set it.
795 // RCHECK((flags & 0x020000) && !(flags & 0x1));
796 RCHECK(!(reader
->flags() & 0x1));
798 if (reader
->flags() & 0x2) {
799 RCHECK(reader
->Read4(&sample_description_index
));
801 sample_description_index
= 0;
804 if (reader
->flags() & 0x8) {
805 RCHECK(reader
->Read4(&default_sample_duration
));
807 default_sample_duration
= 0;
810 if (reader
->flags() & 0x10) {
811 RCHECK(reader
->Read4(&default_sample_size
));
813 default_sample_size
= 0;
816 if (reader
->flags() & 0x20) {
817 RCHECK(reader
->Read4(&default_sample_flags
));
818 has_default_sample_flags
= true;
820 has_default_sample_flags
= false;
826 TrackFragmentRun::TrackFragmentRun()
827 : sample_count(0), data_offset(0) {}
828 TrackFragmentRun::~TrackFragmentRun() {}
829 FourCC
TrackFragmentRun::BoxType() const { return FOURCC_TRUN
; }
831 bool TrackFragmentRun::Parse(BoxReader
* reader
) {
832 RCHECK(reader
->ReadFullBoxHeader() &&
833 reader
->Read4(&sample_count
));
834 const uint32 flags
= reader
->flags();
836 bool data_offset_present
= (flags
& 0x1) != 0;
837 bool first_sample_flags_present
= (flags
& 0x4) != 0;
838 bool sample_duration_present
= (flags
& 0x100) != 0;
839 bool sample_size_present
= (flags
& 0x200) != 0;
840 bool sample_flags_present
= (flags
& 0x400) != 0;
841 bool sample_composition_time_offsets_present
= (flags
& 0x800) != 0;
843 if (data_offset_present
) {
844 RCHECK(reader
->Read4(&data_offset
));
849 uint32 first_sample_flags
= 0;
850 if (first_sample_flags_present
)
851 RCHECK(reader
->Read4(&first_sample_flags
));
853 int fields
= sample_duration_present
+ sample_size_present
+
854 sample_flags_present
+ sample_composition_time_offsets_present
;
855 RCHECK(reader
->HasBytes(fields
* sample_count
));
857 if (sample_duration_present
)
858 sample_durations
.resize(sample_count
);
859 if (sample_size_present
)
860 sample_sizes
.resize(sample_count
);
861 if (sample_flags_present
)
862 sample_flags
.resize(sample_count
);
863 if (sample_composition_time_offsets_present
)
864 sample_composition_time_offsets
.resize(sample_count
);
866 for (uint32 i
= 0; i
< sample_count
; ++i
) {
867 if (sample_duration_present
)
868 RCHECK(reader
->Read4(&sample_durations
[i
]));
869 if (sample_size_present
)
870 RCHECK(reader
->Read4(&sample_sizes
[i
]));
871 if (sample_flags_present
)
872 RCHECK(reader
->Read4(&sample_flags
[i
]));
873 if (sample_composition_time_offsets_present
)
874 RCHECK(reader
->Read4s(&sample_composition_time_offsets
[i
]));
877 if (first_sample_flags_present
) {
878 if (sample_flags
.size() == 0) {
879 sample_flags
.push_back(first_sample_flags
);
881 sample_flags
[0] = first_sample_flags
;
887 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
888 SampleToGroup::~SampleToGroup() {}
889 FourCC
SampleToGroup::BoxType() const { return FOURCC_SBGP
; }
891 bool SampleToGroup::Parse(BoxReader
* reader
) {
892 RCHECK(reader
->ReadFullBoxHeader() &&
893 reader
->Read4(&grouping_type
));
895 if (reader
->version() == 1)
896 RCHECK(reader
->Read4(&grouping_type_parameter
));
898 if (grouping_type
!= FOURCC_SEIG
) {
899 DLOG(WARNING
) << "SampleToGroup box with grouping_type '" << grouping_type
900 << "' is not supported.";
905 RCHECK(reader
->Read4(&count
));
906 entries
.resize(count
);
907 for (uint32 i
= 0; i
< count
; ++i
) {
908 RCHECK(reader
->Read4(&entries
[i
].sample_count
) &&
909 reader
->Read4(&entries
[i
].group_description_index
));
914 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
915 : is_encrypted(false), iv_size(0) {}
916 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
918 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
919 SampleGroupDescription::~SampleGroupDescription() {}
920 FourCC
SampleGroupDescription::BoxType() const { return FOURCC_SGPD
; }
922 bool SampleGroupDescription::Parse(BoxReader
* reader
) {
923 RCHECK(reader
->ReadFullBoxHeader() &&
924 reader
->Read4(&grouping_type
));
926 if (grouping_type
!= FOURCC_SEIG
) {
927 DLOG(WARNING
) << "SampleGroupDescription box with grouping_type '"
928 << grouping_type
<< "' is not supported.";
932 const uint8 version
= reader
->version();
934 const size_t kKeyIdSize
= 16;
935 const size_t kEntrySize
= sizeof(uint32
) + kKeyIdSize
;
936 uint32 default_length
= 0;
938 RCHECK(reader
->Read4(&default_length
));
939 RCHECK(default_length
== 0 || default_length
>= kEntrySize
);
943 RCHECK(reader
->Read4(&count
));
944 entries
.resize(count
);
945 for (uint32 i
= 0; i
< count
; ++i
) {
947 if (default_length
== 0) {
948 uint32 description_length
= 0;
949 RCHECK(reader
->Read4(&description_length
));
950 RCHECK(description_length
>= kEntrySize
);
955 RCHECK(reader
->SkipBytes(2) && // reserved.
956 reader
->Read1(&flag
) &&
957 reader
->Read1(&entries
[i
].iv_size
) &&
958 reader
->ReadVec(&entries
[i
].key_id
, kKeyIdSize
));
960 entries
[i
].is_encrypted
= (flag
!= 0);
961 if (entries
[i
].is_encrypted
) {
962 RCHECK(entries
[i
].iv_size
== 8 || entries
[i
].iv_size
== 16);
964 RCHECK(entries
[i
].iv_size
== 0);
970 TrackFragment::TrackFragment() {}
971 TrackFragment::~TrackFragment() {}
972 FourCC
TrackFragment::BoxType() const { return FOURCC_TRAF
; }
974 bool TrackFragment::Parse(BoxReader
* reader
) {
975 RCHECK(reader
->ScanChildren() &&
976 reader
->ReadChild(&header
) &&
977 // Media Source specific: 'tfdt' required
978 reader
->ReadChild(&decode_time
) &&
979 reader
->MaybeReadChildren(&runs
) &&
980 reader
->MaybeReadChild(&auxiliary_offset
) &&
981 reader
->MaybeReadChild(&auxiliary_size
) &&
982 reader
->MaybeReadChild(&sdtp
));
984 // There could be multiple SampleGroupDescription and SampleToGroup boxes with
985 // different grouping types. For common encryption, the relevant grouping type
986 // is 'seig'. Continue reading until 'seig' is found, or until running out of
988 while (reader
->HasChild(&sample_group_description
)) {
989 RCHECK(reader
->ReadChild(&sample_group_description
));
990 if (sample_group_description
.grouping_type
== FOURCC_SEIG
)
992 sample_group_description
.entries
.clear();
994 while (reader
->HasChild(&sample_to_group
)) {
995 RCHECK(reader
->ReadChild(&sample_to_group
));
996 if (sample_to_group
.grouping_type
== FOURCC_SEIG
)
998 sample_to_group
.entries
.clear();
1003 MovieFragment::MovieFragment() {}
1004 MovieFragment::~MovieFragment() {}
1005 FourCC
MovieFragment::BoxType() const { return FOURCC_MOOF
; }
1007 bool MovieFragment::Parse(BoxReader
* reader
) {
1008 RCHECK(reader
->ScanChildren() &&
1009 reader
->ReadChild(&header
) &&
1010 reader
->ReadChildren(&tracks
) &&
1011 reader
->MaybeReadChildren(&pssh
));
1015 IndependentAndDisposableSamples::IndependentAndDisposableSamples() {}
1016 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {}
1017 FourCC
IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP
; }
1019 bool IndependentAndDisposableSamples::Parse(BoxReader
* reader
) {
1020 RCHECK(reader
->ReadFullBoxHeader());
1021 RCHECK(reader
->version() == 0);
1022 RCHECK(reader
->flags() == 0);
1024 int sample_count
= reader
->size() - reader
->pos();
1025 sample_depends_on_
.resize(sample_count
);
1026 for (int i
= 0; i
< sample_count
; ++i
) {
1028 RCHECK(reader
->Read1(&sample_info
));
1030 sample_depends_on_
[i
] =
1031 static_cast<SampleDependsOn
>((sample_info
>> 4) & 0x3);
1033 RCHECK(sample_depends_on_
[i
] != kSampleDependsOnReserved
);
1039 SampleDependsOn
IndependentAndDisposableSamples::sample_depends_on(
1041 if (i
>= sample_depends_on_
.size())
1042 return kSampleDependsOnUnknown
;
1044 return sample_depends_on_
[i
];
1048 } // namespace media