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/base/macros.h"
12 #include "packager/media/base/rcheck.h"
13 #include "packager/media/formats/mp4/box_buffer.h"
16 const uint32_t kFourCCSize = 4;
19 const uint32_t kCencKeyIdSize = 16;
22 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
27 const char kVideoHandlerName[] =
"VideoHandler";
28 const char kAudioHandlerName[] =
"SoundHandler";
29 const char kTextHandlerName[] =
"TextHandler";
32 const uint32_t kVideoResolution = 0x00480000;
33 const uint16_t kVideoFrameCount = 1;
34 const uint16_t kVideoDepth = 0x0018;
36 const uint32_t kCompressorNameSize = 32u;
37 const char kAvcCompressorName[] =
"\012AVC Coding";
38 const char kHevcCompressorName[] =
"\013HEVC Coding";
39 const char kVpcCompressorName[] =
"\012VPC Coding";
43 const int kCueSourceIdNotSet = -1;
45 const size_t kInvalidIvSize = 1;
49 bool IsIvSizeValid(
size_t per_sample_iv_size) {
50 return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
51 per_sample_iv_size == 16;
68 const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
71 const uint32_t kID3v2HeaderSize = 10;
72 const char kID3v2Identifier[] =
"ID3";
73 const uint16_t kID3v2Version = 0x0400;
76 bool IsFitIn32Bits(uint64_t a) {
77 return a <= std::numeric_limits<uint32_t>::max();
80 bool IsFitIn32Bits(int64_t a) {
81 return a <= std::numeric_limits<int32_t>::max() &&
82 a >= std::numeric_limits<int32_t>::min();
85 template <
typename T1,
typename T2>
86 bool IsFitIn32Bits(T1 a1, T2 a2) {
87 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
90 template <
typename T1,
typename T2,
typename T3>
91 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
92 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
103 TrackType FourCCToTrackType(FourCC fourcc) {
116 FourCC TrackTypeToFourCC(TrackType track_type) {
117 switch (track_type) {
129 bool IsProtectionSchemeSupported(FourCC scheme) {
130 return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
131 scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
136 FileType::FileType() : major_brand(FOURCC_NULL), minor_version(0) {}
137 FileType::~FileType() {}
140 bool FileType::ReadWriteInternal(
BoxBuffer* buffer) {
142 buffer->ReadWriteFourCC(&major_brand) &&
143 buffer->ReadWriteUInt32(&minor_version));
146 RCHECK(buffer->
BytesLeft() %
sizeof(FourCC) == 0);
147 num_brands = buffer->
BytesLeft() /
sizeof(FourCC);
148 compatible_brands.resize(num_brands);
150 num_brands = compatible_brands.size();
152 for (
size_t i = 0; i < num_brands; ++i)
153 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
157 uint32_t FileType::ComputeSizeInternal() {
158 return HeaderSize() + kFourCCSize +
sizeof(minor_version) +
159 kFourCCSize * compatible_brands.size();
164 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
165 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
168 bool ProtectionSystemSpecificHeader::ReadWriteInternal(
BoxBuffer* buffer) {
172 raw_box.assign(reader->data(), reader->data() + reader->size());
174 DCHECK(!raw_box.empty());
175 buffer->
writer()->AppendVector(raw_box);
181 uint32_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
182 return raw_box.size();
185 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
186 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
189 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
194 uint32_t count = offsets.size();
195 RCHECK(buffer->ReadWriteUInt32(&count));
196 offsets.resize(count);
198 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
199 for (uint32_t i = 0; i < count; ++i)
204 uint32_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
206 if (offsets.size() == 0)
208 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
209 return HeaderSize() +
sizeof(uint32_t) + num_bytes * offsets.size();
212 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
213 : default_sample_info_size(0), sample_count(0) {}
214 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
217 bool SampleAuxiliaryInformationSize::ReadWriteInternal(
BoxBuffer* buffer) {
222 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
223 buffer->ReadWriteUInt32(&sample_count));
224 if (default_sample_info_size == 0)
225 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
229 uint32_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
231 if (sample_count == 0)
233 return HeaderSize() +
sizeof(default_sample_info_size) +
234 sizeof(sample_count) +
235 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
238 SampleEncryptionEntry::SampleEncryptionEntry() {}
239 SampleEncryptionEntry::~SampleEncryptionEntry() {}
244 DCHECK(IsIvSizeValid(iv_size));
247 RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
249 if (!has_subsamples) {
254 uint16_t subsample_count = subsamples.size();
255 RCHECK(buffer->ReadWriteUInt16(&subsample_count));
256 RCHECK(subsample_count > 0);
257 subsamples.resize(subsample_count);
258 for (
auto& subsample : subsamples) {
259 RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
260 buffer->ReadWriteUInt32(&subsample.cipher_bytes));
268 DCHECK(IsIvSizeValid(iv_size));
271 initialization_vector.resize(iv_size);
272 RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
274 if (!has_subsamples) {
279 uint16_t subsample_count;
280 RCHECK(reader->Read2(&subsample_count));
281 RCHECK(subsample_count > 0);
282 subsamples.resize(subsample_count);
283 for (
auto& subsample : subsamples) {
284 RCHECK(reader->Read2(&subsample.clear_bytes) &&
285 reader->Read4(&subsample.cipher_bytes));
291 const uint32_t subsample_entry_size =
sizeof(uint16_t) +
sizeof(uint32_t);
292 const uint16_t subsample_count = subsamples.size();
293 return initialization_vector.size() +
294 (subsample_count > 0 ? (
sizeof(subsample_count) +
295 subsample_entry_size * subsample_count)
301 for (uint32_t i = 0; i < subsamples.size(); ++i)
302 size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
306 SampleEncryption::SampleEncryption() : iv_size(kInvalidIvSize) {}
307 SampleEncryption::~SampleEncryption() {}
310 bool SampleEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
315 if (buffer->
Reading() && iv_size == kInvalidIvSize) {
321 if (!IsIvSizeValid(iv_size)) {
323 <<
"IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
328 uint32_t sample_count = sample_encryption_entries.size();
329 RCHECK(buffer->ReadWriteUInt32(&sample_count));
331 sample_encryption_entries.resize(sample_count);
332 for (
auto& sample_encryption_entry : sample_encryption_entries) {
333 RCHECK(sample_encryption_entry.ReadWrite(
334 iv_size, flags & kUseSubsampleEncryption, buffer));
339 uint32_t SampleEncryption::ComputeSizeInternal() {
340 const uint32_t sample_count = sample_encryption_entries.size();
341 if (sample_count == 0) {
346 DCHECK(IsIvSizeValid(iv_size));
348 if (flags & kUseSubsampleEncryption) {
349 for (
const SampleEncryptionEntry& sample_encryption_entry :
350 sample_encryption_entries) {
351 box_size += sample_encryption_entry.ComputeSize();
354 box_size += sample_count * iv_size;
361 std::vector<SampleEncryptionEntry>* sample_encryption_entries)
const {
362 DCHECK(IsIvSizeValid(iv_size));
366 uint32_t sample_count = 0;
367 RCHECK(reader.Read4(&sample_count));
369 sample_encryption_entries->resize(sample_count);
370 for (
auto& sample_encryption_entry : *sample_encryption_entries) {
371 RCHECK(sample_encryption_entry.ParseFromBuffer(
372 iv_size, flags & kUseSubsampleEncryption, &reader));
377 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
378 OriginalFormat::~OriginalFormat() {}
381 bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
385 uint32_t OriginalFormat::ComputeSizeInternal() {
389 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
390 SchemeType::~SchemeType() {}
393 bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
395 buffer->ReadWriteFourCC(&type) &&
396 buffer->ReadWriteUInt32(&version));
400 uint32_t SchemeType::ComputeSizeInternal() {
401 return HeaderSize() + kFourCCSize +
sizeof(version);
404 TrackEncryption::TrackEncryption()
405 : default_is_protected(0),
406 default_per_sample_iv_size(0),
408 default_crypt_byte_block(0),
409 default_skip_byte_block(0) {}
410 TrackEncryption::~TrackEncryption() {}
413 bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
415 if (default_kid.size() != kCencKeyIdSize) {
416 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
417 <<
" bytes; got " << default_kid.size()
418 <<
". Resized accordingly.";
419 default_kid.resize(kCencKeyIdSize);
421 RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
422 if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
431 uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
432 RCHECK(buffer->ReadWriteUInt8(&pattern));
433 default_crypt_byte_block = pattern >> 4;
434 default_skip_byte_block = pattern & 0x0F;
436 RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
437 buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
438 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
440 if (default_is_protected == 1) {
441 if (default_per_sample_iv_size == 0) {
442 uint8_t default_constant_iv_size = default_constant_iv.size();
443 RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
444 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
445 RCHECK(buffer->ReadWriteVector(&default_constant_iv,
446 default_constant_iv_size));
448 RCHECK(default_per_sample_iv_size == 8 ||
449 default_per_sample_iv_size == 16);
450 RCHECK(default_constant_iv.empty());
455 RCHECK(default_is_protected == 0);
456 RCHECK(default_per_sample_iv_size == 0);
457 RCHECK(default_constant_iv.empty());
462 uint32_t TrackEncryption::ComputeSizeInternal() {
463 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize +
464 (default_constant_iv.empty() ? 0 : (
sizeof(uint8_t) +
465 default_constant_iv.size()));
468 SchemeInfo::SchemeInfo() {}
469 SchemeInfo::~SchemeInfo() {}
472 bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
478 uint32_t SchemeInfo::ComputeSizeInternal() {
482 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
483 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
486 bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
491 if (IsProtectionSchemeSupported(type.type)) {
494 DLOG(WARNING) <<
"Ignore unsupported protection scheme: "
495 << FourCCToString(type.type);
504 uint32_t ProtectionSchemeInfo::ComputeSizeInternal() {
506 if (format.format == FOURCC_NULL)
512 MovieHeader::MovieHeader()
514 modification_time(0),
520 MovieHeader::~MovieHeader() {}
523 bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
526 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
529 buffer->ReadWriteUInt32(×cale) &&
532 std::vector<uint8_t> matrix(kUnityMatrix,
533 kUnityMatrix + arraysize(kUnityMatrix));
534 RCHECK(buffer->ReadWriteInt32(&rate) &&
535 buffer->ReadWriteInt16(&volume) &&
537 buffer->ReadWriteVector(&matrix, matrix.size()) &&
539 buffer->ReadWriteUInt32(&next_track_id));
543 uint32_t MovieHeader::ComputeSizeInternal() {
544 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
545 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
546 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
547 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
551 TrackHeader::TrackHeader()
553 modification_time(0),
561 flags = kTrackEnabled | kTrackInMovie;
563 TrackHeader::~TrackHeader() {}
566 bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
569 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
572 buffer->ReadWriteUInt32(&track_id) &&
579 volume = (width != 0 && height != 0) ? 0 : 0x100;
581 std::vector<uint8_t> matrix(kUnityMatrix,
582 kUnityMatrix + arraysize(kUnityMatrix));
584 buffer->ReadWriteInt16(&layer) &&
585 buffer->ReadWriteInt16(&alternate_group) &&
586 buffer->ReadWriteInt16(&volume) &&
588 buffer->ReadWriteVector(&matrix, matrix.size()) &&
589 buffer->ReadWriteUInt32(&width) &&
590 buffer->ReadWriteUInt32(&height));
594 uint32_t TrackHeader::ComputeSizeInternal() {
595 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
597 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
598 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
599 sizeof(height) +
sizeof(kUnityMatrix) + 14;
602 SampleDescription::SampleDescription() : type(kInvalid) {}
603 SampleDescription::~SampleDescription() {}
606 bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
610 count = video_entries.size();
613 count = audio_entries.size();
616 count = text_entries.size();
619 NOTIMPLEMENTED() <<
"SampleDecryption type " << type
620 <<
" is not handled. Skipping.";
623 buffer->ReadWriteUInt32(&count));
626 BoxReader* reader = buffer->
reader();
628 video_entries.clear();
629 audio_entries.clear();
632 if (type == kVideo) {
633 RCHECK(reader->ReadAllChildren(&video_entries));
634 RCHECK(video_entries.size() == count);
635 }
else if (type == kAudio) {
636 RCHECK(reader->ReadAllChildren(&audio_entries));
637 RCHECK(audio_entries.size() == count);
638 }
else if (type == kText) {
639 RCHECK(reader->ReadAllChildren(&text_entries));
640 RCHECK(text_entries.size() == count);
643 DCHECK_LT(0u, count);
644 if (type == kVideo) {
645 for (uint32_t i = 0; i < count; ++i)
647 }
else if (type == kAudio) {
648 for (uint32_t i = 0; i < count; ++i)
650 }
else if (type == kText) {
651 for (uint32_t i = 0; i < count; ++i)
660 uint32_t SampleDescription::ComputeSizeInternal() {
661 uint32_t box_size =
HeaderSize() +
sizeof(uint32_t);
662 if (type == kVideo) {
663 for (uint32_t i = 0; i < video_entries.size(); ++i)
665 }
else if (type == kAudio) {
666 for (uint32_t i = 0; i < audio_entries.size(); ++i)
668 }
else if (type == kText) {
669 for (uint32_t i = 0; i < text_entries.size(); ++i)
675 DecodingTimeToSample::DecodingTimeToSample() {}
676 DecodingTimeToSample::~DecodingTimeToSample() {}
679 bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
680 uint32_t count = decoding_time.size();
682 buffer->ReadWriteUInt32(&count));
684 decoding_time.resize(count);
685 for (uint32_t i = 0; i < count; ++i) {
686 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
687 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
692 uint32_t DecodingTimeToSample::ComputeSizeInternal() {
694 sizeof(DecodingTime) * decoding_time.size();
697 CompositionTimeToSample::CompositionTimeToSample() {}
698 CompositionTimeToSample::~CompositionTimeToSample() {}
701 bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
702 uint32_t count = composition_offset.size();
708 for (uint32_t i = 0; i < count; ++i) {
709 if (composition_offset[i].sample_offset < 0) {
717 buffer->ReadWriteUInt32(&count));
719 composition_offset.resize(count);
720 for (uint32_t i = 0; i < count; ++i) {
721 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
724 uint32_t sample_offset = composition_offset[i].sample_offset;
725 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
726 composition_offset[i].sample_offset = sample_offset;
728 int32_t sample_offset = composition_offset[i].sample_offset;
729 RCHECK(buffer->ReadWriteInt32(&sample_offset));
730 composition_offset[i].sample_offset = sample_offset;
736 uint32_t CompositionTimeToSample::ComputeSizeInternal() {
738 if (composition_offset.empty())
743 const uint32_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
745 kCompositionOffsetSize * composition_offset.size();
748 SampleToChunk::SampleToChunk() {}
749 SampleToChunk::~SampleToChunk() {}
752 bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
753 uint32_t count = chunk_info.size();
755 buffer->ReadWriteUInt32(&count));
757 chunk_info.resize(count);
758 for (uint32_t i = 0; i < count; ++i) {
759 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
760 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
761 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
763 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
764 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
769 uint32_t SampleToChunk::ComputeSizeInternal() {
771 sizeof(ChunkInfo) * chunk_info.size();
774 SampleSize::SampleSize() : sample_size(0), sample_count(0) {}
775 SampleSize::~SampleSize() {}
778 bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
780 buffer->ReadWriteUInt32(&sample_size) &&
781 buffer->ReadWriteUInt32(&sample_count));
783 if (sample_size == 0) {
785 sizes.resize(sample_count);
787 DCHECK(sample_count == sizes.size());
788 for (uint32_t i = 0; i < sample_count; ++i)
789 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
794 uint32_t SampleSize::ComputeSizeInternal() {
795 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
796 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
799 CompactSampleSize::CompactSampleSize() : field_size(0) {}
800 CompactSampleSize::~CompactSampleSize() {}
803 bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
804 uint32_t sample_count = sizes.size();
807 buffer->ReadWriteUInt8(&field_size) &&
808 buffer->ReadWriteUInt32(&sample_count));
811 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
812 switch (field_size) {
814 for (uint32_t i = 0; i < sample_count; i += 2) {
817 RCHECK(buffer->ReadWriteUInt8(&size));
818 sizes[i] = size >> 4;
819 sizes[i + 1] = size & 0x0F;
821 DCHECK_LT(sizes[i], 16u);
822 DCHECK_LT(sizes[i + 1], 16u);
823 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
824 RCHECK(buffer->ReadWriteUInt8(&size));
829 for (uint32_t i = 0; i < sample_count; ++i) {
830 uint8_t size = sizes[i];
831 RCHECK(buffer->ReadWriteUInt8(&size));
836 for (uint32_t i = 0; i < sample_count; ++i) {
837 uint16_t size = sizes[i];
838 RCHECK(buffer->ReadWriteUInt16(&size));
845 sizes.resize(sample_count);
849 uint32_t CompactSampleSize::ComputeSizeInternal() {
850 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
851 (field_size * sizes.size() + 7) / 8;
854 ChunkOffset::ChunkOffset() {}
855 ChunkOffset::~ChunkOffset() {}
858 bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
859 uint32_t count = offsets.size();
861 buffer->ReadWriteUInt32(&count));
863 offsets.resize(count);
864 for (uint32_t i = 0; i < count; ++i)
869 uint32_t ChunkOffset::ComputeSizeInternal() {
870 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
873 ChunkLargeOffset::ChunkLargeOffset() {}
874 ChunkLargeOffset::~ChunkLargeOffset() {}
877 bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
878 uint32_t count = offsets.size();
882 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
884 stco.offsets.swap(offsets);
887 stco.offsets.swap(offsets);
893 buffer->ReadWriteUInt32(&count));
895 offsets.resize(count);
896 for (uint32_t i = 0; i < count; ++i)
897 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
901 uint32_t ChunkLargeOffset::ComputeSizeInternal() {
902 uint32_t count = offsets.size();
903 int use_large_offset =
904 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
906 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
909 SyncSample::SyncSample() {}
910 SyncSample::~SyncSample() {}
913 bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
914 uint32_t count = sample_number.size();
916 buffer->ReadWriteUInt32(&count));
918 sample_number.resize(count);
919 for (uint32_t i = 0; i < count; ++i)
920 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
924 uint32_t SyncSample::ComputeSizeInternal() {
926 if (sample_number.empty())
929 sizeof(uint32_t) * sample_number.size();
932 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
934 per_sample_iv_size(0),
936 skip_byte_block(0) {}
937 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {};
939 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
940 if (!buffer->Reading()) {
941 if (key_id.size() != kCencKeyIdSize) {
942 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
943 <<
" bytes; got " << key_id.size()
944 <<
". Resized accordingly.";
945 key_id.resize(kCencKeyIdSize);
947 RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
950 RCHECK(buffer->IgnoreBytes(1));
952 uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
953 RCHECK(buffer->ReadWriteUInt8(&pattern));
954 crypt_byte_block = pattern >> 4;
955 skip_byte_block = pattern & 0x0F;
957 RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
958 buffer->ReadWriteUInt8(&per_sample_iv_size) &&
959 buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
961 if (is_protected == 1) {
962 if (per_sample_iv_size == 0) {
963 uint8_t constant_iv_size = constant_iv.size();
964 RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
965 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
966 RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
968 RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
969 DCHECK(constant_iv.empty());
974 RCHECK(is_protected == 0);
975 RCHECK(per_sample_iv_size == 0);
980 uint32_t CencSampleEncryptionInfoEntry::ComputeSize()
const {
981 return sizeof(uint32_t) + kCencKeyIdSize +
982 (constant_iv.empty() ? 0 : (
sizeof(uint8_t) + constant_iv.size()));
985 AudioRollRecoveryEntry::AudioRollRecoveryEntry(): roll_distance(0) {}
986 AudioRollRecoveryEntry::~AudioRollRecoveryEntry() {}
988 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
989 RCHECK(buffer->ReadWriteInt16(&roll_distance));
993 uint32_t AudioRollRecoveryEntry::ComputeSize()
const {
994 return sizeof(roll_distance);
997 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
998 SampleGroupDescription::~SampleGroupDescription() {}
1001 bool SampleGroupDescription::ReadWriteInternal(
BoxBuffer* buffer) {
1003 buffer->ReadWriteUInt32(&grouping_type));
1005 switch (grouping_type) {
1007 return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
1009 return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
1012 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1013 << FourCCToString(static_cast<FourCC>(grouping_type));
1018 template <
typename T>
1019 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
1020 std::vector<T>* entries) {
1021 uint32_t default_length = 0;
1022 if (!buffer->Reading()) {
1023 DCHECK(!entries->empty());
1024 default_length = (*entries)[0].ComputeSize();
1025 DCHECK_NE(default_length, 0u);
1028 RCHECK(buffer->ReadWriteUInt32(&default_length));
1030 NOTIMPLEMENTED() <<
"Unsupported SampleGroupDescriptionBox 'sgpd' version "
1031 <<
static_cast<int>(version);
1035 uint32_t count = entries->size();
1036 RCHECK(buffer->ReadWriteUInt32(&count));
1038 entries->resize(count);
1040 for (T& entry : *entries) {
1042 uint32_t description_length = default_length;
1043 if (buffer->Reading() && default_length == 0)
1044 RCHECK(buffer->ReadWriteUInt32(&description_length));
1045 RCHECK(entry.ReadWrite(buffer));
1046 RCHECK(entry.ComputeSize() == description_length);
1048 RCHECK(entry.ReadWrite(buffer));
1054 uint32_t SampleGroupDescription::ComputeSizeInternal() {
1057 size_t entries_size = 0;
1058 switch (grouping_type) {
1060 for (
const auto& entry : cenc_sample_encryption_info_entries)
1061 entries_size += entry.ComputeSize();
1064 for (
const auto& entry : audio_roll_recovery_entries)
1065 entries_size += entry.ComputeSize();
1069 if (entries_size == 0)
1071 return HeaderSize() +
sizeof(grouping_type) +
1072 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1076 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
1077 SampleToGroup::~SampleToGroup() {}
1080 bool SampleToGroup::ReadWriteInternal(
BoxBuffer* buffer) {
1082 buffer->ReadWriteUInt32(&grouping_type));
1084 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1086 if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
1088 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1089 << FourCCToString(static_cast<FourCC>(grouping_type));
1093 uint32_t count = entries.size();
1094 RCHECK(buffer->ReadWriteUInt32(&count));
1095 entries.resize(count);
1096 for (uint32_t i = 0; i < count; ++i) {
1097 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1098 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1103 uint32_t SampleToGroup::ComputeSizeInternal() {
1105 if (entries.empty())
1107 return HeaderSize() +
sizeof(grouping_type) +
1108 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1109 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1112 SampleTable::SampleTable() {}
1113 SampleTable::~SampleTable() {}
1116 bool SampleTable::ReadWriteInternal(
BoxBuffer* buffer) {
1130 RCHECK(reader->
ReadChild(&sample_size));
1132 CompactSampleSize compact_sample_size;
1133 RCHECK(reader->
ReadChild(&compact_sample_size));
1134 sample_size.sample_size = 0;
1135 sample_size.sample_count = compact_sample_size.sizes.size();
1136 sample_size.sizes.swap(compact_sample_size.sizes);
1140 if (reader->
ChildExist(&chunk_large_offset)) {
1141 RCHECK(reader->
ReadChild(&chunk_large_offset));
1143 ChunkOffset chunk_offset;
1144 RCHECK(reader->
ReadChild(&chunk_offset));
1145 chunk_large_offset.offsets.swap(chunk_offset.offsets);
1156 for (
auto& sample_group_description : sample_group_descriptions)
1158 for (
auto& sample_to_group : sample_to_groups)
1164 uint32_t SampleTable::ComputeSizeInternal() {
1171 for (
auto& sample_group_description : sample_group_descriptions)
1172 box_size += sample_group_description.ComputeSize();
1173 for (
auto& sample_to_group : sample_to_groups)
1174 box_size += sample_to_group.ComputeSize();
1178 EditList::EditList() {}
1179 EditList::~EditList() {}
1182 bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
1183 uint32_t count = edits.size();
1185 edits.resize(count);
1187 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1188 for (uint32_t i = 0; i < count; ++i) {
1191 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1192 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1193 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1198 uint32_t EditList::ComputeSizeInternal() {
1204 for (uint32_t i = 0; i < edits.size(); ++i) {
1205 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1211 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
1219 bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
1225 uint32_t Edit::ComputeSizeInternal() {
1227 if (list.edits.empty())
1232 HandlerReference::HandlerReference() : handler_type(FOURCC_NULL) {}
1233 HandlerReference::~HandlerReference() {}
1236 bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
1237 std::vector<uint8_t> handler_name;
1239 switch (handler_type) {
1241 handler_name.assign(kVideoHandlerName,
1242 kVideoHandlerName + arraysize(kVideoHandlerName));
1245 handler_name.assign(kAudioHandlerName,
1246 kAudioHandlerName + arraysize(kAudioHandlerName));
1249 handler_name.assign(kTextHandlerName,
1250 kTextHandlerName + arraysize(kTextHandlerName));
1261 buffer->ReadWriteFourCC(&handler_type));
1264 buffer->ReadWriteVector(&handler_name, handler_name.size()));
1269 uint32_t HandlerReference::ComputeSizeInternal() {
1270 uint32_t box_size =
HeaderSize() + kFourCCSize + 16;
1271 switch (handler_type) {
1273 box_size +=
sizeof(kVideoHandlerName);
1276 box_size +=
sizeof(kAudioHandlerName);
1279 box_size +=
sizeof(kTextHandlerName);
1289 bool Language::ReadWrite(BoxBuffer* buffer) {
1290 if (buffer->Reading()) {
1293 std::vector<uint8_t> temp;
1294 RCHECK(buffer->ReadWriteVector(&temp, 2));
1296 BitReader bit_reader(&temp[0], 2);
1297 bit_reader.SkipBits(1);
1299 for (
int i = 0; i < 3; ++i) {
1300 CHECK(bit_reader.ReadBits(5, &language[i]));
1301 language[i] += 0x60;
1303 code.assign(language, 3);
1306 const char kUndefinedLanguage[] =
"und";
1308 code = kUndefinedLanguage;
1309 DCHECK_EQ(code.size(), 3u);
1313 for (
int i = 0; i < 3; ++i)
1314 lang |= (code[i] - 0x60) << ((2 - i) * 5);
1315 RCHECK(buffer->ReadWriteUInt16(&lang));
1320 uint32_t Language::ComputeSize()
const {
1325 bool PrivFrame::ReadWrite(BoxBuffer* buffer) {
1326 FourCC fourcc = FOURCC_PRIV;
1327 RCHECK(buffer->ReadWriteFourCC(&fourcc));
1328 if (fourcc != FOURCC_PRIV) {
1329 VLOG(1) <<
"Skip unrecognized id3 frame during read: "
1330 << FourCCToString(fourcc);
1334 uint32_t frame_size = owner.size() + 1 + value.size();
1338 DCHECK_LT(frame_size, 0x7Fu);
1340 RCHECK(buffer->ReadWriteUInt32(&frame_size) &&
1341 buffer->ReadWriteUInt16(&flags));
1343 if (buffer->Reading()) {
1345 RCHECK(buffer->ReadWriteString(&str, frame_size));
1347 size_t pos = str.find(
'\0');
1348 RCHECK(pos < str.size());
1349 owner = str.substr(0, pos);
1350 value = str.substr(pos + 1);
1353 RCHECK(buffer->ReadWriteString(&owner, owner.size()) &&
1354 buffer->ReadWriteUInt8(&byte) &&
1355 buffer->ReadWriteString(&value, value.size()));
1360 uint32_t PrivFrame::ComputeSize()
const {
1361 if (owner.empty() && value.empty())
1363 const uint32_t kFourCCSize = 4;
1364 return kFourCCSize +
sizeof(uint32_t) +
sizeof(uint16_t) + owner.size() + 1 +
1373 bool ID3v2::ReadWriteInternal(
BoxBuffer* buffer) {
1375 language.ReadWrite(buffer));
1378 std::string id3v2_identifier = kID3v2Identifier;
1379 uint16_t version = kID3v2Version;
1385 DCHECK_LT(data_size, 0x7Fu);
1387 RCHECK(buffer->
ReadWriteString(&id3v2_identifier, id3v2_identifier.size()) &&
1388 buffer->ReadWriteUInt16(&version) &&
1389 buffer->ReadWriteUInt8(&flags) &&
1390 buffer->ReadWriteUInt32(&data_size));
1396 uint32_t ID3v2::ComputeSizeInternal() {
1399 return private_frame_size == 0 ? 0 :
HeaderSize() + language.ComputeSize() +
1404 Metadata::Metadata() {}
1405 Metadata::~Metadata() {}
1411 bool Metadata::ReadWriteInternal(
BoxBuffer* buffer) {
1419 uint32_t Metadata::ComputeSizeInternal() {
1422 return id3v2_size == 0 ? 0
1426 CodecConfiguration::CodecConfiguration() : box_type(FOURCC_NULL) {}
1427 CodecConfiguration::~CodecConfiguration() {}
1435 bool CodecConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1436 DCHECK_NE(box_type, FOURCC_NULL);
1441 if (box_type == FOURCC_vpcC) {
1442 uint32_t version_flags = 0;
1443 RCHECK(buffer->ReadWriteUInt32(&version_flags));
1444 RCHECK(version_flags == 0);
1448 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1450 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1455 uint32_t CodecConfiguration::ComputeSizeInternal() {
1458 DCHECK_NE(box_type, FOURCC_NULL);
1459 return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1462 PixelAspectRatio::PixelAspectRatio() : h_spacing(0), v_spacing(0) {}
1463 PixelAspectRatio::~PixelAspectRatio() {}
1466 bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
1468 buffer->ReadWriteUInt32(&h_spacing) &&
1469 buffer->ReadWriteUInt32(&v_spacing));
1473 uint32_t PixelAspectRatio::ComputeSizeInternal() {
1475 if (h_spacing == 0 && v_spacing == 0)
1478 DCHECK(h_spacing != 0 && v_spacing != 0);
1479 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
1482 VideoSampleEntry::VideoSampleEntry()
1483 : format(FOURCC_NULL), data_reference_index(1), width(0), height(0) {}
1485 VideoSampleEntry::~VideoSampleEntry() {}
1487 if (format == FOURCC_NULL) {
1488 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
1489 <<
"handler type recovered in its Media ancestor.";
1494 bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1495 std::vector<uint8_t> compressor_name;
1497 DCHECK(buffer->
reader());
1498 format = buffer->
reader()->type();
1502 const FourCC actual_format = GetActualFormat();
1503 switch (actual_format) {
1505 compressor_name.assign(
1507 kAvcCompressorName + arraysize(kAvcCompressorName));
1511 compressor_name.assign(
1512 kHevcCompressorName,
1513 kHevcCompressorName + arraysize(kHevcCompressorName));
1518 compressor_name.assign(
1520 kVpcCompressorName + arraysize(kVpcCompressorName));
1523 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
1526 compressor_name.resize(kCompressorNameSize);
1529 uint32_t video_resolution = kVideoResolution;
1530 uint16_t video_frame_count = kVideoFrameCount;
1531 uint16_t video_depth = kVideoDepth;
1532 int16_t predefined = -1;
1534 buffer->ReadWriteUInt16(&data_reference_index) &&
1536 buffer->ReadWriteUInt16(&width) &&
1537 buffer->ReadWriteUInt16(&height) &&
1538 buffer->ReadWriteUInt32(&video_resolution) &&
1539 buffer->ReadWriteUInt32(&video_resolution) &&
1541 buffer->ReadWriteUInt16(&video_frame_count) &&
1542 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1543 buffer->ReadWriteUInt16(&video_depth) &&
1544 buffer->ReadWriteInt16(&predefined));
1548 if (format == FOURCC_encv) {
1552 while (!IsProtectionSchemeSupported(sinf.type.type))
1555 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1560 const FourCC actual_format = GetActualFormat();
1562 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1564 DCHECK_EQ(codec_configuration.box_type,
1565 GetCodecConfigurationBoxType(actual_format));
1567 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1574 uint32_t VideoSampleEntry::ComputeSizeInternal() {
1575 const FourCC actual_format = GetActualFormat();
1576 if (actual_format == FOURCC_NULL)
1578 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1579 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1580 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
1581 sizeof(height) +
sizeof(kVideoResolution) * 2 +
1582 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
1584 codec_configuration.
ComputeSize() + kCompressorNameSize + 6 + 4 + 16 +
1588 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format)
const {
1600 LOG(ERROR) << FourCCToString(format) <<
" is not supported.";
1605 ElementaryStreamDescriptor::ElementaryStreamDescriptor() {}
1606 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
1609 bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
1612 std::vector<uint8_t> data;
1613 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1614 RCHECK(es_descriptor.Parse(data));
1615 if (es_descriptor.
IsAAC()) {
1616 RCHECK(aac_audio_specific_config.
Parse(
1617 es_descriptor.decoder_specific_info()));
1620 DCHECK(buffer->
writer());
1621 es_descriptor.Write(buffer->
writer());
1626 uint32_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1628 if (es_descriptor.object_type() == kForbidden)
1630 return HeaderSize() + es_descriptor.ComputeSize();
1633 DTSSpecific::DTSSpecific()
1634 : sampling_frequency(0),
1637 pcm_sample_depth(0) {}
1638 DTSSpecific::~DTSSpecific() {}
1641 bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1643 buffer->ReadWriteUInt32(&sampling_frequency) &&
1644 buffer->ReadWriteUInt32(&max_bitrate) &&
1645 buffer->ReadWriteUInt32(&avg_bitrate) &&
1646 buffer->ReadWriteUInt8(&pcm_sample_depth));
1649 RCHECK(buffer->ReadWriteVector(&extra_data, buffer->
BytesLeft()));
1651 if (extra_data.empty()) {
1652 extra_data.assign(kDdtsExtraData,
1653 kDdtsExtraData +
sizeof(kDdtsExtraData));
1655 RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1660 uint32_t DTSSpecific::ComputeSizeInternal() {
1662 if (sampling_frequency == 0)
1664 return HeaderSize() +
sizeof(sampling_frequency) +
sizeof(max_bitrate) +
1665 sizeof(avg_bitrate) +
sizeof(pcm_sample_depth) +
1666 sizeof(kDdtsExtraData);
1669 AC3Specific::AC3Specific() {}
1670 AC3Specific::~AC3Specific() {}
1674 bool AC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1676 buffer->ReadWriteVector(
1681 uint32_t AC3Specific::ComputeSizeInternal() {
1688 EC3Specific::EC3Specific() {}
1689 EC3Specific::~EC3Specific() {}
1693 bool EC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1696 RCHECK(buffer->ReadWriteVector(&data, size));
1700 uint32_t EC3Specific::ComputeSizeInternal() {
1707 OpusSpecific::OpusSpecific() : preskip(0) {}
1708 OpusSpecific::~OpusSpecific() {}
1712 bool OpusSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1715 std::vector<uint8_t> data;
1716 const int kMinOpusSpecificBoxDataSize = 11;
1717 RCHECK(buffer->
BytesLeft() >= kMinOpusSpecificBoxDataSize);
1718 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1719 preskip = data[2] + (data[3] << 8);
1724 writer.AppendInt(FOURCC_Head);
1726 const uint8_t kOpusIdentificationHeaderVersion = 1;
1727 data[0] = kOpusIdentificationHeaderVersion;
1728 writer.AppendVector(data);
1729 writer.SwapBuffer(&opus_identification_header);
1733 const size_t kOpusMagicSignatureSize = 8u;
1734 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1737 const uint8_t kOpusSpecificBoxVersion = 0;
1739 buffer->
writer()->AppendArray(
1740 &opus_identification_header[kOpusMagicSignatureSize + 1],
1741 opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1746 uint32_t OpusSpecific::ComputeSizeInternal() {
1748 if (opus_identification_header.empty())
1752 const size_t kOpusMagicSignatureSize = 8u;
1753 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1754 return HeaderSize() + opus_identification_header.size() -
1755 kOpusMagicSignatureSize;
1758 AudioSampleEntry::AudioSampleEntry()
1759 : format(FOURCC_NULL),
1760 data_reference_index(1),
1765 AudioSampleEntry::~AudioSampleEntry() {}
1768 if (format == FOURCC_NULL) {
1769 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
1770 <<
"handler type recovered in its Media ancestor.";
1775 bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1777 DCHECK(buffer->
reader());
1778 format = buffer->
reader()->type();
1786 buffer->ReadWriteUInt16(&data_reference_index) &&
1788 buffer->ReadWriteUInt16(&channelcount) &&
1789 buffer->ReadWriteUInt16(&samplesize) &&
1791 buffer->ReadWriteUInt32(&samplerate));
1796 if (format == FOURCC_enca) {
1800 while (!IsProtectionSchemeSupported(sinf.type.type))
1803 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1816 uint32_t AudioSampleEntry::ComputeSizeInternal() {
1817 if (GetActualFormat() == FOURCC_NULL)
1819 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
1820 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
1827 WebVTTConfigurationBox::WebVTTConfigurationBox() {}
1828 WebVTTConfigurationBox::~WebVTTConfigurationBox() {}
1834 bool WebVTTConfigurationBox::ReadWriteInternal(
BoxBuffer* buffer) {
1841 uint32_t WebVTTConfigurationBox::ComputeSizeInternal() {
1845 WebVTTSourceLabelBox::WebVTTSourceLabelBox() {}
1846 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() {}
1852 bool WebVTTSourceLabelBox::ReadWriteInternal(
BoxBuffer* buffer) {
1856 : source_label.size());
1859 uint32_t WebVTTSourceLabelBox::ComputeSizeInternal() {
1860 if (source_label.empty())
1865 TextSampleEntry::TextSampleEntry() : format(FOURCC_NULL) {}
1866 TextSampleEntry::~TextSampleEntry() {}
1869 if (format == FOURCC_NULL) {
1870 LOG(ERROR) <<
"TextSampleEntry should be parsed according to the "
1871 <<
"handler type recovered in its Media ancestor.";
1876 bool TextSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1878 DCHECK(buffer->
reader());
1879 format = buffer->
reader()->type();
1884 buffer->ReadWriteUInt16(&data_reference_index));
1886 if (format == FOURCC_wvtt) {
1895 uint32_t TextSampleEntry::ComputeSizeInternal() {
1897 return HeaderSize() + 6 +
sizeof(data_reference_index) +
1901 MediaHeader::MediaHeader()
1902 : creation_time(0), modification_time(0), timescale(0), duration(0) {}
1903 MediaHeader::~MediaHeader() {}
1906 bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1909 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1912 buffer->ReadWriteUInt32(×cale) &&
1914 language.ReadWrite(buffer) &&
1919 uint32_t MediaHeader::ComputeSizeInternal() {
1920 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1922 sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
1926 VideoMediaHeader::VideoMediaHeader()
1927 : graphicsmode(0), opcolor_red(0), opcolor_green(0), opcolor_blue(0) {
1928 const uint32_t kVideoMediaHeaderFlags = 1;
1929 flags = kVideoMediaHeaderFlags;
1931 VideoMediaHeader::~VideoMediaHeader() {}
1933 bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1935 buffer->ReadWriteUInt16(&graphicsmode) &&
1936 buffer->ReadWriteUInt16(&opcolor_red) &&
1937 buffer->ReadWriteUInt16(&opcolor_green) &&
1938 buffer->ReadWriteUInt16(&opcolor_blue));
1942 uint32_t VideoMediaHeader::ComputeSizeInternal() {
1943 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
1944 sizeof(opcolor_green) +
sizeof(opcolor_blue);
1947 SoundMediaHeader::SoundMediaHeader() : balance(0) {}
1948 SoundMediaHeader::~SoundMediaHeader() {}
1950 bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1952 buffer->ReadWriteUInt16(&balance) &&
1957 uint32_t SoundMediaHeader::ComputeSizeInternal() {
1958 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
1961 SubtitleMediaHeader::SubtitleMediaHeader() {}
1962 SubtitleMediaHeader::~SubtitleMediaHeader() {}
1966 bool SubtitleMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1970 uint32_t SubtitleMediaHeader::ComputeSizeInternal() {
1974 DataEntryUrl::DataEntryUrl() {
1975 const uint32_t kDataEntryUrlFlags = 1;
1976 flags = kDataEntryUrlFlags;
1978 DataEntryUrl::~DataEntryUrl() {}
1980 bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
1983 RCHECK(buffer->ReadWriteVector(&location, buffer->
BytesLeft()));
1985 RCHECK(buffer->ReadWriteVector(&location, location.size()));
1990 uint32_t DataEntryUrl::ComputeSizeInternal() {
1994 DataReference::DataReference() {
1996 data_entry.resize(1);
1998 DataReference::~DataReference() {}
2000 bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
2001 uint32_t entry_count = data_entry.size();
2003 buffer->ReadWriteUInt32(&entry_count));
2004 data_entry.resize(entry_count);
2006 for (uint32_t i = 0; i < entry_count; ++i)
2011 uint32_t DataReference::ComputeSizeInternal() {
2012 uint32_t count = data_entry.size();
2013 uint32_t box_size =
HeaderSize() +
sizeof(count);
2014 for (uint32_t i = 0; i < count; ++i)
2019 DataInformation::DataInformation() {}
2020 DataInformation::~DataInformation() {}
2023 bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2029 uint32_t DataInformation::ComputeSizeInternal() {
2033 MediaInformation::MediaInformation() {}
2034 MediaInformation::~MediaInformation() {}
2037 bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2042 switch (sample_table.description.type) {
2059 uint32_t MediaInformation::ComputeSizeInternal() {
2062 switch (sample_table.description.type) {
2082 bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
2094 information.sample_table.description.type =
2095 FourCCToTrackType(handler.handler_type);
2097 handler.handler_type =
2098 TrackTypeToFourCC(information.sample_table.description.type);
2099 RCHECK(handler.handler_type != FOURCC_NULL);
2106 uint32_t Media::ComputeSizeInternal() {
2107 handler.handler_type =
2108 TrackTypeToFourCC(information.sample_table.description.type);
2117 bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
2127 uint32_t Track::ComputeSizeInternal() {
2132 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
2133 MovieExtendsHeader::~MovieExtendsHeader() {}
2136 bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2138 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2143 uint32_t MovieExtendsHeader::ComputeSizeInternal() {
2145 if (fragment_duration == 0)
2147 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2148 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2151 TrackExtends::TrackExtends()
2153 default_sample_description_index(0),
2154 default_sample_duration(0),
2155 default_sample_size(0),
2156 default_sample_flags(0) {}
2157 TrackExtends::~TrackExtends() {}
2160 bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2162 buffer->ReadWriteUInt32(&track_id) &&
2163 buffer->ReadWriteUInt32(&default_sample_description_index) &&
2164 buffer->ReadWriteUInt32(&default_sample_duration) &&
2165 buffer->ReadWriteUInt32(&default_sample_size) &&
2166 buffer->ReadWriteUInt32(&default_sample_flags));
2170 uint32_t TrackExtends::ComputeSizeInternal() {
2172 sizeof(default_sample_description_index) +
2173 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
2174 sizeof(default_sample_flags);
2177 MovieExtends::MovieExtends() {}
2178 MovieExtends::~MovieExtends() {}
2181 bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2186 DCHECK(buffer->
reader());
2189 for (uint32_t i = 0; i < tracks.size(); ++i)
2195 uint32_t MovieExtends::ComputeSizeInternal() {
2197 if (tracks.size() == 0)
2200 for (uint32_t i = 0; i < tracks.size(); ++i)
2209 bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
2221 for (uint32_t i = 0; i < tracks.size(); ++i)
2223 for (uint32_t i = 0; i < pssh.size(); ++i)
2229 uint32_t Movie::ComputeSizeInternal() {
2232 for (uint32_t i = 0; i < tracks.size(); ++i)
2234 for (uint32_t i = 0; i < pssh.size(); ++i)
2239 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
2240 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
2243 bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
2245 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2250 uint32_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2251 version = IsFitIn32Bits(decode_time) ? 0 : 1;
2252 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2255 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
2256 MovieFragmentHeader::~MovieFragmentHeader() {}
2259 bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2261 buffer->ReadWriteUInt32(&sequence_number);
2264 uint32_t MovieFragmentHeader::ComputeSizeInternal() {
2265 return HeaderSize() +
sizeof(sequence_number);
2268 TrackFragmentHeader::TrackFragmentHeader()
2270 sample_description_index(0),
2271 default_sample_duration(0),
2272 default_sample_size(0),
2273 default_sample_flags(0) {}
2275 TrackFragmentHeader::~TrackFragmentHeader() {}
2278 bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2280 buffer->ReadWriteUInt32(&track_id));
2282 if (flags & kBaseDataOffsetPresentMask) {
2287 uint64_t base_data_offset;
2288 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2289 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
2290 "default-base-is-moof.";
2293 if (flags & kSampleDescriptionIndexPresentMask) {
2294 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2295 }
else if (buffer->
Reading()) {
2296 sample_description_index = 0;
2299 if (flags & kDefaultSampleDurationPresentMask) {
2300 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2301 }
else if (buffer->
Reading()) {
2302 default_sample_duration = 0;
2305 if (flags & kDefaultSampleSizePresentMask) {
2306 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2307 }
else if (buffer->
Reading()) {
2308 default_sample_size = 0;
2311 if (flags & kDefaultSampleFlagsPresentMask)
2312 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2316 uint32_t TrackFragmentHeader::ComputeSizeInternal() {
2317 uint32_t box_size =
HeaderSize() +
sizeof(track_id);
2318 if (flags & kSampleDescriptionIndexPresentMask)
2319 box_size +=
sizeof(sample_description_index);
2320 if (flags & kDefaultSampleDurationPresentMask)
2321 box_size +=
sizeof(default_sample_duration);
2322 if (flags & kDefaultSampleSizePresentMask)
2323 box_size +=
sizeof(default_sample_size);
2324 if (flags & kDefaultSampleFlagsPresentMask)
2325 box_size +=
sizeof(default_sample_flags);
2329 TrackFragmentRun::TrackFragmentRun() : sample_count(0), data_offset(0) {}
2330 TrackFragmentRun::~TrackFragmentRun() {}
2333 bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
2339 if (flags & kSampleCompTimeOffsetsPresentMask) {
2340 for (uint32_t i = 0; i < sample_count; ++i) {
2341 if (sample_composition_time_offsets[i] < 0) {
2350 buffer->ReadWriteUInt32(&sample_count));
2352 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2353 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2354 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2355 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2356 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2357 bool sample_composition_time_offsets_present =
2358 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2360 if (data_offset_present) {
2361 RCHECK(buffer->ReadWriteUInt32(&data_offset));
2372 uint32_t first_sample_flags;
2375 if (first_sample_flags_present)
2376 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2378 if (sample_duration_present)
2379 sample_durations.resize(sample_count);
2380 if (sample_size_present)
2381 sample_sizes.resize(sample_count);
2382 if (sample_flags_present)
2383 sample_flags.resize(sample_count);
2384 if (sample_composition_time_offsets_present)
2385 sample_composition_time_offsets.resize(sample_count);
2387 if (first_sample_flags_present) {
2388 first_sample_flags = sample_flags[0];
2389 DCHECK(sample_flags.size() == 1);
2390 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2393 if (sample_duration_present)
2394 DCHECK(sample_durations.size() == sample_count);
2395 if (sample_size_present)
2396 DCHECK(sample_sizes.size() == sample_count);
2397 if (sample_flags_present)
2398 DCHECK(sample_flags.size() == sample_count);
2399 if (sample_composition_time_offsets_present)
2400 DCHECK(sample_composition_time_offsets.size() == sample_count);
2403 for (uint32_t i = 0; i < sample_count; ++i) {
2404 if (sample_duration_present)
2405 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2406 if (sample_size_present)
2407 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2408 if (sample_flags_present)
2409 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2411 if (sample_composition_time_offsets_present) {
2413 uint32_t sample_offset = sample_composition_time_offsets[i];
2414 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2415 sample_composition_time_offsets[i] = sample_offset;
2417 int32_t sample_offset = sample_composition_time_offsets[i];
2418 RCHECK(buffer->ReadWriteInt32(&sample_offset));
2419 sample_composition_time_offsets[i] = sample_offset;
2425 if (first_sample_flags_present) {
2426 if (sample_flags.size() == 0) {
2427 sample_flags.push_back(first_sample_flags);
2429 sample_flags[0] = first_sample_flags;
2436 uint32_t TrackFragmentRun::ComputeSizeInternal() {
2437 uint32_t box_size =
HeaderSize() +
sizeof(sample_count);
2438 if (flags & kDataOffsetPresentMask)
2439 box_size +=
sizeof(data_offset);
2440 if (flags & kFirstSampleFlagsPresentMask)
2441 box_size +=
sizeof(uint32_t);
2442 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2443 (flags & kSampleSizePresentMask ? 1 : 0) +
2444 (flags & kSampleFlagsPresentMask ? 1 : 0) +
2445 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2446 box_size += fields *
sizeof(uint32_t) * sample_count;
2450 TrackFragment::TrackFragment() : decode_time_absent(false) {}
2451 TrackFragment::~TrackFragment() {}
2454 bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2459 DCHECK(buffer->
reader());
2461 if (!decode_time_absent)
2467 if (!decode_time_absent)
2469 for (uint32_t i = 0; i < runs.size(); ++i)
2471 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2473 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2481 uint32_t TrackFragment::ComputeSizeInternal() {
2486 for (uint32_t i = 0; i < runs.size(); ++i)
2488 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2489 box_size += sample_group_descriptions[i].
ComputeSize();
2490 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2495 MovieFragment::MovieFragment() {}
2496 MovieFragment::~MovieFragment() {}
2499 bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2509 for (uint32_t i = 0; i < tracks.size(); ++i)
2511 for (uint32_t i = 0; i < pssh.size(); ++i)
2517 uint32_t MovieFragment::ComputeSizeInternal() {
2519 for (uint32_t i = 0; i < tracks.size(); ++i)
2521 for (uint32_t i = 0; i < pssh.size(); ++i)
2526 SegmentIndex::SegmentIndex()
2529 earliest_presentation_time(0),
2531 SegmentIndex::~SegmentIndex() {}
2534 bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
2536 buffer->ReadWriteUInt32(&reference_id) &&
2537 buffer->ReadWriteUInt32(×cale));
2539 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2544 uint16_t reference_count = references.size();
2546 buffer->ReadWriteUInt16(&reference_count));
2547 references.resize(reference_count);
2549 uint32_t reference_type_size;
2551 for (uint32_t i = 0; i < reference_count; ++i) {
2553 reference_type_size = references[i].referenced_size;
2554 if (references[i].reference_type)
2555 reference_type_size |= (1 << 31);
2556 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2557 if (references[i].starts_with_sap)
2560 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2561 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2562 buffer->ReadWriteUInt32(&sap));
2564 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
2565 references[i].referenced_size = reference_type_size & ~(1 << 31);
2566 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
2567 references[i].sap_type =
2568 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
2569 references[i].sap_delta_time = sap & ~(0xF << 28);
2575 uint32_t SegmentIndex::ComputeSizeInternal() {
2576 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2577 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
2578 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
2579 3 *
sizeof(uint32_t) * references.size();
2582 MediaData::MediaData() : data_size(0) {}
2583 MediaData::~MediaData() {}
2586 bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
2587 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
2591 uint32_t MediaData::ComputeSizeInternal() {
2595 CueSourceIDBox::CueSourceIDBox() : source_id(kCueSourceIdNotSet) {}
2596 CueSourceIDBox::~CueSourceIDBox() {}
2600 bool CueSourceIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2605 uint32_t CueSourceIDBox::ComputeSizeInternal() {
2606 if (source_id == kCueSourceIdNotSet)
2611 CueTimeBox::CueTimeBox() {}
2612 CueTimeBox::~CueTimeBox() {}
2618 bool CueTimeBox::ReadWriteInternal(
BoxBuffer* buffer) {
2625 uint32_t CueTimeBox::ComputeSizeInternal() {
2626 if (cue_current_time.empty())
2628 return HeaderSize() + cue_current_time.size();
2631 CueIDBox::CueIDBox() {}
2632 CueIDBox::~CueIDBox() {}
2638 bool CueIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2644 uint32_t CueIDBox::ComputeSizeInternal() {
2650 CueSettingsBox::CueSettingsBox() {}
2651 CueSettingsBox::~CueSettingsBox() {}
2657 bool CueSettingsBox::ReadWriteInternal(
BoxBuffer* buffer) {
2663 uint32_t CueSettingsBox::ComputeSizeInternal() {
2664 if (settings.empty())
2669 CuePayloadBox::CuePayloadBox() {}
2670 CuePayloadBox::~CuePayloadBox() {}
2676 bool CuePayloadBox::ReadWriteInternal(
BoxBuffer* buffer) {
2682 uint32_t CuePayloadBox::ComputeSizeInternal() {
2686 VTTEmptyCueBox::VTTEmptyCueBox() {}
2687 VTTEmptyCueBox::~VTTEmptyCueBox() {}
2693 bool VTTEmptyCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2697 uint32_t VTTEmptyCueBox::ComputeSizeInternal() {
2701 VTTAdditionalTextBox::VTTAdditionalTextBox() {}
2702 VTTAdditionalTextBox::~VTTAdditionalTextBox() {}
2708 bool VTTAdditionalTextBox::ReadWriteInternal(
BoxBuffer* buffer) {
2711 &cue_additional_text,
2715 uint32_t VTTAdditionalTextBox::ComputeSizeInternal() {
2716 return HeaderSize() + cue_additional_text.size();
2719 VTTCueBox::VTTCueBox() {}
2720 VTTCueBox::~VTTCueBox() {}
2726 bool VTTCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2737 uint32_t VTTCueBox::ComputeSizeInternal() {
FourCC BoxType() const override
bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
uint32_t GetTotalSizeOfSubsamples() const
bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
FourCC BoxType() const override
uint32_t ComputeSize() const