5 #include "packager/media/formats/mp4/box_definitions.h"
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/formats/mp4/box_buffer.h"
12 #include "packager/media/formats/mp4/rcheck.h"
15 const uint32_t kFourCCSize = 4;
17 const uint32_t kBoxSize = kFourCCSize +
sizeof(uint32_t);
19 const uint32_t kFullBoxSize = kBoxSize + 4;
22 const uint32_t kCencKeyIdSize = 16;
25 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
27 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
30 const char kVideoHandlerName[] =
"VideoHandler";
31 const char kAudioHandlerName[] =
"SoundHandler";
34 const uint32_t kVideoResolution = 0x00480000;
35 const uint16_t kVideoFrameCount = 1;
36 const uint16_t kVideoDepth = 0x0018;
38 const uint32_t kCompressorNameSize = 32u;
41 bool IsFitIn32Bits(uint64_t a) {
42 return a <= std::numeric_limits<uint32_t>::max();
45 bool IsFitIn32Bits(int64_t a) {
46 return a <= std::numeric_limits<int32_t>::max() &&
47 a >= std::numeric_limits<int32_t>::min();
50 template <
typename T1,
typename T2>
51 bool IsFitIn32Bits(T1 a1, T2 a2) {
52 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
55 template <
typename T1,
typename T2,
typename T3>
56 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
57 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
62 namespace edash_packager {
66 FileType::FileType() : major_brand(FOURCC_NULL), minor_version(0) {}
67 FileType::~FileType() {}
68 FourCC FileType::BoxType()
const {
return FOURCC_FTYP; }
72 buffer->ReadWriteFourCC(&major_brand) &&
73 buffer->ReadWriteUInt32(&minor_version));
76 num_brands = (buffer->
Size() - buffer->
Pos()) /
sizeof(FourCC);
77 compatible_brands.resize(num_brands);
79 num_brands = compatible_brands.size();
81 for (
size_t i = 0; i < num_brands; ++i)
82 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
87 atom_size = kBoxSize + kFourCCSize +
sizeof(minor_version) +
88 kFourCCSize * compatible_brands.size();
92 SegmentType::SegmentType() {}
93 SegmentType::~SegmentType() {}
94 FourCC SegmentType::BoxType()
const {
return FOURCC_STYP; }
104 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
105 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
106 FourCC ProtectionSystemSpecificHeader::BoxType()
const {
return FOURCC_PSSH; }
109 if (!buffer->
Reading() && !raw_box.empty()) {
111 buffer->
writer()->AppendVector(raw_box);
115 uint32_t size = data.size();
117 buffer->ReadWriteVector(&system_id, 16) &&
118 buffer->ReadWriteUInt32(&size) &&
119 buffer->ReadWriteVector(&data, size));
124 DCHECK(raw_box.empty());
127 raw_box.assign(reader->data(), reader->data() + reader->size());
133 if (!raw_box.empty()) {
137 kFullBoxSize + system_id.size() +
sizeof(uint32_t) + data.size();
142 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
143 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
144 FourCC SampleAuxiliaryInformationOffset::BoxType()
const {
return FOURCC_SAIO; }
151 uint32_t count = offsets.size();
152 RCHECK(buffer->ReadWriteUInt32(&count));
153 offsets.resize(count);
155 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
156 for (uint32_t i = 0; i < count; ++i)
164 if (offsets.size() != 0) {
165 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
166 atom_size = kFullBoxSize +
sizeof(uint32_t) + num_bytes * offsets.size();
171 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
172 : default_sample_info_size(0), sample_count(0) {}
173 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
174 FourCC SampleAuxiliaryInformationSize::BoxType()
const {
return FOURCC_SAIZ; }
181 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
182 buffer->ReadWriteUInt32(&sample_count));
183 if (default_sample_info_size == 0)
184 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
191 if (sample_count != 0) {
192 atom_size = kFullBoxSize +
sizeof(default_sample_info_size) +
193 sizeof(sample_count) +
194 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
199 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
200 OriginalFormat::~OriginalFormat() {}
201 FourCC OriginalFormat::BoxType()
const {
return FOURCC_FRMA; }
204 return Box::ReadWrite(buffer) && buffer->ReadWriteFourCC(&format);
212 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
213 SchemeType::~SchemeType() {}
214 FourCC SchemeType::BoxType()
const {
return FOURCC_SCHM; }
218 buffer->ReadWriteFourCC(&type) &&
219 buffer->ReadWriteUInt32(&version));
224 atom_size = kFullBoxSize + kFourCCSize +
sizeof(version);
228 TrackEncryption::TrackEncryption()
229 : is_encrypted(false), default_iv_size(0), default_kid(16, 0) {}
230 TrackEncryption::~TrackEncryption() {}
231 FourCC TrackEncryption::BoxType()
const {
return FOURCC_TENC; }
235 if (default_kid.size() != kCencKeyIdSize) {
236 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
237 <<
" bytes; got " << default_kid.size()
238 <<
". Resized accordingly.";
239 default_kid.resize(kCencKeyIdSize);
243 uint8_t flag = is_encrypted ? 1 : 0;
246 buffer->ReadWriteUInt8(&flag) &&
247 buffer->ReadWriteUInt8(&default_iv_size) &&
248 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
250 is_encrypted = (flag != 0);
252 RCHECK(default_iv_size == 8 || default_iv_size == 16);
254 RCHECK(default_iv_size == 0);
261 atom_size = kFullBoxSize +
sizeof(uint32_t) + kCencKeyIdSize;
265 SchemeInfo::SchemeInfo() {}
266 SchemeInfo::~SchemeInfo() {}
267 FourCC SchemeInfo::BoxType()
const {
return FOURCC_SCHI; }
280 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
281 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
282 FourCC ProtectionSchemeInfo::BoxType()
const {
return FOURCC_SINF; }
289 if (type.type == FOURCC_CENC)
301 if (format.format != FOURCC_NULL) {
308 MovieHeader::MovieHeader()
310 modification_time(0),
316 MovieHeader::~MovieHeader() {}
317 FourCC MovieHeader::BoxType()
const {
return FOURCC_MVHD; }
322 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
325 buffer->ReadWriteUInt32(×cale) &&
328 std::vector<uint8_t> matrix(kUnityMatrix,
329 kUnityMatrix + arraysize(kUnityMatrix));
330 RCHECK(buffer->ReadWriteInt32(&rate) &&
331 buffer->ReadWriteInt16(&volume) &&
333 buffer->ReadWriteVector(&matrix, matrix.size()) &&
335 buffer->ReadWriteUInt32(&next_track_id));
340 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
341 atom_size = kFullBoxSize +
sizeof(uint32_t) * (1 + version) * 3 +
342 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
343 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
348 TrackHeader::TrackHeader()
350 modification_time(0),
358 flags = kTrackEnabled | kTrackInMovie;
360 TrackHeader::~TrackHeader() {}
361 FourCC TrackHeader::BoxType()
const {
return FOURCC_TKHD; }
366 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
369 buffer->ReadWriteUInt32(&track_id) &&
376 volume = (width != 0 && height != 0) ? 0 : 0x100;
378 std::vector<uint8_t> matrix(kUnityMatrix,
379 kUnityMatrix + arraysize(kUnityMatrix));
381 buffer->ReadWriteInt16(&layer) &&
382 buffer->ReadWriteInt16(&alternate_group) &&
383 buffer->ReadWriteInt16(&volume) &&
385 buffer->ReadWriteVector(&matrix, matrix.size()) &&
386 buffer->ReadWriteUInt32(&width) &&
387 buffer->ReadWriteUInt32(&height));
392 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
393 atom_size = kFullBoxSize +
sizeof(track_id) +
394 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
395 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
396 sizeof(height) +
sizeof(kUnityMatrix) + 14;
400 SampleDescription::SampleDescription() : type(kInvalid) {}
401 SampleDescription::~SampleDescription() {}
402 FourCC SampleDescription::BoxType()
const {
return FOURCC_STSD; }
407 count = video_entries.size();
409 count = audio_entries.size();
411 buffer->ReadWriteUInt32(&count));
416 video_entries.clear();
417 audio_entries.clear();
420 if (type == kVideo) {
422 RCHECK(video_entries.size() == count);
423 }
else if (type == kAudio) {
425 RCHECK(audio_entries.size() == count);
428 DCHECK_LT(0u, count);
429 if (type == kVideo) {
430 for (uint32_t i = 0; i < count; ++i)
431 RCHECK(video_entries[i].
ReadWrite(buffer));
432 }
else if (type == kAudio) {
433 for (uint32_t i = 0; i < count; ++i)
434 RCHECK(audio_entries[i].
ReadWrite(buffer));
443 atom_size = kFullBoxSize +
sizeof(uint32_t);
444 if (type == kVideo) {
445 for (uint32_t i = 0; i < video_entries.size(); ++i)
447 }
else if (type == kAudio) {
448 for (uint32_t i = 0; i < audio_entries.size(); ++i)
454 DecodingTimeToSample::DecodingTimeToSample() {}
455 DecodingTimeToSample::~DecodingTimeToSample() {}
456 FourCC DecodingTimeToSample::BoxType()
const {
return FOURCC_STTS; }
459 uint32_t count = decoding_time.size();
461 buffer->ReadWriteUInt32(&count));
463 decoding_time.resize(count);
464 for (uint32_t i = 0; i < count; ++i) {
465 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
466 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
472 atom_size = kFullBoxSize +
sizeof(uint32_t) +
477 CompositionTimeToSample::CompositionTimeToSample() {}
478 CompositionTimeToSample::~CompositionTimeToSample() {}
479 FourCC CompositionTimeToSample::BoxType()
const {
return FOURCC_CTTS; }
482 uint32_t count = composition_offset.size();
488 for (uint32_t i = 0; i < count; ++i) {
489 if (composition_offset[i].sample_offset < 0) {
497 buffer->ReadWriteUInt32(&count));
499 composition_offset.resize(count);
500 for (uint32_t i = 0; i < count; ++i) {
501 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
504 uint32_t sample_offset = composition_offset[i].sample_offset;
505 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
506 composition_offset[i].sample_offset = sample_offset;
508 int32_t sample_offset = composition_offset[i].sample_offset;
509 RCHECK(buffer->ReadWriteInt32(&sample_offset));
510 composition_offset[i].sample_offset = sample_offset;
519 if (!composition_offset.empty()) {
523 const uint32_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
524 atom_size = kFullBoxSize +
sizeof(uint32_t) +
525 kCompositionOffsetSize * composition_offset.size();
530 SampleToChunk::SampleToChunk() {}
531 SampleToChunk::~SampleToChunk() {}
532 FourCC SampleToChunk::BoxType()
const {
return FOURCC_STSC; }
535 uint32_t count = chunk_info.size();
537 buffer->ReadWriteUInt32(&count));
539 chunk_info.resize(count);
540 for (uint32_t i = 0; i < count; ++i) {
541 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
542 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
543 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
545 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
546 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
553 kFullBoxSize +
sizeof(uint32_t) +
sizeof(
ChunkInfo) * chunk_info.size();
557 SampleSize::SampleSize() : sample_size(0), sample_count(0) {}
558 SampleSize::~SampleSize() {}
559 FourCC SampleSize::BoxType()
const {
return FOURCC_STSZ; }
563 buffer->ReadWriteUInt32(&sample_size) &&
564 buffer->ReadWriteUInt32(&sample_count));
566 if (sample_size == 0) {
568 sizes.resize(sample_count);
570 DCHECK(sample_count == sizes.size());
571 for (uint32_t i = 0; i < sample_count; ++i)
572 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
578 atom_size = kFullBoxSize +
sizeof(sample_size) +
sizeof(sample_count) +
579 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
583 CompactSampleSize::CompactSampleSize() : field_size(0) {}
584 CompactSampleSize::~CompactSampleSize() {}
585 FourCC CompactSampleSize::BoxType()
const {
return FOURCC_STZ2; }
588 uint32_t sample_count = sizes.size();
591 buffer->ReadWriteUInt8(&field_size) &&
592 buffer->ReadWriteUInt32(&sample_count));
595 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
596 switch (field_size) {
598 for (uint32_t i = 0; i < sample_count; i += 2) {
601 RCHECK(buffer->ReadWriteUInt8(&size));
602 sizes[i] = size >> 4;
603 sizes[i + 1] = size & 0x0F;
605 DCHECK_LT(sizes[i], 16u);
606 DCHECK_LT(sizes[i + 1], 16u);
607 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
608 RCHECK(buffer->ReadWriteUInt8(&size));
613 for (uint32_t i = 0; i < sample_count; ++i) {
614 uint8_t size = sizes[i];
615 RCHECK(buffer->ReadWriteUInt8(&size));
620 for (uint32_t i = 0; i < sample_count; ++i) {
621 uint16_t size = sizes[i];
622 RCHECK(buffer->ReadWriteUInt16(&size));
629 sizes.resize(sample_count);
634 atom_size = kFullBoxSize +
sizeof(uint32_t) +
sizeof(uint32_t) +
635 (field_size * sizes.size() + 7) / 8;
639 ChunkOffset::ChunkOffset() {}
640 ChunkOffset::~ChunkOffset() {}
641 FourCC ChunkOffset::BoxType()
const {
return FOURCC_STCO; }
644 uint32_t count = offsets.size();
646 buffer->ReadWriteUInt32(&count));
648 offsets.resize(count);
649 for (uint32_t i = 0; i < count; ++i)
656 kFullBoxSize +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
660 ChunkLargeOffset::ChunkLargeOffset() {}
661 ChunkLargeOffset::~ChunkLargeOffset() {}
662 FourCC ChunkLargeOffset::BoxType()
const {
return FOURCC_CO64; }
665 uint32_t count = offsets.size();
669 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
671 stco.offsets.swap(offsets);
674 stco.offsets.swap(offsets);
680 buffer->ReadWriteUInt32(&count));
682 offsets.resize(count);
683 for (uint32_t i = 0; i < count; ++i)
684 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
689 uint32_t count = offsets.size();
690 int use_large_offset =
691 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
692 atom_size = kFullBoxSize +
sizeof(count) +
693 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
697 SyncSample::SyncSample() {}
698 SyncSample::~SyncSample() {}
699 FourCC SyncSample::BoxType()
const {
return FOURCC_STSS; }
702 uint32_t count = sample_number.size();
704 buffer->ReadWriteUInt32(&count));
706 sample_number.resize(count);
707 for (uint32_t i = 0; i < count; ++i)
708 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
715 if (!sample_number.empty()) {
716 atom_size = kFullBoxSize +
sizeof(uint32_t) +
717 sizeof(uint32_t) * sample_number.size();
722 SampleTable::SampleTable() {}
723 SampleTable::~SampleTable() {}
724 FourCC SampleTable::BoxType()
const {
return FOURCC_STBL; }
743 RCHECK(reader->
ReadChild(&compact_sample_size));
744 sample_size.sample_size = 0;
745 sample_size.sample_count = compact_sample_size.sizes.size();
746 sample_size.sizes.swap(compact_sample_size.sizes);
750 if (reader->
ChildExist(&chunk_large_offset)) {
751 RCHECK(reader->
ReadChild(&chunk_large_offset));
754 RCHECK(reader->
ReadChild(&chunk_offset));
755 chunk_large_offset.offsets.swap(chunk_offset.offsets);
774 EditList::EditList() {}
775 EditList::~EditList() {}
776 FourCC EditList::BoxType()
const {
return FOURCC_ELST; }
779 uint32_t count = edits.size();
783 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
784 for (uint32_t i = 0; i < count; ++i) {
787 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
788 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
789 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
801 for (uint32_t i = 0; i < edits.size(); ++i) {
802 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
807 atom_size = kFullBoxSize +
sizeof(uint32_t) +
808 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
815 FourCC Edit::BoxType()
const {
return FOURCC_EDTS; }
826 if (!list.edits.empty())
831 HandlerReference::HandlerReference() : type(kInvalid) {}
832 HandlerReference::~HandlerReference() {}
833 FourCC HandlerReference::BoxType()
const {
return FOURCC_HDLR; }
836 FourCC hdlr_type = FOURCC_NULL;
837 std::vector<uint8_t> handler_name;
839 if (type == kVideo) {
840 hdlr_type = FOURCC_VIDE;
841 handler_name.assign(kVideoHandlerName,
842 kVideoHandlerName + arraysize(kVideoHandlerName));
843 }
else if (type == kAudio) {
844 hdlr_type = FOURCC_SOUN;
845 handler_name.assign(kAudioHandlerName,
846 kAudioHandlerName + arraysize(kAudioHandlerName));
854 buffer->ReadWriteFourCC(&hdlr_type));
857 if (hdlr_type == FOURCC_VIDE) {
859 }
else if (hdlr_type == FOURCC_SOUN) {
866 buffer->ReadWriteVector(&handler_name, handler_name.size()));
873 kFullBoxSize + kFourCCSize + 16 +
874 (type == kVideo ?
sizeof(kVideoHandlerName) :
sizeof(kAudioHandlerName));
878 CodecConfigurationRecord::CodecConfigurationRecord() : box_type(FOURCC_NULL) {}
879 CodecConfigurationRecord::~CodecConfigurationRecord() {}
880 FourCC CodecConfigurationRecord::BoxType()
const {
889 RCHECK(buffer->ReadWriteVector(&data, buffer->
Size() - buffer->
Pos()));
891 RCHECK(buffer->ReadWriteVector(&data, data.size()));
903 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(0), v_spacing(0) {}
904 PixelAspectRatioBox::~PixelAspectRatioBox() {}
905 FourCC PixelAspectRatioBox::BoxType()
const {
return FOURCC_PASP; }
909 buffer->ReadWriteUInt32(&h_spacing) &&
910 buffer->ReadWriteUInt32(&v_spacing));
917 if (h_spacing != 0 || v_spacing != 0) {
919 DCHECK(h_spacing != 0 && v_spacing != 0);
920 atom_size = kBoxSize +
sizeof(h_spacing) +
sizeof(v_spacing);
925 VideoSampleEntry::VideoSampleEntry()
926 : format(FOURCC_NULL), data_reference_index(1), width(0), height(0) {}
928 VideoSampleEntry::~VideoSampleEntry() {}
929 FourCC VideoSampleEntry::BoxType()
const {
930 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
931 <<
"handler type recovered in its Media ancestor.";
938 format = buffer->
reader()->type();
940 RCHECK(buffer->ReadWriteUInt32(&
atom_size) &&
941 buffer->ReadWriteFourCC(&format));
944 uint32_t video_resolution = kVideoResolution;
945 uint16_t video_frame_count = kVideoFrameCount;
946 uint16_t video_depth = kVideoDepth;
947 int16_t predefined = -1;
949 buffer->ReadWriteUInt16(&data_reference_index) &&
951 buffer->ReadWriteUInt16(&width) &&
952 buffer->ReadWriteUInt16(&height) &&
953 buffer->ReadWriteUInt32(&video_resolution) &&
954 buffer->ReadWriteUInt32(&video_resolution) &&
956 buffer->ReadWriteUInt16(&video_frame_count) &&
958 buffer->ReadWriteUInt16(&video_depth) &&
959 buffer->ReadWriteInt16(&predefined));
963 if (format == FOURCC_ENCV) {
967 while (sinf.type.type != FOURCC_CENC) {
976 const FourCC actual_format = GetActualFormat();
977 switch (actual_format) {
979 codec_config_record.box_type = FOURCC_AVCC;
982 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
991 atom_size = kBoxSize +
sizeof(data_reference_index) +
sizeof(width) +
992 sizeof(height) +
sizeof(kVideoResolution) * 2 +
993 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
995 codec_config_record.
ComputeSize() + kCompressorNameSize +
1000 ElementaryStreamDescriptor::ElementaryStreamDescriptor() {}
1001 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
1002 FourCC ElementaryStreamDescriptor::BoxType()
const {
return FOURCC_ESDS; }
1007 std::vector<uint8_t> data;
1008 RCHECK(buffer->ReadWriteVector(&data, buffer->
Size() - buffer->
Pos()));
1009 RCHECK(es_descriptor.Parse(data));
1010 if (es_descriptor.
IsAAC()) {
1011 RCHECK(aac_audio_specific_config.
Parse(
1012 es_descriptor.decoder_specific_info()));
1015 DCHECK(buffer->
writer());
1016 es_descriptor.Write(buffer->
writer());
1024 if (es_descriptor.object_type() != kForbidden)
1025 atom_size = kFullBoxSize + es_descriptor.ComputeSize();
1029 AudioSampleEntry::AudioSampleEntry()
1030 : format(FOURCC_NULL),
1031 data_reference_index(1),
1036 AudioSampleEntry::~AudioSampleEntry() {}
1038 FourCC AudioSampleEntry::BoxType()
const {
1039 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
1040 <<
"handler type recovered in its Media ancestor.";
1046 DCHECK(buffer->
reader());
1047 format = buffer->
reader()->type();
1049 RCHECK(buffer->ReadWriteUInt32(&
atom_size) &&
1050 buffer->ReadWriteFourCC(&format));
1056 buffer->ReadWriteUInt16(&data_reference_index) &&
1058 buffer->ReadWriteUInt16(&channelcount) &&
1059 buffer->ReadWriteUInt16(&samplesize) &&
1061 buffer->ReadWriteUInt32(&samplerate));
1066 if (format == FOURCC_ENCA) {
1070 while (sinf.type.type != FOURCC_CENC) {
1085 atom_size = kBoxSize +
sizeof(data_reference_index) +
sizeof(channelcount) +
1086 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
1092 MediaHeader::MediaHeader()
1093 : creation_time(0), modification_time(0), timescale(0), duration(0) {
1096 MediaHeader::~MediaHeader() {}
1097 FourCC MediaHeader::BoxType()
const {
return FOURCC_MDHD; }
1102 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1105 buffer->ReadWriteUInt32(×cale) &&
1111 std::vector<uint8_t> temp;
1112 RCHECK(buffer->ReadWriteVector(&temp, 2));
1115 bit_reader.SkipBits(1);
1116 for (
int i = 0; i < 3; ++i) {
1117 CHECK(bit_reader.ReadBits(5, &language[i]));
1118 language[i] += 0x60;
1123 const char kUndefinedLanguage[] =
"und";
1124 if (language[0] == 0)
1125 strcpy(language, kUndefinedLanguage);
1129 for (
int i = 0; i < 3; ++i)
1130 lang |= (language[i] - 0x60) << ((2 - i) * 5);
1131 RCHECK(buffer->ReadWriteUInt16(&lang));
1139 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1140 atom_size = kFullBoxSize +
sizeof(timescale) +
1141 sizeof(uint32_t) * (1 + version) * 3 + 2 +
1146 VideoMediaHeader::VideoMediaHeader()
1147 : graphicsmode(0), opcolor_red(0), opcolor_green(0), opcolor_blue(0) {
1148 const uint32_t kVideoMediaHeaderFlags = 1;
1149 flags = kVideoMediaHeaderFlags;
1151 VideoMediaHeader::~VideoMediaHeader() {}
1152 FourCC VideoMediaHeader::BoxType()
const {
return FOURCC_VMHD; }
1155 buffer->ReadWriteUInt16(&graphicsmode) &&
1156 buffer->ReadWriteUInt16(&opcolor_red) &&
1157 buffer->ReadWriteUInt16(&opcolor_green) &&
1158 buffer->ReadWriteUInt16(&opcolor_blue));
1163 atom_size = kFullBoxSize +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
1164 sizeof(opcolor_green) +
sizeof(opcolor_blue);
1168 SoundMediaHeader::SoundMediaHeader() : balance(0) {}
1169 SoundMediaHeader::~SoundMediaHeader() {}
1170 FourCC SoundMediaHeader::BoxType()
const {
return FOURCC_SMHD; }
1173 buffer->ReadWriteUInt16(&balance) &&
1179 atom_size = kFullBoxSize +
sizeof(balance) +
sizeof(uint16_t);
1183 DataEntryUrl::DataEntryUrl() {
1184 const uint32_t kDataEntryUrlFlags = 1;
1185 flags = kDataEntryUrlFlags;
1187 DataEntryUrl::~DataEntryUrl() {}
1188 FourCC DataEntryUrl::BoxType()
const {
return FOURCC_URL; }
1192 RCHECK(buffer->ReadWriteVector(&location, buffer->
Size() - buffer->
Pos()));
1194 RCHECK(buffer->ReadWriteVector(&location, location.size()));
1200 atom_size = kBoxSize +
sizeof(flags) + location.size();
1204 DataReference::DataReference() {
1206 data_entry.resize(1);
1208 DataReference::~DataReference() {}
1209 FourCC DataReference::BoxType()
const {
return FOURCC_DREF; }
1211 uint32_t entry_count = data_entry.size();
1213 buffer->ReadWriteUInt32(&entry_count));
1214 data_entry.resize(entry_count);
1216 for (uint32_t i = 0; i < entry_count; ++i)
1222 uint32_t count = data_entry.size();
1223 atom_size = kFullBoxSize +
sizeof(count);
1224 for (uint32_t i = 0; i < count; ++i)
1229 DataInformation::DataInformation() {}
1230 DataInformation::~DataInformation() {}
1231 FourCC DataInformation::BoxType()
const {
return FOURCC_DINF; }
1244 MediaInformation::MediaInformation() {}
1245 MediaInformation::~MediaInformation() {}
1246 FourCC MediaInformation::BoxType()
const {
return FOURCC_MINF; }
1253 if (sample_table.description.type == kVideo)
1255 else if (sample_table.description.type == kAudio)
1265 if (sample_table.description.type == kVideo)
1267 else if (sample_table.description.type == kAudio)
1274 FourCC Media::BoxType()
const {
return FOURCC_MDIA; }
1288 information.sample_table.description.type = handler.type;
1290 DCHECK_EQ(information.sample_table.description.type, handler.type);
1304 FourCC Track::BoxType()
const {
return FOURCC_TRAK; }
1321 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
1322 MovieExtendsHeader::~MovieExtendsHeader() {}
1323 FourCC MovieExtendsHeader::BoxType()
const {
return FOURCC_MEHD; }
1327 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1335 if (fragment_duration != 0) {
1336 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
1337 atom_size = kFullBoxSize +
sizeof(uint32_t) * (1 + version);
1342 TrackExtends::TrackExtends()
1344 default_sample_description_index(0),
1345 default_sample_duration(0),
1346 default_sample_size(0),
1347 default_sample_flags(0) {}
1348 TrackExtends::~TrackExtends() {}
1349 FourCC TrackExtends::BoxType()
const {
return FOURCC_TREX; }
1353 buffer->ReadWriteUInt32(&track_id) &&
1354 buffer->ReadWriteUInt32(&default_sample_description_index) &&
1355 buffer->ReadWriteUInt32(&default_sample_duration) &&
1356 buffer->ReadWriteUInt32(&default_sample_size) &&
1357 buffer->ReadWriteUInt32(&default_sample_flags));
1362 atom_size = kFullBoxSize +
sizeof(track_id) +
1363 sizeof(default_sample_description_index) +
1364 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
1365 sizeof(default_sample_flags);
1369 MovieExtends::MovieExtends() {}
1370 MovieExtends::~MovieExtends() {}
1371 FourCC MovieExtends::BoxType()
const {
return FOURCC_MVEX; }
1378 DCHECK(buffer->
reader());
1381 for (uint32_t i = 0; i < tracks.size(); ++i)
1390 if (tracks.size() != 0) {
1392 for (uint32_t i = 0; i < tracks.size(); ++i)
1400 FourCC Movie::BoxType()
const {
return FOURCC_MOOV; }
1413 for (uint32_t i = 0; i < tracks.size(); ++i)
1415 for (uint32_t i = 0; i < pssh.size(); ++i)
1423 for (uint32_t i = 0; i < tracks.size(); ++i)
1425 for (uint32_t i = 0; i < pssh.size(); ++i)
1430 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
1431 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
1432 FourCC TrackFragmentDecodeTime::BoxType()
const {
return FOURCC_TFDT; }
1436 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1442 version = IsFitIn32Bits(decode_time) ? 0 : 1;
1443 atom_size = kFullBoxSize +
sizeof(uint32_t) * (1 + version);
1447 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
1448 MovieFragmentHeader::~MovieFragmentHeader() {}
1449 FourCC MovieFragmentHeader::BoxType()
const {
return FOURCC_MFHD; }
1453 buffer->ReadWriteUInt32(&sequence_number);
1457 atom_size = kFullBoxSize +
sizeof(sequence_number);
1461 TrackFragmentHeader::TrackFragmentHeader()
1463 sample_description_index(0),
1464 default_sample_duration(0),
1465 default_sample_size(0),
1466 default_sample_flags(0) {}
1468 TrackFragmentHeader::~TrackFragmentHeader() {}
1469 FourCC TrackFragmentHeader::BoxType()
const {
return FOURCC_TFHD; }
1473 buffer->ReadWriteUInt32(&track_id));
1475 if (flags & kBaseDataOffsetPresentMask) {
1480 uint64_t base_data_offset;
1481 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
1482 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
1483 "default-base-is-moof.";
1486 if (flags & kSampleDescriptionIndexPresentMask) {
1487 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
1488 }
else if (buffer->
Reading()) {
1489 sample_description_index = 0;
1492 if (flags & kDefaultSampleDurationPresentMask) {
1493 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
1494 }
else if (buffer->
Reading()) {
1495 default_sample_duration = 0;
1498 if (flags & kDefaultSampleSizePresentMask) {
1499 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
1500 }
else if (buffer->
Reading()) {
1501 default_sample_size = 0;
1504 if (flags & kDefaultSampleFlagsPresentMask)
1505 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
1510 atom_size = kFullBoxSize +
sizeof(track_id);
1511 if (flags & kSampleDescriptionIndexPresentMask)
1512 atom_size +=
sizeof(sample_description_index);
1513 if (flags & kDefaultSampleDurationPresentMask)
1514 atom_size +=
sizeof(default_sample_duration);
1515 if (flags & kDefaultSampleSizePresentMask)
1516 atom_size +=
sizeof(default_sample_size);
1517 if (flags & kDefaultSampleFlagsPresentMask)
1518 atom_size +=
sizeof(default_sample_flags);
1522 TrackFragmentRun::TrackFragmentRun() : sample_count(0), data_offset(0) {}
1523 TrackFragmentRun::~TrackFragmentRun() {}
1524 FourCC TrackFragmentRun::BoxType()
const {
return FOURCC_TRUN; }
1532 if (flags & kSampleCompTimeOffsetsPresentMask) {
1533 for (uint32_t i = 0; i < sample_count; ++i) {
1534 if (sample_composition_time_offsets[i] < 0) {
1543 buffer->ReadWriteUInt32(&sample_count));
1545 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
1546 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
1547 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
1548 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
1549 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
1550 bool sample_composition_time_offsets_present =
1551 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
1553 if (data_offset_present) {
1554 RCHECK(buffer->ReadWriteUInt32(&data_offset));
1565 uint32_t first_sample_flags;
1568 if (first_sample_flags_present)
1569 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
1571 if (sample_duration_present)
1572 sample_durations.resize(sample_count);
1573 if (sample_size_present)
1574 sample_sizes.resize(sample_count);
1575 if (sample_flags_present)
1576 sample_flags.resize(sample_count);
1577 if (sample_composition_time_offsets_present)
1578 sample_composition_time_offsets.resize(sample_count);
1580 if (first_sample_flags_present) {
1581 first_sample_flags = sample_flags[0];
1582 DCHECK(sample_flags.size() == 1);
1583 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
1586 if (sample_duration_present)
1587 DCHECK(sample_durations.size() == sample_count);
1588 if (sample_size_present)
1589 DCHECK(sample_sizes.size() == sample_count);
1590 if (sample_flags_present)
1591 DCHECK(sample_flags.size() == sample_count);
1592 if (sample_composition_time_offsets_present)
1593 DCHECK(sample_composition_time_offsets.size() == sample_count);
1596 for (uint32_t i = 0; i < sample_count; ++i) {
1597 if (sample_duration_present)
1598 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
1599 if (sample_size_present)
1600 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
1601 if (sample_flags_present)
1602 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
1604 if (sample_composition_time_offsets_present) {
1606 uint32_t sample_offset = sample_composition_time_offsets[i];
1607 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
1608 sample_composition_time_offsets[i] = sample_offset;
1610 int32_t sample_offset = sample_composition_time_offsets[i];
1611 RCHECK(buffer->ReadWriteInt32(&sample_offset));
1612 sample_composition_time_offsets[i] = sample_offset;
1618 if (first_sample_flags_present) {
1619 if (sample_flags.size() == 0) {
1620 sample_flags.push_back(first_sample_flags);
1622 sample_flags[0] = first_sample_flags;
1630 atom_size = kFullBoxSize +
sizeof(sample_count);
1631 if (flags & kDataOffsetPresentMask)
1633 if (flags & kFirstSampleFlagsPresentMask)
1635 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
1636 (flags & kSampleSizePresentMask ? 1 : 0) +
1637 (flags & kSampleFlagsPresentMask ? 1 : 0) +
1638 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
1639 atom_size += fields *
sizeof(uint32_t) * sample_count;
1643 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
1644 SampleToGroup::~SampleToGroup() {}
1645 FourCC SampleToGroup::BoxType()
const {
return FOURCC_SBGP; }
1649 buffer->ReadWriteUInt32(&grouping_type));
1651 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1653 if (grouping_type != FOURCC_SEIG) {
1655 DLOG(WARNING) <<
"Sample group '" << grouping_type <<
"' is not supported.";
1659 uint32_t count = entries.size();
1660 RCHECK(buffer->ReadWriteUInt32(&count));
1661 entries.resize(count);
1662 for (uint32_t i = 0; i < count; ++i) {
1663 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1664 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1672 if (!entries.empty()) {
1673 atom_size = kFullBoxSize +
sizeof(grouping_type) +
1674 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1675 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1680 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1681 : is_encrypted(false), iv_size(0) {
1683 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {};
1685 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
1686 SampleGroupDescription::~SampleGroupDescription() {}
1687 FourCC SampleGroupDescription::BoxType()
const {
return FOURCC_SGPD; }
1691 buffer->ReadWriteUInt32(&grouping_type));
1693 if (grouping_type != FOURCC_SEIG) {
1695 DLOG(WARNING) <<
"Sample group '" << grouping_type <<
"' is not supported.";
1699 const size_t kEntrySize =
sizeof(uint32_t) + kCencKeyIdSize;
1700 uint32_t default_length = 0;
1703 RCHECK(buffer->ReadWriteUInt32(&default_length));
1704 RCHECK(default_length == 0 || default_length >= kEntrySize);
1706 default_length = kEntrySize;
1707 RCHECK(buffer->ReadWriteUInt32(&default_length));
1711 uint32_t count = entries.size();
1712 RCHECK(buffer->ReadWriteUInt32(&count));
1713 entries.resize(count);
1714 for (uint32_t i = 0; i < count; ++i) {
1716 if (buffer->
Reading() && default_length == 0) {
1717 uint32_t description_length = 0;
1718 RCHECK(buffer->ReadWriteUInt32(&description_length));
1719 RCHECK(description_length >= kEntrySize);
1724 if (entries[i].key_id.size() != kCencKeyIdSize) {
1725 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
1726 <<
" bytes; got " << entries[i].key_id.size()
1727 <<
". Resized accordingly.";
1728 entries[i].key_id.resize(kCencKeyIdSize);
1732 uint8_t flag = entries[i].is_encrypted ? 1 : 0;
1734 buffer->ReadWriteUInt8(&flag) &&
1735 buffer->ReadWriteUInt8(&entries[i].iv_size) &&
1736 buffer->ReadWriteVector(&entries[i].key_id, kCencKeyIdSize));
1739 entries[i].is_encrypted = (flag != 0);
1740 if (entries[i].is_encrypted) {
1741 RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
1743 RCHECK(entries[i].iv_size == 0);
1755 if (!entries.empty()) {
1756 const size_t kEntrySize =
sizeof(uint32_t) + kCencKeyIdSize;
1757 atom_size = kFullBoxSize +
sizeof(grouping_type) +
1758 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1759 entries.size() * kEntrySize;
1764 TrackFragment::TrackFragment() : decode_time_absent(false) {}
1765 TrackFragment::~TrackFragment() {}
1766 FourCC TrackFragment::BoxType()
const {
return FOURCC_TRAF; }
1773 DCHECK(buffer->
reader());
1775 if (!decode_time_absent)
1783 while (sample_to_group.grouping_type != FOURCC_SEIG &&
1787 while (sample_group_description.grouping_type != FOURCC_SEIG &&
1792 if (!decode_time_absent)
1794 for (uint32_t i = 0; i < runs.size(); ++i)
1808 for (uint32_t i = 0; i < runs.size(); ++i)
1813 MovieFragment::MovieFragment() {}
1814 MovieFragment::~MovieFragment() {}
1815 FourCC MovieFragment::BoxType()
const {
return FOURCC_MOOF; }
1827 for (uint32_t i = 0; i < tracks.size(); ++i)
1829 for (uint32_t i = 0; i < pssh.size(); ++i)
1837 for (uint32_t i = 0; i < tracks.size(); ++i)
1839 for (uint32_t i = 0; i < pssh.size(); ++i)
1844 SegmentIndex::SegmentIndex()
1847 earliest_presentation_time(0),
1849 SegmentIndex::~SegmentIndex() {}
1850 FourCC SegmentIndex::BoxType()
const {
return FOURCC_SIDX; }
1854 buffer->ReadWriteUInt32(&reference_id) &&
1855 buffer->ReadWriteUInt32(×cale));
1857 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1862 uint16_t reference_count = references.size();
1864 buffer->ReadWriteUInt16(&reference_count));
1865 references.resize(reference_count);
1867 uint32_t reference_type_size;
1869 for (uint32_t i = 0; i < reference_count; ++i) {
1871 reference_type_size = references[i].referenced_size;
1872 if (references[i].reference_type)
1873 reference_type_size |= (1 << 31);
1874 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
1875 if (references[i].starts_with_sap)
1878 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
1879 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
1880 buffer->ReadWriteUInt32(&sap));
1882 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
1883 references[i].referenced_size = reference_type_size & ~(1 << 31);
1884 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
1885 references[i].sap_type =
1886 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
1887 references[i].sap_delta_time = sap & ~(0xF << 28);
1894 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
1895 atom_size = kFullBoxSize +
sizeof(reference_id) +
sizeof(timescale) +
1896 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
1897 3 *
sizeof(uint32_t) * references.size();
1901 MediaData::MediaData() : data_size(0) {}
1902 MediaData::~MediaData() {}
1903 FourCC MediaData::BoxType()
const {
return FOURCC_MDAT; }
1905 void MediaData::Write(BufferWriter* buffer) {
1906 buffer->AppendInt(ComputeSize());
1907 buffer->AppendInt(static_cast<uint32_t>(BoxType()));
1910 uint32_t MediaData::ComputeSize() {
1911 return kBoxSize + data_size;
bool ReadWrite(BoxBuffer *buffer) override
Read/write the mp4 box from/to BoxBuffer.
bool ReadWrite(BoxBuffer *buffer) override
Read/write the mp4 box from/to BoxBuffer.
uint32_t ComputeSize() override
uint32_t ComputeSize() override
uint32_t ComputeSize() override
bool ReadWrite(BoxBuffer *buffer) override
Read/write the mp4 box from/to BoxBuffer.