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(uint8_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 size_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 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
182 return raw_box.size();
185 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
186 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
189 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
194 uint32_t count =
static_cast<uint32_t
>(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 size_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 size_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 =
static_cast<uint16_t
>(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 =
static_cast<uint16_t
>(subsamples.size());
293 return static_cast<uint32_t
>(
294 initialization_vector.size() +
296 ? (
sizeof(subsample_count) + subsample_entry_size * subsample_count)
302 for (uint32_t i = 0; i < subsamples.size(); ++i)
303 size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
307 SampleEncryption::SampleEncryption() : iv_size(kInvalidIvSize) {}
308 SampleEncryption::~SampleEncryption() {}
311 bool SampleEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
316 if (buffer->
Reading() && iv_size == kInvalidIvSize) {
322 if (!IsIvSizeValid(iv_size)) {
324 <<
"IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
329 uint32_t sample_count =
330 static_cast<uint32_t
>(sample_encryption_entries.size());
331 RCHECK(buffer->ReadWriteUInt32(&sample_count));
333 sample_encryption_entries.resize(sample_count);
334 for (
auto& sample_encryption_entry : sample_encryption_entries) {
335 RCHECK(sample_encryption_entry.ReadWrite(
336 iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
341 size_t SampleEncryption::ComputeSizeInternal() {
342 const uint32_t sample_count =
343 static_cast<uint32_t
>(sample_encryption_entries.size());
344 if (sample_count == 0) {
349 DCHECK(IsIvSizeValid(iv_size));
351 if (flags & kUseSubsampleEncryption) {
352 for (
const SampleEncryptionEntry& sample_encryption_entry :
353 sample_encryption_entries) {
354 box_size += sample_encryption_entry.ComputeSize();
357 box_size += sample_count * iv_size;
364 std::vector<SampleEncryptionEntry>* sample_encryption_entries)
const {
365 DCHECK(IsIvSizeValid(iv_size));
369 uint32_t sample_count = 0;
370 RCHECK(reader.Read4(&sample_count));
372 sample_encryption_entries->resize(sample_count);
373 for (
auto& sample_encryption_entry : *sample_encryption_entries) {
374 RCHECK(sample_encryption_entry.ParseFromBuffer(
375 iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) != 0);
380 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
381 OriginalFormat::~OriginalFormat() {}
384 bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
388 size_t OriginalFormat::ComputeSizeInternal() {
392 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
393 SchemeType::~SchemeType() {}
396 bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
398 buffer->ReadWriteFourCC(&type) &&
399 buffer->ReadWriteUInt32(&version));
403 size_t SchemeType::ComputeSizeInternal() {
404 return HeaderSize() + kFourCCSize +
sizeof(version);
407 TrackEncryption::TrackEncryption()
408 : default_is_protected(0),
409 default_per_sample_iv_size(0),
411 default_crypt_byte_block(0),
412 default_skip_byte_block(0) {}
413 TrackEncryption::~TrackEncryption() {}
416 bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
418 if (default_kid.size() != kCencKeyIdSize) {
419 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
420 <<
" bytes; got " << default_kid.size()
421 <<
". Resized accordingly.";
422 default_kid.resize(kCencKeyIdSize);
424 RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
425 if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
434 uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
435 RCHECK(buffer->ReadWriteUInt8(&pattern));
436 default_crypt_byte_block = pattern >> 4;
437 default_skip_byte_block = pattern & 0x0F;
439 RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
440 buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
441 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
443 if (default_is_protected == 1) {
444 if (default_per_sample_iv_size == 0) {
445 uint8_t default_constant_iv_size =
446 static_cast<uint8_t
>(default_constant_iv.size());
447 RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
448 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
449 RCHECK(buffer->ReadWriteVector(&default_constant_iv,
450 default_constant_iv_size));
452 RCHECK(default_per_sample_iv_size == 8 ||
453 default_per_sample_iv_size == 16);
454 RCHECK(default_constant_iv.empty());
459 RCHECK(default_is_protected == 0);
460 RCHECK(default_per_sample_iv_size == 0);
461 RCHECK(default_constant_iv.empty());
466 size_t TrackEncryption::ComputeSizeInternal() {
467 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize +
468 (default_constant_iv.empty() ? 0 : (
sizeof(uint8_t) +
469 default_constant_iv.size()));
472 SchemeInfo::SchemeInfo() {}
473 SchemeInfo::~SchemeInfo() {}
476 bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
482 size_t SchemeInfo::ComputeSizeInternal() {
486 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
487 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
490 bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
495 if (IsProtectionSchemeSupported(type.type)) {
498 DLOG(WARNING) <<
"Ignore unsupported protection scheme: "
499 << FourCCToString(type.type);
508 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
510 if (format.format == FOURCC_NULL)
516 MovieHeader::MovieHeader()
518 modification_time(0),
524 MovieHeader::~MovieHeader() {}
527 bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
530 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
533 buffer->ReadWriteUInt32(×cale) &&
536 std::vector<uint8_t> matrix(kUnityMatrix,
537 kUnityMatrix + arraysize(kUnityMatrix));
538 RCHECK(buffer->ReadWriteInt32(&rate) &&
539 buffer->ReadWriteInt16(&volume) &&
541 buffer->ReadWriteVector(&matrix, matrix.size()) &&
543 buffer->ReadWriteUInt32(&next_track_id));
547 size_t MovieHeader::ComputeSizeInternal() {
548 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
549 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
550 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
551 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
555 TrackHeader::TrackHeader()
557 modification_time(0),
565 flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
567 TrackHeader::~TrackHeader() {}
570 bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
573 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
576 buffer->ReadWriteUInt32(&track_id) &&
583 volume = (width != 0 && height != 0) ? 0 : 0x100;
585 std::vector<uint8_t> matrix(kUnityMatrix,
586 kUnityMatrix + arraysize(kUnityMatrix));
588 buffer->ReadWriteInt16(&layer) &&
589 buffer->ReadWriteInt16(&alternate_group) &&
590 buffer->ReadWriteInt16(&volume) &&
592 buffer->ReadWriteVector(&matrix, matrix.size()) &&
593 buffer->ReadWriteUInt32(&width) &&
594 buffer->ReadWriteUInt32(&height));
598 size_t TrackHeader::ComputeSizeInternal() {
599 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
601 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
602 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
603 sizeof(height) +
sizeof(kUnityMatrix) + 14;
606 SampleDescription::SampleDescription() : type(kInvalid) {}
607 SampleDescription::~SampleDescription() {}
610 bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
614 count =
static_cast<uint32_t
>(video_entries.size());
617 count =
static_cast<uint32_t
>(audio_entries.size());
620 count =
static_cast<uint32_t
>(text_entries.size());
623 NOTIMPLEMENTED() <<
"SampleDecryption type " << type
624 <<
" is not handled. Skipping.";
627 buffer->ReadWriteUInt32(&count));
630 BoxReader* reader = buffer->
reader();
632 video_entries.clear();
633 audio_entries.clear();
636 if (type == kVideo) {
637 RCHECK(reader->ReadAllChildren(&video_entries));
638 RCHECK(video_entries.size() == count);
639 }
else if (type == kAudio) {
640 RCHECK(reader->ReadAllChildren(&audio_entries));
641 RCHECK(audio_entries.size() == count);
642 }
else if (type == kText) {
643 RCHECK(reader->ReadAllChildren(&text_entries));
644 RCHECK(text_entries.size() == count);
647 DCHECK_LT(0u, count);
648 if (type == kVideo) {
649 for (uint32_t i = 0; i < count; ++i)
651 }
else if (type == kAudio) {
652 for (uint32_t i = 0; i < count; ++i)
654 }
else if (type == kText) {
655 for (uint32_t i = 0; i < count; ++i)
664 size_t SampleDescription::ComputeSizeInternal() {
665 size_t box_size =
HeaderSize() +
sizeof(uint32_t);
666 if (type == kVideo) {
667 for (uint32_t i = 0; i < video_entries.size(); ++i)
669 }
else if (type == kAudio) {
670 for (uint32_t i = 0; i < audio_entries.size(); ++i)
672 }
else if (type == kText) {
673 for (uint32_t i = 0; i < text_entries.size(); ++i)
679 DecodingTimeToSample::DecodingTimeToSample() {}
680 DecodingTimeToSample::~DecodingTimeToSample() {}
683 bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
684 uint32_t count =
static_cast<uint32_t
>(decoding_time.size());
686 buffer->ReadWriteUInt32(&count));
688 decoding_time.resize(count);
689 for (uint32_t i = 0; i < count; ++i) {
690 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
691 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
696 size_t DecodingTimeToSample::ComputeSizeInternal() {
698 sizeof(DecodingTime) * decoding_time.size();
701 CompositionTimeToSample::CompositionTimeToSample() {}
702 CompositionTimeToSample::~CompositionTimeToSample() {}
705 bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
706 uint32_t count =
static_cast<uint32_t
>(composition_offset.size());
712 for (uint32_t i = 0; i < count; ++i) {
713 if (composition_offset[i].sample_offset < 0) {
721 buffer->ReadWriteUInt32(&count));
723 composition_offset.resize(count);
724 for (uint32_t i = 0; i < count; ++i) {
725 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
728 uint32_t sample_offset = composition_offset[i].sample_offset;
729 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
730 composition_offset[i].sample_offset = sample_offset;
732 int32_t sample_offset = composition_offset[i].sample_offset;
733 RCHECK(buffer->ReadWriteInt32(&sample_offset));
734 composition_offset[i].sample_offset = sample_offset;
740 size_t CompositionTimeToSample::ComputeSizeInternal() {
742 if (composition_offset.empty())
747 const size_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
749 kCompositionOffsetSize * composition_offset.size();
752 SampleToChunk::SampleToChunk() {}
753 SampleToChunk::~SampleToChunk() {}
756 bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
757 uint32_t count =
static_cast<uint32_t
>(chunk_info.size());
759 buffer->ReadWriteUInt32(&count));
761 chunk_info.resize(count);
762 for (uint32_t i = 0; i < count; ++i) {
763 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
764 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
765 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
767 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
768 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
773 size_t SampleToChunk::ComputeSizeInternal() {
775 sizeof(ChunkInfo) * chunk_info.size();
778 SampleSize::SampleSize() : sample_size(0), sample_count(0) {}
779 SampleSize::~SampleSize() {}
782 bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
784 buffer->ReadWriteUInt32(&sample_size) &&
785 buffer->ReadWriteUInt32(&sample_count));
787 if (sample_size == 0) {
789 sizes.resize(sample_count);
791 DCHECK(sample_count == sizes.size());
792 for (uint32_t i = 0; i < sample_count; ++i)
793 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
798 size_t SampleSize::ComputeSizeInternal() {
799 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
800 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
803 CompactSampleSize::CompactSampleSize() : field_size(0) {}
804 CompactSampleSize::~CompactSampleSize() {}
807 bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
808 uint32_t sample_count =
static_cast<uint32_t
>(sizes.size());
811 buffer->ReadWriteUInt8(&field_size) &&
812 buffer->ReadWriteUInt32(&sample_count));
815 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
816 switch (field_size) {
818 for (uint32_t i = 0; i < sample_count; i += 2) {
821 RCHECK(buffer->ReadWriteUInt8(&size));
822 sizes[i] = size >> 4;
823 sizes[i + 1] = size & 0x0F;
825 DCHECK_LT(sizes[i], 16u);
826 DCHECK_LT(sizes[i + 1], 16u);
827 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
828 RCHECK(buffer->ReadWriteUInt8(&size));
833 for (uint32_t i = 0; i < sample_count; ++i) {
834 uint8_t size = sizes[i];
835 RCHECK(buffer->ReadWriteUInt8(&size));
840 for (uint32_t i = 0; i < sample_count; ++i) {
841 uint16_t size = sizes[i];
842 RCHECK(buffer->ReadWriteUInt16(&size));
849 sizes.resize(sample_count);
853 size_t CompactSampleSize::ComputeSizeInternal() {
854 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
855 (field_size * sizes.size() + 7) / 8;
858 ChunkOffset::ChunkOffset() {}
859 ChunkOffset::~ChunkOffset() {}
862 bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
863 uint32_t count =
static_cast<uint32_t
>(offsets.size());
865 buffer->ReadWriteUInt32(&count));
867 offsets.resize(count);
868 for (uint32_t i = 0; i < count; ++i)
873 size_t ChunkOffset::ComputeSizeInternal() {
874 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
877 ChunkLargeOffset::ChunkLargeOffset() {}
878 ChunkLargeOffset::~ChunkLargeOffset() {}
881 bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
882 uint32_t count =
static_cast<uint32_t
>(offsets.size());
886 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
888 stco.offsets.swap(offsets);
891 stco.offsets.swap(offsets);
897 buffer->ReadWriteUInt32(&count));
899 offsets.resize(count);
900 for (uint32_t i = 0; i < count; ++i)
901 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
905 size_t ChunkLargeOffset::ComputeSizeInternal() {
906 uint32_t count =
static_cast<uint32_t
>(offsets.size());
907 int use_large_offset =
908 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
910 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
913 SyncSample::SyncSample() {}
914 SyncSample::~SyncSample() {}
917 bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
918 uint32_t count =
static_cast<uint32_t
>(sample_number.size());
920 buffer->ReadWriteUInt32(&count));
922 sample_number.resize(count);
923 for (uint32_t i = 0; i < count; ++i)
924 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
928 size_t SyncSample::ComputeSizeInternal() {
930 if (sample_number.empty())
933 sizeof(uint32_t) * sample_number.size();
936 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
938 per_sample_iv_size(0),
940 skip_byte_block(0) {}
941 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {};
943 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
944 if (!buffer->Reading()) {
945 if (key_id.size() != kCencKeyIdSize) {
946 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
947 <<
" bytes; got " << key_id.size()
948 <<
". Resized accordingly.";
949 key_id.resize(kCencKeyIdSize);
951 RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
954 RCHECK(buffer->IgnoreBytes(1));
956 uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
957 RCHECK(buffer->ReadWriteUInt8(&pattern));
958 crypt_byte_block = pattern >> 4;
959 skip_byte_block = pattern & 0x0F;
961 RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
962 buffer->ReadWriteUInt8(&per_sample_iv_size) &&
963 buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
965 if (is_protected == 1) {
966 if (per_sample_iv_size == 0) {
967 uint8_t constant_iv_size =
static_cast<uint8_t
>(constant_iv.size());
968 RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
969 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
970 RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
972 RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
973 DCHECK(constant_iv.empty());
978 RCHECK(is_protected == 0);
979 RCHECK(per_sample_iv_size == 0);
984 uint32_t CencSampleEncryptionInfoEntry::ComputeSize()
const {
985 return static_cast<uint32_t
>(
986 sizeof(uint32_t) + kCencKeyIdSize +
987 (constant_iv.empty() ? 0 : (
sizeof(uint8_t) + constant_iv.size())));
990 AudioRollRecoveryEntry::AudioRollRecoveryEntry(): roll_distance(0) {}
991 AudioRollRecoveryEntry::~AudioRollRecoveryEntry() {}
993 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
994 RCHECK(buffer->ReadWriteInt16(&roll_distance));
998 uint32_t AudioRollRecoveryEntry::ComputeSize()
const {
999 return sizeof(roll_distance);
1002 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
1003 SampleGroupDescription::~SampleGroupDescription() {}
1006 bool SampleGroupDescription::ReadWriteInternal(
BoxBuffer* buffer) {
1008 buffer->ReadWriteUInt32(&grouping_type));
1010 switch (grouping_type) {
1012 return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
1014 return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
1017 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1018 << FourCCToString(static_cast<FourCC>(grouping_type));
1023 template <
typename T>
1024 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
1025 std::vector<T>* entries) {
1026 uint32_t default_length = 0;
1027 if (!buffer->Reading()) {
1028 DCHECK(!entries->empty());
1029 default_length = (*entries)[0].ComputeSize();
1030 DCHECK_NE(default_length, 0u);
1033 RCHECK(buffer->ReadWriteUInt32(&default_length));
1035 NOTIMPLEMENTED() <<
"Unsupported SampleGroupDescriptionBox 'sgpd' version "
1036 <<
static_cast<int>(version);
1040 uint32_t count =
static_cast<uint32_t
>(entries->size());
1041 RCHECK(buffer->ReadWriteUInt32(&count));
1043 entries->resize(count);
1045 for (T& entry : *entries) {
1047 uint32_t description_length = default_length;
1048 if (buffer->Reading() && default_length == 0)
1049 RCHECK(buffer->ReadWriteUInt32(&description_length));
1050 RCHECK(entry.ReadWrite(buffer));
1051 RCHECK(entry.ComputeSize() == description_length);
1053 RCHECK(entry.ReadWrite(buffer));
1059 size_t SampleGroupDescription::ComputeSizeInternal() {
1062 size_t entries_size = 0;
1063 switch (grouping_type) {
1065 for (
const auto& entry : cenc_sample_encryption_info_entries)
1066 entries_size += entry.ComputeSize();
1069 for (
const auto& entry : audio_roll_recovery_entries)
1070 entries_size += entry.ComputeSize();
1074 if (entries_size == 0)
1076 return HeaderSize() +
sizeof(grouping_type) +
1077 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1081 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
1082 SampleToGroup::~SampleToGroup() {}
1085 bool SampleToGroup::ReadWriteInternal(
BoxBuffer* buffer) {
1087 buffer->ReadWriteUInt32(&grouping_type));
1089 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1091 if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
1093 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1094 << FourCCToString(static_cast<FourCC>(grouping_type));
1098 uint32_t count =
static_cast<uint32_t
>(entries.size());
1099 RCHECK(buffer->ReadWriteUInt32(&count));
1100 entries.resize(count);
1101 for (uint32_t i = 0; i < count; ++i) {
1102 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1103 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1108 size_t SampleToGroup::ComputeSizeInternal() {
1110 if (entries.empty())
1112 return HeaderSize() +
sizeof(grouping_type) +
1113 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1114 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1117 SampleTable::SampleTable() {}
1118 SampleTable::~SampleTable() {}
1121 bool SampleTable::ReadWriteInternal(
BoxBuffer* buffer) {
1135 RCHECK(reader->
ReadChild(&sample_size));
1137 CompactSampleSize compact_sample_size;
1138 RCHECK(reader->
ReadChild(&compact_sample_size));
1139 sample_size.sample_size = 0;
1140 sample_size.sample_count =
1141 static_cast<uint32_t
>(compact_sample_size.sizes.size());
1142 sample_size.sizes.swap(compact_sample_size.sizes);
1146 if (reader->
ChildExist(&chunk_large_offset)) {
1147 RCHECK(reader->
ReadChild(&chunk_large_offset));
1149 ChunkOffset chunk_offset;
1150 RCHECK(reader->
ReadChild(&chunk_offset));
1151 chunk_large_offset.offsets.swap(chunk_offset.offsets);
1162 for (
auto& sample_group_description : sample_group_descriptions)
1164 for (
auto& sample_to_group : sample_to_groups)
1170 size_t SampleTable::ComputeSizeInternal() {
1177 for (
auto& sample_group_description : sample_group_descriptions)
1178 box_size += sample_group_description.ComputeSize();
1179 for (
auto& sample_to_group : sample_to_groups)
1180 box_size += sample_to_group.ComputeSize();
1184 EditList::EditList() {}
1185 EditList::~EditList() {}
1188 bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
1189 uint32_t count =
static_cast<uint32_t
>(edits.size());
1191 edits.resize(count);
1193 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1194 for (uint32_t i = 0; i < count; ++i) {
1197 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1198 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1199 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1204 size_t EditList::ComputeSizeInternal() {
1210 for (uint32_t i = 0; i < edits.size(); ++i) {
1211 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1217 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
1225 bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
1231 size_t Edit::ComputeSizeInternal() {
1233 if (list.edits.empty())
1238 HandlerReference::HandlerReference() : handler_type(FOURCC_NULL) {}
1239 HandlerReference::~HandlerReference() {}
1242 bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
1243 std::vector<uint8_t> handler_name;
1245 switch (handler_type) {
1247 handler_name.assign(kVideoHandlerName,
1248 kVideoHandlerName + arraysize(kVideoHandlerName));
1251 handler_name.assign(kAudioHandlerName,
1252 kAudioHandlerName + arraysize(kAudioHandlerName));
1255 handler_name.assign(kTextHandlerName,
1256 kTextHandlerName + arraysize(kTextHandlerName));
1267 buffer->ReadWriteFourCC(&handler_type));
1270 buffer->ReadWriteVector(&handler_name, handler_name.size()));
1275 size_t HandlerReference::ComputeSizeInternal() {
1276 size_t box_size =
HeaderSize() + kFourCCSize + 16;
1277 switch (handler_type) {
1279 box_size +=
sizeof(kVideoHandlerName);
1282 box_size +=
sizeof(kAudioHandlerName);
1285 box_size +=
sizeof(kTextHandlerName);
1295 bool Language::ReadWrite(BoxBuffer* buffer) {
1296 if (buffer->Reading()) {
1299 std::vector<uint8_t> temp;
1300 RCHECK(buffer->ReadWriteVector(&temp, 2));
1302 BitReader bit_reader(&temp[0], 2);
1303 bit_reader.SkipBits(1);
1305 for (
int i = 0; i < 3; ++i) {
1306 CHECK(bit_reader.ReadBits(5, &language[i]));
1307 language[i] += 0x60;
1309 code.assign(language, 3);
1312 const char kUndefinedLanguage[] =
"und";
1314 code = kUndefinedLanguage;
1315 DCHECK_EQ(code.size(), 3u);
1319 for (
int i = 0; i < 3; ++i)
1320 lang |= (code[i] - 0x60) << ((2 - i) * 5);
1321 RCHECK(buffer->ReadWriteUInt16(&lang));
1326 uint32_t Language::ComputeSize()
const {
1331 bool PrivFrame::ReadWrite(BoxBuffer* buffer) {
1332 FourCC fourcc = FOURCC_PRIV;
1333 RCHECK(buffer->ReadWriteFourCC(&fourcc));
1334 if (fourcc != FOURCC_PRIV) {
1335 VLOG(1) <<
"Skip unrecognized id3 frame during read: "
1336 << FourCCToString(fourcc);
1340 uint32_t frame_size =
static_cast<uint32_t
>(owner.size() + 1 + value.size());
1344 DCHECK_LT(frame_size, 0x7Fu);
1346 RCHECK(buffer->ReadWriteUInt32(&frame_size) &&
1347 buffer->ReadWriteUInt16(&flags));
1349 if (buffer->Reading()) {
1351 RCHECK(buffer->ReadWriteString(&str, frame_size));
1353 size_t pos = str.find(
'\0');
1354 RCHECK(pos < str.size());
1355 owner = str.substr(0, pos);
1356 value = str.substr(pos + 1);
1359 RCHECK(buffer->ReadWriteString(&owner, owner.size()) &&
1360 buffer->ReadWriteUInt8(&byte) &&
1361 buffer->ReadWriteString(&value, value.size()));
1366 uint32_t PrivFrame::ComputeSize()
const {
1367 if (owner.empty() && value.empty())
1369 const uint32_t kFourCCSize = 4;
1370 return kFourCCSize +
1371 static_cast<uint32_t
>(
sizeof(uint32_t) +
sizeof(uint16_t) +
1372 owner.size() + 1 + value.size());
1380 bool ID3v2::ReadWriteInternal(
BoxBuffer* buffer) {
1382 language.ReadWrite(buffer));
1385 std::string id3v2_identifier = kID3v2Identifier;
1386 uint16_t version = kID3v2Version;
1392 DCHECK_LT(data_size, 0x7Fu);
1394 RCHECK(buffer->
ReadWriteString(&id3v2_identifier, id3v2_identifier.size()) &&
1395 buffer->ReadWriteUInt16(&version) &&
1396 buffer->ReadWriteUInt8(&flags) &&
1397 buffer->ReadWriteUInt32(&data_size));
1403 size_t ID3v2::ComputeSizeInternal() {
1406 return private_frame_size == 0 ? 0 :
HeaderSize() + language.ComputeSize() +
1411 Metadata::Metadata() {}
1412 Metadata::~Metadata() {}
1418 bool Metadata::ReadWriteInternal(
BoxBuffer* buffer) {
1426 size_t Metadata::ComputeSizeInternal() {
1429 return id3v2_size == 0 ? 0
1433 CodecConfiguration::CodecConfiguration() : box_type(FOURCC_NULL) {}
1434 CodecConfiguration::~CodecConfiguration() {}
1442 bool CodecConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1443 DCHECK_NE(box_type, FOURCC_NULL);
1448 if (box_type == FOURCC_vpcC) {
1450 uint8_t vpcc_version = 1;
1451 uint32_t version_flags = vpcc_version << 24;
1452 RCHECK(buffer->ReadWriteUInt32(&version_flags));
1453 vpcc_version = version_flags >> 24;
1454 RCHECK(vpcc_version == 1);
1458 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1460 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1465 size_t CodecConfiguration::ComputeSizeInternal() {
1468 DCHECK_NE(box_type, FOURCC_NULL);
1469 return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1472 PixelAspectRatio::PixelAspectRatio() : h_spacing(0), v_spacing(0) {}
1473 PixelAspectRatio::~PixelAspectRatio() {}
1476 bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
1478 buffer->ReadWriteUInt32(&h_spacing) &&
1479 buffer->ReadWriteUInt32(&v_spacing));
1483 size_t PixelAspectRatio::ComputeSizeInternal() {
1485 if (h_spacing == 0 && v_spacing == 0)
1488 DCHECK(h_spacing != 0 && v_spacing != 0);
1489 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
1492 VideoSampleEntry::VideoSampleEntry()
1493 : format(FOURCC_NULL), data_reference_index(1), width(0), height(0) {}
1495 VideoSampleEntry::~VideoSampleEntry() {}
1497 if (format == FOURCC_NULL) {
1498 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
1499 <<
"handler type recovered in its Media ancestor.";
1504 bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1505 std::vector<uint8_t> compressor_name;
1507 DCHECK(buffer->
reader());
1508 format = buffer->
reader()->type();
1512 const FourCC actual_format = GetActualFormat();
1513 switch (actual_format) {
1516 compressor_name.assign(
1518 kAvcCompressorName + arraysize(kAvcCompressorName));
1522 compressor_name.assign(
1523 kHevcCompressorName,
1524 kHevcCompressorName + arraysize(kHevcCompressorName));
1529 compressor_name.assign(
1531 kVpcCompressorName + arraysize(kVpcCompressorName));
1534 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
1537 compressor_name.resize(kCompressorNameSize);
1540 uint32_t video_resolution = kVideoResolution;
1541 uint16_t video_frame_count = kVideoFrameCount;
1542 uint16_t video_depth = kVideoDepth;
1543 int16_t predefined = -1;
1545 buffer->ReadWriteUInt16(&data_reference_index) &&
1547 buffer->ReadWriteUInt16(&width) &&
1548 buffer->ReadWriteUInt16(&height) &&
1549 buffer->ReadWriteUInt32(&video_resolution) &&
1550 buffer->ReadWriteUInt32(&video_resolution) &&
1552 buffer->ReadWriteUInt16(&video_frame_count) &&
1553 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1554 buffer->ReadWriteUInt16(&video_depth) &&
1555 buffer->ReadWriteInt16(&predefined));
1562 if (format == FOURCC_encv && buffer->
Reading()) {
1565 while (!IsProtectionSchemeSupported(sinf.type.type))
1569 const FourCC actual_format = GetActualFormat();
1571 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1573 DCHECK_EQ(codec_configuration.box_type,
1574 GetCodecConfigurationBoxType(actual_format));
1576 if (codec_configuration.box_type == FOURCC_NULL)
1585 if (format == FOURCC_encv && !buffer->
Reading()) {
1586 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1592 size_t VideoSampleEntry::ComputeSizeInternal() {
1593 const FourCC actual_format = GetActualFormat();
1594 if (actual_format == FOURCC_NULL)
1596 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1597 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1598 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
1599 sizeof(height) +
sizeof(kVideoResolution) * 2 +
1600 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
1602 codec_configuration.
ComputeSize() + kCompressorNameSize + 6 + 4 + 16 +
1606 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format)
const {
1619 LOG(ERROR) << FourCCToString(format) <<
" is not supported.";
1624 ElementaryStreamDescriptor::ElementaryStreamDescriptor() {}
1625 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
1628 bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
1631 std::vector<uint8_t> data;
1632 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1633 RCHECK(es_descriptor.Parse(data));
1634 if (es_descriptor.
IsAAC()) {
1635 RCHECK(aac_audio_specific_config.
Parse(
1636 es_descriptor.decoder_specific_info()));
1639 DCHECK(buffer->
writer());
1640 es_descriptor.Write(buffer->
writer());
1645 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1647 if (es_descriptor.object_type() == kForbidden)
1649 return HeaderSize() + es_descriptor.ComputeSize();
1652 DTSSpecific::DTSSpecific()
1653 : sampling_frequency(0),
1656 pcm_sample_depth(0) {}
1657 DTSSpecific::~DTSSpecific() {}
1660 bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1662 buffer->ReadWriteUInt32(&sampling_frequency) &&
1663 buffer->ReadWriteUInt32(&max_bitrate) &&
1664 buffer->ReadWriteUInt32(&avg_bitrate) &&
1665 buffer->ReadWriteUInt8(&pcm_sample_depth));
1668 RCHECK(buffer->ReadWriteVector(&extra_data, buffer->
BytesLeft()));
1670 if (extra_data.empty()) {
1671 extra_data.assign(kDdtsExtraData,
1672 kDdtsExtraData +
sizeof(kDdtsExtraData));
1674 RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1679 size_t DTSSpecific::ComputeSizeInternal() {
1681 if (sampling_frequency == 0)
1683 return HeaderSize() +
sizeof(sampling_frequency) +
sizeof(max_bitrate) +
1684 sizeof(avg_bitrate) +
sizeof(pcm_sample_depth) +
1685 sizeof(kDdtsExtraData);
1688 AC3Specific::AC3Specific() {}
1689 AC3Specific::~AC3Specific() {}
1693 bool AC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1695 buffer->ReadWriteVector(
1700 size_t AC3Specific::ComputeSizeInternal() {
1707 EC3Specific::EC3Specific() {}
1708 EC3Specific::~EC3Specific() {}
1712 bool EC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1715 RCHECK(buffer->ReadWriteVector(&data, size));
1719 size_t EC3Specific::ComputeSizeInternal() {
1726 OpusSpecific::OpusSpecific() : preskip(0) {}
1727 OpusSpecific::~OpusSpecific() {}
1731 bool OpusSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1734 std::vector<uint8_t> data;
1735 const int kMinOpusSpecificBoxDataSize = 11;
1736 RCHECK(buffer->
BytesLeft() >= kMinOpusSpecificBoxDataSize);
1737 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1738 preskip = data[2] + (data[3] << 8);
1743 writer.AppendInt(FOURCC_Head);
1745 const uint8_t kOpusIdentificationHeaderVersion = 1;
1746 data[0] = kOpusIdentificationHeaderVersion;
1747 writer.AppendVector(data);
1748 writer.SwapBuffer(&opus_identification_header);
1752 const size_t kOpusMagicSignatureSize = 8u;
1753 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1756 const uint8_t kOpusSpecificBoxVersion = 0;
1758 buffer->
writer()->AppendArray(
1759 &opus_identification_header[kOpusMagicSignatureSize + 1],
1760 opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1765 size_t OpusSpecific::ComputeSizeInternal() {
1767 if (opus_identification_header.empty())
1771 const size_t kOpusMagicSignatureSize = 8u;
1772 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1773 return HeaderSize() + opus_identification_header.size() -
1774 kOpusMagicSignatureSize;
1777 AudioSampleEntry::AudioSampleEntry()
1778 : format(FOURCC_NULL),
1779 data_reference_index(1),
1784 AudioSampleEntry::~AudioSampleEntry() {}
1787 if (format == FOURCC_NULL) {
1788 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
1789 <<
"handler type recovered in its Media ancestor.";
1794 bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1796 DCHECK(buffer->
reader());
1797 format = buffer->
reader()->type();
1805 buffer->ReadWriteUInt16(&data_reference_index) &&
1807 buffer->ReadWriteUInt16(&channelcount) &&
1808 buffer->ReadWriteUInt16(&samplesize) &&
1810 buffer->ReadWriteUInt32(&samplerate));
1825 if (format == FOURCC_enca) {
1829 while (!IsProtectionSchemeSupported(sinf.type.type))
1832 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1839 size_t AudioSampleEntry::ComputeSizeInternal() {
1840 if (GetActualFormat() == FOURCC_NULL)
1842 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
1843 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
1850 WebVTTConfigurationBox::WebVTTConfigurationBox() {}
1851 WebVTTConfigurationBox::~WebVTTConfigurationBox() {}
1857 bool WebVTTConfigurationBox::ReadWriteInternal(
BoxBuffer* buffer) {
1864 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
1868 WebVTTSourceLabelBox::WebVTTSourceLabelBox() {}
1869 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() {}
1875 bool WebVTTSourceLabelBox::ReadWriteInternal(
BoxBuffer* buffer) {
1879 : source_label.size());
1882 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
1883 if (source_label.empty())
1888 TextSampleEntry::TextSampleEntry() : format(FOURCC_NULL) {}
1889 TextSampleEntry::~TextSampleEntry() {}
1892 if (format == FOURCC_NULL) {
1893 LOG(ERROR) <<
"TextSampleEntry should be parsed according to the "
1894 <<
"handler type recovered in its Media ancestor.";
1899 bool TextSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1901 DCHECK(buffer->
reader());
1902 format = buffer->
reader()->type();
1907 buffer->ReadWriteUInt16(&data_reference_index));
1909 if (format == FOURCC_wvtt) {
1918 size_t TextSampleEntry::ComputeSizeInternal() {
1920 return HeaderSize() + 6 +
sizeof(data_reference_index) +
1924 MediaHeader::MediaHeader()
1925 : creation_time(0), modification_time(0), timescale(0), duration(0) {}
1926 MediaHeader::~MediaHeader() {}
1929 bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1932 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1935 buffer->ReadWriteUInt32(×cale) &&
1937 language.ReadWrite(buffer) &&
1942 size_t MediaHeader::ComputeSizeInternal() {
1943 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1945 sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
1949 VideoMediaHeader::VideoMediaHeader()
1950 : graphicsmode(0), opcolor_red(0), opcolor_green(0), opcolor_blue(0) {
1951 const uint32_t kVideoMediaHeaderFlags = 1;
1952 flags = kVideoMediaHeaderFlags;
1954 VideoMediaHeader::~VideoMediaHeader() {}
1956 bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1958 buffer->ReadWriteUInt16(&graphicsmode) &&
1959 buffer->ReadWriteUInt16(&opcolor_red) &&
1960 buffer->ReadWriteUInt16(&opcolor_green) &&
1961 buffer->ReadWriteUInt16(&opcolor_blue));
1965 size_t VideoMediaHeader::ComputeSizeInternal() {
1966 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
1967 sizeof(opcolor_green) +
sizeof(opcolor_blue);
1970 SoundMediaHeader::SoundMediaHeader() : balance(0) {}
1971 SoundMediaHeader::~SoundMediaHeader() {}
1973 bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1975 buffer->ReadWriteUInt16(&balance) &&
1980 size_t SoundMediaHeader::ComputeSizeInternal() {
1981 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
1984 SubtitleMediaHeader::SubtitleMediaHeader() {}
1985 SubtitleMediaHeader::~SubtitleMediaHeader() {}
1989 bool SubtitleMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1993 size_t SubtitleMediaHeader::ComputeSizeInternal() {
1997 DataEntryUrl::DataEntryUrl() {
1998 const uint32_t kDataEntryUrlFlags = 1;
1999 flags = kDataEntryUrlFlags;
2001 DataEntryUrl::~DataEntryUrl() {}
2003 bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
2006 RCHECK(buffer->ReadWriteVector(&location, buffer->
BytesLeft()));
2008 RCHECK(buffer->ReadWriteVector(&location, location.size()));
2013 size_t DataEntryUrl::ComputeSizeInternal() {
2017 DataReference::DataReference() {
2019 data_entry.resize(1);
2021 DataReference::~DataReference() {}
2023 bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
2024 uint32_t entry_count =
static_cast<uint32_t
>(data_entry.size());
2026 buffer->ReadWriteUInt32(&entry_count));
2027 data_entry.resize(entry_count);
2029 for (uint32_t i = 0; i < entry_count; ++i)
2034 size_t DataReference::ComputeSizeInternal() {
2035 uint32_t count =
static_cast<uint32_t
>(data_entry.size());
2036 size_t box_size =
HeaderSize() +
sizeof(count);
2037 for (uint32_t i = 0; i < count; ++i)
2042 DataInformation::DataInformation() {}
2043 DataInformation::~DataInformation() {}
2046 bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2052 size_t DataInformation::ComputeSizeInternal() {
2056 MediaInformation::MediaInformation() {}
2057 MediaInformation::~MediaInformation() {}
2060 bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2065 switch (sample_table.description.type) {
2082 size_t MediaInformation::ComputeSizeInternal() {
2085 switch (sample_table.description.type) {
2105 bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
2117 information.sample_table.description.type =
2118 FourCCToTrackType(handler.handler_type);
2120 handler.handler_type =
2121 TrackTypeToFourCC(information.sample_table.description.type);
2122 RCHECK(handler.handler_type != FOURCC_NULL);
2129 size_t Media::ComputeSizeInternal() {
2130 handler.handler_type =
2131 TrackTypeToFourCC(information.sample_table.description.type);
2140 bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
2150 size_t Track::ComputeSizeInternal() {
2155 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
2156 MovieExtendsHeader::~MovieExtendsHeader() {}
2159 bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2161 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2166 size_t MovieExtendsHeader::ComputeSizeInternal() {
2168 if (fragment_duration == 0)
2170 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2171 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2174 TrackExtends::TrackExtends()
2176 default_sample_description_index(0),
2177 default_sample_duration(0),
2178 default_sample_size(0),
2179 default_sample_flags(0) {}
2180 TrackExtends::~TrackExtends() {}
2183 bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2185 buffer->ReadWriteUInt32(&track_id) &&
2186 buffer->ReadWriteUInt32(&default_sample_description_index) &&
2187 buffer->ReadWriteUInt32(&default_sample_duration) &&
2188 buffer->ReadWriteUInt32(&default_sample_size) &&
2189 buffer->ReadWriteUInt32(&default_sample_flags));
2193 size_t TrackExtends::ComputeSizeInternal() {
2195 sizeof(default_sample_description_index) +
2196 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
2197 sizeof(default_sample_flags);
2200 MovieExtends::MovieExtends() {}
2201 MovieExtends::~MovieExtends() {}
2204 bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2209 DCHECK(buffer->
reader());
2212 for (uint32_t i = 0; i < tracks.size(); ++i)
2218 size_t MovieExtends::ComputeSizeInternal() {
2220 if (tracks.size() == 0)
2223 for (uint32_t i = 0; i < tracks.size(); ++i)
2232 bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
2244 for (uint32_t i = 0; i < tracks.size(); ++i)
2247 for (uint32_t i = 0; i < pssh.size(); ++i)
2253 size_t Movie::ComputeSizeInternal() {
2256 for (uint32_t i = 0; i < tracks.size(); ++i)
2258 for (uint32_t i = 0; i < pssh.size(); ++i)
2263 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
2264 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
2267 bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
2269 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2274 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2275 version = IsFitIn32Bits(decode_time) ? 0 : 1;
2276 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2279 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
2280 MovieFragmentHeader::~MovieFragmentHeader() {}
2283 bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2285 buffer->ReadWriteUInt32(&sequence_number);
2288 size_t MovieFragmentHeader::ComputeSizeInternal() {
2289 return HeaderSize() +
sizeof(sequence_number);
2292 TrackFragmentHeader::TrackFragmentHeader()
2294 sample_description_index(0),
2295 default_sample_duration(0),
2296 default_sample_size(0),
2297 default_sample_flags(0) {}
2299 TrackFragmentHeader::~TrackFragmentHeader() {}
2302 bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2304 buffer->ReadWriteUInt32(&track_id));
2306 if (flags & kBaseDataOffsetPresentMask) {
2311 uint64_t base_data_offset;
2312 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2313 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
2314 "default-base-is-moof.";
2317 if (flags & kSampleDescriptionIndexPresentMask) {
2318 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2319 }
else if (buffer->
Reading()) {
2320 sample_description_index = 0;
2323 if (flags & kDefaultSampleDurationPresentMask) {
2324 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2325 }
else if (buffer->
Reading()) {
2326 default_sample_duration = 0;
2329 if (flags & kDefaultSampleSizePresentMask) {
2330 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2331 }
else if (buffer->
Reading()) {
2332 default_sample_size = 0;
2335 if (flags & kDefaultSampleFlagsPresentMask)
2336 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2340 size_t TrackFragmentHeader::ComputeSizeInternal() {
2341 size_t box_size =
HeaderSize() +
sizeof(track_id);
2342 if (flags & kSampleDescriptionIndexPresentMask)
2343 box_size +=
sizeof(sample_description_index);
2344 if (flags & kDefaultSampleDurationPresentMask)
2345 box_size +=
sizeof(default_sample_duration);
2346 if (flags & kDefaultSampleSizePresentMask)
2347 box_size +=
sizeof(default_sample_size);
2348 if (flags & kDefaultSampleFlagsPresentMask)
2349 box_size +=
sizeof(default_sample_flags);
2353 TrackFragmentRun::TrackFragmentRun() : sample_count(0), data_offset(0) {}
2354 TrackFragmentRun::~TrackFragmentRun() {}
2357 bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
2363 if (flags & kSampleCompTimeOffsetsPresentMask) {
2364 for (uint32_t i = 0; i < sample_count; ++i) {
2365 if (sample_composition_time_offsets[i] < 0) {
2374 buffer->ReadWriteUInt32(&sample_count));
2376 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2377 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2378 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2379 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2380 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2381 bool sample_composition_time_offsets_present =
2382 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2384 if (data_offset_present) {
2385 RCHECK(buffer->ReadWriteUInt32(&data_offset));
2396 uint32_t first_sample_flags(0);
2399 if (first_sample_flags_present)
2400 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2402 if (sample_duration_present)
2403 sample_durations.resize(sample_count);
2404 if (sample_size_present)
2405 sample_sizes.resize(sample_count);
2406 if (sample_flags_present)
2407 sample_flags.resize(sample_count);
2408 if (sample_composition_time_offsets_present)
2409 sample_composition_time_offsets.resize(sample_count);
2411 if (first_sample_flags_present) {
2412 first_sample_flags = sample_flags[0];
2413 DCHECK(sample_flags.size() == 1);
2414 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2417 if (sample_duration_present)
2418 DCHECK(sample_durations.size() == sample_count);
2419 if (sample_size_present)
2420 DCHECK(sample_sizes.size() == sample_count);
2421 if (sample_flags_present)
2422 DCHECK(sample_flags.size() == sample_count);
2423 if (sample_composition_time_offsets_present)
2424 DCHECK(sample_composition_time_offsets.size() == sample_count);
2427 for (uint32_t i = 0; i < sample_count; ++i) {
2428 if (sample_duration_present)
2429 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2430 if (sample_size_present)
2431 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2432 if (sample_flags_present)
2433 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2435 if (sample_composition_time_offsets_present) {
2437 uint32_t sample_offset = sample_composition_time_offsets[i];
2438 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2439 sample_composition_time_offsets[i] = sample_offset;
2441 int32_t sample_offset = sample_composition_time_offsets[i];
2442 RCHECK(buffer->ReadWriteInt32(&sample_offset));
2443 sample_composition_time_offsets[i] = sample_offset;
2449 if (first_sample_flags_present) {
2450 if (sample_flags.size() == 0) {
2451 sample_flags.push_back(first_sample_flags);
2453 sample_flags[0] = first_sample_flags;
2460 size_t TrackFragmentRun::ComputeSizeInternal() {
2461 size_t box_size =
HeaderSize() +
sizeof(sample_count);
2462 if (flags & kDataOffsetPresentMask)
2463 box_size +=
sizeof(data_offset);
2464 if (flags & kFirstSampleFlagsPresentMask)
2465 box_size +=
sizeof(uint32_t);
2466 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2467 (flags & kSampleSizePresentMask ? 1 : 0) +
2468 (flags & kSampleFlagsPresentMask ? 1 : 0) +
2469 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2470 box_size += fields *
sizeof(uint32_t) * sample_count;
2474 TrackFragment::TrackFragment() : decode_time_absent(false) {}
2475 TrackFragment::~TrackFragment() {}
2478 bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2483 DCHECK(buffer->
reader());
2485 if (!decode_time_absent)
2491 if (!decode_time_absent)
2493 for (uint32_t i = 0; i < runs.size(); ++i)
2495 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2497 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2505 size_t TrackFragment::ComputeSizeInternal() {
2510 for (uint32_t i = 0; i < runs.size(); ++i)
2512 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2513 box_size += sample_group_descriptions[i].
ComputeSize();
2514 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2519 MovieFragment::MovieFragment() {}
2520 MovieFragment::~MovieFragment() {}
2523 bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2533 for (uint32_t i = 0; i < tracks.size(); ++i)
2535 for (uint32_t i = 0; i < pssh.size(); ++i)
2541 size_t MovieFragment::ComputeSizeInternal() {
2543 for (uint32_t i = 0; i < tracks.size(); ++i)
2545 for (uint32_t i = 0; i < pssh.size(); ++i)
2550 SegmentIndex::SegmentIndex()
2553 earliest_presentation_time(0),
2555 SegmentIndex::~SegmentIndex() {}
2558 bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
2560 buffer->ReadWriteUInt32(&reference_id) &&
2561 buffer->ReadWriteUInt32(×cale));
2563 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2568 uint16_t reference_count =
static_cast<uint16_t
>(references.size());
2570 buffer->ReadWriteUInt16(&reference_count));
2571 references.resize(reference_count);
2573 uint32_t reference_type_size;
2575 for (uint32_t i = 0; i < reference_count; ++i) {
2577 reference_type_size = references[i].referenced_size;
2578 if (references[i].reference_type)
2579 reference_type_size |= (1 << 31);
2580 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2581 if (references[i].starts_with_sap)
2584 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2585 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2586 buffer->ReadWriteUInt32(&sap));
2588 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
2589 references[i].referenced_size = reference_type_size & ~(1 << 31);
2590 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
2591 references[i].sap_type =
2592 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
2593 references[i].sap_delta_time = sap & ~(0xF << 28);
2599 size_t SegmentIndex::ComputeSizeInternal() {
2600 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2601 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
2602 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
2603 3 *
sizeof(uint32_t) * references.size();
2606 MediaData::MediaData() : data_size(0) {}
2607 MediaData::~MediaData() {}
2610 bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
2611 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
2615 size_t MediaData::ComputeSizeInternal() {
2619 CueSourceIDBox::CueSourceIDBox() : source_id(kCueSourceIdNotSet) {}
2620 CueSourceIDBox::~CueSourceIDBox() {}
2624 bool CueSourceIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2629 size_t CueSourceIDBox::ComputeSizeInternal() {
2630 if (source_id == kCueSourceIdNotSet)
2635 CueTimeBox::CueTimeBox() {}
2636 CueTimeBox::~CueTimeBox() {}
2642 bool CueTimeBox::ReadWriteInternal(
BoxBuffer* buffer) {
2649 size_t CueTimeBox::ComputeSizeInternal() {
2650 if (cue_current_time.empty())
2652 return HeaderSize() + cue_current_time.size();
2655 CueIDBox::CueIDBox() {}
2656 CueIDBox::~CueIDBox() {}
2662 bool CueIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2668 size_t CueIDBox::ComputeSizeInternal() {
2674 CueSettingsBox::CueSettingsBox() {}
2675 CueSettingsBox::~CueSettingsBox() {}
2681 bool CueSettingsBox::ReadWriteInternal(
BoxBuffer* buffer) {
2687 size_t CueSettingsBox::ComputeSizeInternal() {
2688 if (settings.empty())
2693 CuePayloadBox::CuePayloadBox() {}
2694 CuePayloadBox::~CuePayloadBox() {}
2700 bool CuePayloadBox::ReadWriteInternal(
BoxBuffer* buffer) {
2706 size_t CuePayloadBox::ComputeSizeInternal() {
2710 VTTEmptyCueBox::VTTEmptyCueBox() {}
2711 VTTEmptyCueBox::~VTTEmptyCueBox() {}
2717 bool VTTEmptyCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2721 size_t VTTEmptyCueBox::ComputeSizeInternal() {
2725 VTTAdditionalTextBox::VTTAdditionalTextBox() {}
2726 VTTAdditionalTextBox::~VTTAdditionalTextBox() {}
2732 bool VTTAdditionalTextBox::ReadWriteInternal(
BoxBuffer* buffer) {
2735 &cue_additional_text,
2739 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
2740 return HeaderSize() + cue_additional_text.size();
2743 VTTCueBox::VTTCueBox() {}
2744 VTTCueBox::~VTTCueBox() {}
2750 bool VTTCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2761 size_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