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 bool IsFitIn32Bits(uint64_t a) {
72 return a <= std::numeric_limits<uint32_t>::max();
75 bool IsFitIn32Bits(int64_t a) {
76 return a <= std::numeric_limits<int32_t>::max() &&
77 a >= std::numeric_limits<int32_t>::min();
80 template <
typename T1,
typename T2>
81 bool IsFitIn32Bits(T1 a1, T2 a2) {
82 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
85 template <
typename T1,
typename T2,
typename T3>
86 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
87 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
98 TrackType FourCCToTrackType(FourCC fourcc) {
111 FourCC TrackTypeToFourCC(TrackType track_type) {
112 switch (track_type) {
124 bool IsProtectionSchemeSupported(FourCC scheme) {
125 return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
126 scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
131 FileType::FileType() : major_brand(FOURCC_NULL), minor_version(0) {}
132 FileType::~FileType() {}
135 bool FileType::ReadWriteInternal(
BoxBuffer* buffer) {
136 RCHECK(ReadWriteHeaderInternal(buffer) &&
137 buffer->ReadWriteFourCC(&major_brand) &&
138 buffer->ReadWriteUInt32(&minor_version));
141 RCHECK(buffer->
BytesLeft() %
sizeof(FourCC) == 0);
142 num_brands = buffer->
BytesLeft() /
sizeof(FourCC);
143 compatible_brands.resize(num_brands);
145 num_brands = compatible_brands.size();
147 for (
size_t i = 0; i < num_brands; ++i)
148 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
152 size_t FileType::ComputeSizeInternal() {
153 return HeaderSize() + kFourCCSize +
sizeof(minor_version) +
154 kFourCCSize * compatible_brands.size();
159 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
160 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
163 bool ProtectionSystemSpecificHeader::ReadWriteInternal(
BoxBuffer* buffer) {
167 raw_box.assign(reader->data(), reader->data() + reader->size());
169 DCHECK(!raw_box.empty());
170 buffer->
writer()->AppendVector(raw_box);
176 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
177 return raw_box.size();
180 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
181 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
184 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
185 RCHECK(ReadWriteHeaderInternal(buffer));
189 uint32_t count =
static_cast<uint32_t
>(offsets.size());
190 RCHECK(buffer->ReadWriteUInt32(&count));
191 offsets.resize(count);
193 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
194 for (uint32_t i = 0; i < count; ++i)
199 size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
201 if (offsets.size() == 0)
203 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
204 return HeaderSize() +
sizeof(uint32_t) + num_bytes * offsets.size();
207 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
208 : default_sample_info_size(0), sample_count(0) {}
209 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
212 bool SampleAuxiliaryInformationSize::ReadWriteInternal(
BoxBuffer* buffer) {
213 RCHECK(ReadWriteHeaderInternal(buffer));
217 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
218 buffer->ReadWriteUInt32(&sample_count));
219 if (default_sample_info_size == 0)
220 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
224 size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
226 if (sample_count == 0)
228 return HeaderSize() +
sizeof(default_sample_info_size) +
229 sizeof(sample_count) +
230 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
233 SampleEncryptionEntry::SampleEncryptionEntry() {}
234 SampleEncryptionEntry::~SampleEncryptionEntry() {}
239 DCHECK(IsIvSizeValid(iv_size));
242 RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
244 if (!has_subsamples) {
249 uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
250 RCHECK(buffer->ReadWriteUInt16(&subsample_count));
251 RCHECK(subsample_count > 0);
252 subsamples.resize(subsample_count);
253 for (
auto& subsample : subsamples) {
254 RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
255 buffer->ReadWriteUInt32(&subsample.cipher_bytes));
263 DCHECK(IsIvSizeValid(iv_size));
266 initialization_vector.resize(iv_size);
267 RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
269 if (!has_subsamples) {
274 uint16_t subsample_count;
275 RCHECK(reader->Read2(&subsample_count));
276 RCHECK(subsample_count > 0);
277 subsamples.resize(subsample_count);
278 for (
auto& subsample : subsamples) {
279 RCHECK(reader->Read2(&subsample.clear_bytes) &&
280 reader->Read4(&subsample.cipher_bytes));
286 const uint32_t subsample_entry_size =
sizeof(uint16_t) +
sizeof(uint32_t);
287 const uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
288 return static_cast<uint32_t
>(
289 initialization_vector.size() +
291 ? (
sizeof(subsample_count) + subsample_entry_size * subsample_count)
297 for (uint32_t i = 0; i < subsamples.size(); ++i)
298 size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
302 SampleEncryption::SampleEncryption() : iv_size(kInvalidIvSize) {}
303 SampleEncryption::~SampleEncryption() {}
306 bool SampleEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
307 RCHECK(ReadWriteHeaderInternal(buffer));
311 if (buffer->
Reading() && iv_size == kInvalidIvSize) {
313 buffer->ReadWriteVector(&sample_encryption_data, buffer->
BytesLeft()));
317 if (!IsIvSizeValid(iv_size)) {
319 <<
"IV_size can only be 8 or 16 or 0 for constant iv, but seeing " 324 uint32_t sample_count =
325 static_cast<uint32_t
>(sample_encryption_entries.size());
326 RCHECK(buffer->ReadWriteUInt32(&sample_count));
328 sample_encryption_entries.resize(sample_count);
329 for (
auto& sample_encryption_entry : sample_encryption_entries) {
330 RCHECK(sample_encryption_entry.ReadWrite(
331 iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
336 size_t SampleEncryption::ComputeSizeInternal() {
337 const uint32_t sample_count =
338 static_cast<uint32_t
>(sample_encryption_entries.size());
339 if (sample_count == 0) {
344 DCHECK(IsIvSizeValid(iv_size));
345 size_t box_size = HeaderSize() +
sizeof(sample_count);
346 if (flags & kUseSubsampleEncryption) {
348 sample_encryption_entries) {
349 box_size += sample_encryption_entry.ComputeSize();
352 box_size += sample_count * iv_size;
359 std::vector<SampleEncryptionEntry>* sample_encryption_entries)
const {
360 DCHECK(IsIvSizeValid(iv_size));
363 sample_encryption_data.size());
364 uint32_t sample_count = 0;
365 RCHECK(
reader.Read4(&sample_count));
367 sample_encryption_entries->resize(sample_count);
368 for (
auto& sample_encryption_entry : *sample_encryption_entries) {
369 RCHECK(sample_encryption_entry.ParseFromBuffer(
370 iv_size, (flags & kUseSubsampleEncryption) != 0, &
reader) != 0);
375 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
376 OriginalFormat::~OriginalFormat() {}
379 bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
380 return ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&format);
383 size_t OriginalFormat::ComputeSizeInternal() {
384 return HeaderSize() + kFourCCSize;
387 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
388 SchemeType::~SchemeType() {}
391 bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
392 RCHECK(ReadWriteHeaderInternal(buffer) &&
393 buffer->ReadWriteFourCC(&type) &&
394 buffer->ReadWriteUInt32(&version));
398 size_t SchemeType::ComputeSizeInternal() {
399 return HeaderSize() + kFourCCSize +
sizeof(version);
402 TrackEncryption::TrackEncryption()
403 : default_is_protected(0),
404 default_per_sample_iv_size(0),
406 default_crypt_byte_block(0),
407 default_skip_byte_block(0) {}
408 TrackEncryption::~TrackEncryption() {}
411 bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
413 if (default_kid.size() != kCencKeyIdSize) {
414 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
415 <<
" bytes; got " << default_kid.size()
416 <<
". Resized accordingly.";
417 default_kid.resize(kCencKeyIdSize);
419 RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
420 if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
426 RCHECK(ReadWriteHeaderInternal(buffer) &&
429 uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
430 RCHECK(buffer->ReadWriteUInt8(&pattern));
431 default_crypt_byte_block = pattern >> 4;
432 default_skip_byte_block = pattern & 0x0F;
434 RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
435 buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
436 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
438 if (default_is_protected == 1) {
439 if (default_per_sample_iv_size == 0) {
440 uint8_t default_constant_iv_size =
441 static_cast<uint8_t
>(default_constant_iv.size());
442 RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
443 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
444 RCHECK(buffer->ReadWriteVector(&default_constant_iv,
445 default_constant_iv_size));
447 RCHECK(default_per_sample_iv_size == 8 ||
448 default_per_sample_iv_size == 16);
449 RCHECK(default_constant_iv.empty());
454 RCHECK(default_is_protected == 0);
455 RCHECK(default_per_sample_iv_size == 0);
456 RCHECK(default_constant_iv.empty());
461 size_t TrackEncryption::ComputeSizeInternal() {
462 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize +
463 (default_constant_iv.empty() ? 0 : (
sizeof(uint8_t) +
464 default_constant_iv.size()));
467 SchemeInfo::SchemeInfo() {}
468 SchemeInfo::~SchemeInfo() {}
471 bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
477 size_t SchemeInfo::ComputeSizeInternal() {
478 return HeaderSize() + track_encryption.ComputeSize();
481 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
482 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
485 bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
486 RCHECK(ReadWriteHeaderInternal(buffer) &&
490 if (IsProtectionSchemeSupported(type.type)) {
493 DLOG(WARNING) <<
"Ignore unsupported protection scheme: " 494 << FourCCToString(type.type);
503 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
505 if (format.format == FOURCC_NULL)
507 return HeaderSize() + format.ComputeSize() + type.ComputeSize() +
511 MovieHeader::MovieHeader()
513 modification_time(0),
519 MovieHeader::~MovieHeader() {}
522 bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
523 RCHECK(ReadWriteHeaderInternal(buffer));
525 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
528 buffer->ReadWriteUInt32(×cale) &&
531 std::vector<uint8_t> matrix(kUnityMatrix,
532 kUnityMatrix + arraysize(kUnityMatrix));
533 RCHECK(buffer->ReadWriteInt32(&rate) &&
534 buffer->ReadWriteInt16(&volume) &&
536 buffer->ReadWriteVector(&matrix, matrix.size()) &&
538 buffer->ReadWriteUInt32(&next_track_id));
542 size_t MovieHeader::ComputeSizeInternal() {
543 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
544 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
545 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
546 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
550 TrackHeader::TrackHeader()
552 modification_time(0),
560 flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
562 TrackHeader::~TrackHeader() {}
565 bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
566 RCHECK(ReadWriteHeaderInternal(buffer));
568 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
571 buffer->ReadWriteUInt32(&track_id) &&
578 volume = (width != 0 && height != 0) ? 0 : 0x100;
580 std::vector<uint8_t> matrix(kUnityMatrix,
581 kUnityMatrix + arraysize(kUnityMatrix));
583 buffer->ReadWriteInt16(&layer) &&
584 buffer->ReadWriteInt16(&alternate_group) &&
585 buffer->ReadWriteInt16(&volume) &&
587 buffer->ReadWriteVector(&matrix, matrix.size()) &&
588 buffer->ReadWriteUInt32(&width) &&
589 buffer->ReadWriteUInt32(&height));
593 size_t TrackHeader::ComputeSizeInternal() {
594 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
595 return HeaderSize() +
sizeof(track_id) +
596 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
597 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
598 sizeof(height) +
sizeof(kUnityMatrix) + 14;
601 SampleDescription::SampleDescription() : type(kInvalid) {}
602 SampleDescription::~SampleDescription() {}
605 bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
609 count =
static_cast<uint32_t
>(video_entries.size());
612 count =
static_cast<uint32_t
>(audio_entries.size());
615 count =
static_cast<uint32_t
>(text_entries.size());
618 NOTIMPLEMENTED() <<
"SampleDecryption type " << type
619 <<
" is not handled. Skipping.";
621 RCHECK(ReadWriteHeaderInternal(buffer) &&
622 buffer->ReadWriteUInt32(&count));
627 video_entries.clear();
628 audio_entries.clear();
631 if (type == kVideo) {
633 RCHECK(video_entries.size() == count);
634 }
else if (type == kAudio) {
636 RCHECK(audio_entries.size() == count);
637 }
else if (type == kText) {
639 RCHECK(text_entries.size() == count);
642 DCHECK_LT(0u, count);
643 if (type == kVideo) {
644 for (uint32_t i = 0; i < count; ++i)
646 }
else if (type == kAudio) {
647 for (uint32_t i = 0; i < count; ++i)
649 }
else if (type == kText) {
650 for (uint32_t i = 0; i < count; ++i)
659 size_t SampleDescription::ComputeSizeInternal() {
660 size_t box_size = HeaderSize() +
sizeof(uint32_t);
661 if (type == kVideo) {
662 for (uint32_t i = 0; i < video_entries.size(); ++i)
663 box_size += video_entries[i].ComputeSize();
664 }
else if (type == kAudio) {
665 for (uint32_t i = 0; i < audio_entries.size(); ++i)
666 box_size += audio_entries[i].ComputeSize();
667 }
else if (type == kText) {
668 for (uint32_t i = 0; i < text_entries.size(); ++i)
669 box_size += text_entries[i].ComputeSize();
674 DecodingTimeToSample::DecodingTimeToSample() {}
675 DecodingTimeToSample::~DecodingTimeToSample() {}
678 bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
679 uint32_t count =
static_cast<uint32_t
>(decoding_time.size());
680 RCHECK(ReadWriteHeaderInternal(buffer) &&
681 buffer->ReadWriteUInt32(&count));
683 decoding_time.resize(count);
684 for (uint32_t i = 0; i < count; ++i) {
685 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
686 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
691 size_t DecodingTimeToSample::ComputeSizeInternal() {
692 return HeaderSize() +
sizeof(uint32_t) +
696 CompositionTimeToSample::CompositionTimeToSample() {}
697 CompositionTimeToSample::~CompositionTimeToSample() {}
700 bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
701 uint32_t count =
static_cast<uint32_t
>(composition_offset.size());
707 for (uint32_t i = 0; i < count; ++i) {
708 if (composition_offset[i].sample_offset < 0) {
715 RCHECK(ReadWriteHeaderInternal(buffer) &&
716 buffer->ReadWriteUInt32(&count));
718 composition_offset.resize(count);
719 for (uint32_t i = 0; i < count; ++i) {
720 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
723 uint32_t sample_offset = composition_offset[i].sample_offset;
724 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
725 composition_offset[i].sample_offset = sample_offset;
727 int32_t sample_offset = composition_offset[i].sample_offset;
728 RCHECK(buffer->ReadWriteInt32(&sample_offset));
729 composition_offset[i].sample_offset = sample_offset;
735 size_t CompositionTimeToSample::ComputeSizeInternal() {
737 if (composition_offset.empty())
742 const size_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
743 return HeaderSize() +
sizeof(uint32_t) +
744 kCompositionOffsetSize * composition_offset.size();
747 SampleToChunk::SampleToChunk() {}
748 SampleToChunk::~SampleToChunk() {}
751 bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
752 uint32_t count =
static_cast<uint32_t
>(chunk_info.size());
753 RCHECK(ReadWriteHeaderInternal(buffer) &&
754 buffer->ReadWriteUInt32(&count));
756 chunk_info.resize(count);
757 for (uint32_t i = 0; i < count; ++i) {
758 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
759 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
760 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
762 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
763 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
768 size_t SampleToChunk::ComputeSizeInternal() {
769 return HeaderSize() +
sizeof(uint32_t) +
773 SampleSize::SampleSize() : sample_size(0), sample_count(0) {}
774 SampleSize::~SampleSize() {}
777 bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
778 RCHECK(ReadWriteHeaderInternal(buffer) &&
779 buffer->ReadWriteUInt32(&sample_size) &&
780 buffer->ReadWriteUInt32(&sample_count));
782 if (sample_size == 0) {
784 sizes.resize(sample_count);
786 DCHECK(sample_count == sizes.size());
787 for (uint32_t i = 0; i < sample_count; ++i)
788 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
793 size_t SampleSize::ComputeSizeInternal() {
794 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
795 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
798 CompactSampleSize::CompactSampleSize() : field_size(0) {}
799 CompactSampleSize::~CompactSampleSize() {}
802 bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
803 uint32_t sample_count =
static_cast<uint32_t
>(sizes.size());
804 RCHECK(ReadWriteHeaderInternal(buffer) &&
806 buffer->ReadWriteUInt8(&field_size) &&
807 buffer->ReadWriteUInt32(&sample_count));
810 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
811 switch (field_size) {
813 for (uint32_t i = 0; i < sample_count; i += 2) {
816 RCHECK(buffer->ReadWriteUInt8(&size));
817 sizes[i] = size >> 4;
818 sizes[i + 1] = size & 0x0F;
820 DCHECK_LT(sizes[i], 16u);
821 DCHECK_LT(sizes[i + 1], 16u);
822 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
823 RCHECK(buffer->ReadWriteUInt8(&size));
828 for (uint32_t i = 0; i < sample_count; ++i) {
829 uint8_t size = sizes[i];
830 RCHECK(buffer->ReadWriteUInt8(&size));
835 for (uint32_t i = 0; i < sample_count; ++i) {
836 uint16_t size = sizes[i];
837 RCHECK(buffer->ReadWriteUInt16(&size));
844 sizes.resize(sample_count);
848 size_t CompactSampleSize::ComputeSizeInternal() {
849 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
850 (field_size * sizes.size() + 7) / 8;
853 ChunkOffset::ChunkOffset() {}
854 ChunkOffset::~ChunkOffset() {}
857 bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
858 uint32_t count =
static_cast<uint32_t
>(offsets.size());
859 RCHECK(ReadWriteHeaderInternal(buffer) &&
860 buffer->ReadWriteUInt32(&count));
862 offsets.resize(count);
863 for (uint32_t i = 0; i < count; ++i)
868 size_t ChunkOffset::ComputeSizeInternal() {
869 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
872 ChunkLargeOffset::ChunkLargeOffset() {}
873 ChunkLargeOffset::~ChunkLargeOffset() {}
876 bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
877 uint32_t count =
static_cast<uint32_t
>(offsets.size());
881 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
883 stco.offsets.swap(offsets);
886 stco.offsets.swap(offsets);
891 RCHECK(ReadWriteHeaderInternal(buffer) &&
892 buffer->ReadWriteUInt32(&count));
894 offsets.resize(count);
895 for (uint32_t i = 0; i < count; ++i)
896 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
900 size_t ChunkLargeOffset::ComputeSizeInternal() {
901 uint32_t count =
static_cast<uint32_t
>(offsets.size());
902 int use_large_offset =
903 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
904 return HeaderSize() +
sizeof(count) +
905 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
908 SyncSample::SyncSample() {}
909 SyncSample::~SyncSample() {}
912 bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
913 uint32_t count =
static_cast<uint32_t
>(sample_number.size());
914 RCHECK(ReadWriteHeaderInternal(buffer) &&
915 buffer->ReadWriteUInt32(&count));
917 sample_number.resize(count);
918 for (uint32_t i = 0; i < count; ++i)
919 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
923 size_t SyncSample::ComputeSizeInternal() {
925 if (sample_number.empty())
927 return HeaderSize() +
sizeof(uint32_t) +
928 sizeof(uint32_t) * sample_number.size();
931 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
933 per_sample_iv_size(0),
935 skip_byte_block(0) {}
936 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {};
938 bool CencSampleEncryptionInfoEntry::ReadWrite(
BoxBuffer* buffer) {
940 if (key_id.size() != kCencKeyIdSize) {
941 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
942 <<
" bytes; got " << key_id.size()
943 <<
". Resized accordingly.";
944 key_id.resize(kCencKeyIdSize);
946 RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
951 uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
952 RCHECK(buffer->ReadWriteUInt8(&pattern));
953 crypt_byte_block = pattern >> 4;
954 skip_byte_block = pattern & 0x0F;
956 RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
957 buffer->ReadWriteUInt8(&per_sample_iv_size) &&
958 buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
960 if (is_protected == 1) {
961 if (per_sample_iv_size == 0) {
962 uint8_t constant_iv_size =
static_cast<uint8_t
>(constant_iv.size());
963 RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
964 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
965 RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
967 RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
968 DCHECK(constant_iv.empty());
973 RCHECK(is_protected == 0);
974 RCHECK(per_sample_iv_size == 0);
979 uint32_t CencSampleEncryptionInfoEntry::ComputeSize()
const {
980 return static_cast<uint32_t
>(
981 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) {
1002 RCHECK(ReadWriteHeaderInternal(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;
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 =
static_cast<uint32_t
>(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 size_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) {
1081 RCHECK(ReadWriteHeaderInternal(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 =
static_cast<uint32_t
>(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 size_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) {
1117 RCHECK(ReadWriteHeaderInternal(buffer) &&
1130 RCHECK(reader->
ReadChild(&sample_size));
1133 RCHECK(reader->
ReadChild(&compact_sample_size));
1134 sample_size.sample_size = 0;
1135 sample_size.sample_count =
1136 static_cast<uint32_t
>(compact_sample_size.sizes.size());
1137 sample_size.sizes.swap(compact_sample_size.sizes);
1141 if (reader->
ChildExist(&chunk_large_offset)) {
1142 RCHECK(reader->
ReadChild(&chunk_large_offset));
1145 RCHECK(reader->
ReadChild(&chunk_offset));
1146 chunk_large_offset.offsets.swap(chunk_offset.offsets);
1157 for (
auto& sample_group_description : sample_group_descriptions)
1159 for (
auto& sample_to_group : sample_to_groups)
1165 size_t SampleTable::ComputeSizeInternal() {
1166 size_t box_size = HeaderSize() + description.ComputeSize() +
1167 decoding_time_to_sample.ComputeSize() +
1168 composition_time_to_sample.ComputeSize() +
1169 sample_to_chunk.ComputeSize() + sample_size.ComputeSize() +
1170 chunk_large_offset.ComputeSize() +
1171 sync_sample.ComputeSize();
1172 for (
auto& sample_group_description : sample_group_descriptions)
1173 box_size += sample_group_description.ComputeSize();
1174 for (
auto& sample_to_group : sample_to_groups)
1175 box_size += sample_to_group.ComputeSize();
1179 EditList::EditList() {}
1180 EditList::~EditList() {}
1183 bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
1184 uint32_t count =
static_cast<uint32_t
>(edits.size());
1185 RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
1186 edits.resize(count);
1188 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1189 for (uint32_t i = 0; i < count; ++i) {
1192 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1193 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1194 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1199 size_t EditList::ComputeSizeInternal() {
1205 for (uint32_t i = 0; i < edits.size(); ++i) {
1206 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1211 return HeaderSize() +
sizeof(uint32_t) +
1212 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
1220 bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
1221 return ReadWriteHeaderInternal(buffer) &&
1226 size_t Edit::ComputeSizeInternal() {
1228 if (list.edits.empty())
1230 return HeaderSize() + list.ComputeSize();
1233 HandlerReference::HandlerReference() : handler_type(FOURCC_NULL) {}
1234 HandlerReference::~HandlerReference() {}
1237 bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
1238 std::vector<uint8_t> handler_name;
1240 switch (handler_type) {
1242 handler_name.assign(kVideoHandlerName,
1243 kVideoHandlerName + arraysize(kVideoHandlerName));
1246 handler_name.assign(kAudioHandlerName,
1247 kAudioHandlerName + arraysize(kAudioHandlerName));
1250 handler_name.assign(kTextHandlerName,
1251 kTextHandlerName + arraysize(kTextHandlerName));
1260 RCHECK(ReadWriteHeaderInternal(buffer) &&
1262 buffer->ReadWriteFourCC(&handler_type));
1265 buffer->ReadWriteVector(&handler_name, handler_name.size()));
1270 size_t HandlerReference::ComputeSizeInternal() {
1271 size_t box_size = HeaderSize() + kFourCCSize + 16;
1272 switch (handler_type) {
1274 box_size +=
sizeof(kVideoHandlerName);
1277 box_size +=
sizeof(kAudioHandlerName);
1280 box_size +=
sizeof(kTextHandlerName);
1290 bool Language::ReadWrite(
BoxBuffer* buffer) {
1294 std::vector<uint8_t> temp;
1295 RCHECK(buffer->ReadWriteVector(&temp, 2));
1298 bit_reader.SkipBits(1);
1300 for (
int i = 0; i < 3; ++i) {
1301 CHECK(bit_reader.ReadBits(5, &language[i]));
1302 language[i] += 0x60;
1304 code.assign(language, 3);
1307 const char kUndefinedLanguage[] =
"und";
1309 code = kUndefinedLanguage;
1310 DCHECK_EQ(code.size(), 3u);
1314 for (
int i = 0; i < 3; ++i)
1315 lang |= (code[i] - 0x60) << ((2 - i) * 5);
1316 RCHECK(buffer->ReadWriteUInt16(&lang));
1321 uint32_t Language::ComputeSize()
const {
1331 bool ID3v2::ReadWriteInternal(
BoxBuffer* buffer) {
1332 RCHECK(ReadWriteHeaderInternal(buffer) && language.ReadWrite(buffer) &&
1333 buffer->ReadWriteVector(&id3v2_data, buffer->
Reading()
1335 : id3v2_data.size()));
1339 size_t ID3v2::ComputeSizeInternal() {
1341 return id3v2_data.size() == 0
1343 : HeaderSize() + language.ComputeSize() + id3v2_data.size();
1346 Metadata::Metadata() {}
1347 Metadata::~Metadata() {}
1353 bool Metadata::ReadWriteInternal(
BoxBuffer* buffer) {
1354 RCHECK(ReadWriteHeaderInternal(buffer) &&
1361 size_t Metadata::ComputeSizeInternal() {
1362 size_t id3v2_size = id3v2.ComputeSize();
1364 return id3v2_size == 0 ? 0
1365 : HeaderSize() + handler.ComputeSize() + id3v2_size;
1368 CodecConfiguration::CodecConfiguration() : box_type(FOURCC_NULL) {}
1369 CodecConfiguration::~CodecConfiguration() {}
1377 bool CodecConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1378 DCHECK_NE(box_type, FOURCC_NULL);
1379 RCHECK(ReadWriteHeaderInternal(buffer));
1383 if (box_type == FOURCC_vpcC) {
1385 uint8_t vpcc_version = 1;
1386 uint32_t version_flags = vpcc_version << 24;
1387 RCHECK(buffer->ReadWriteUInt32(&version_flags));
1388 vpcc_version = version_flags >> 24;
1389 RCHECK(vpcc_version == 1);
1393 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1395 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1400 size_t CodecConfiguration::ComputeSizeInternal() {
1403 DCHECK_NE(box_type, FOURCC_NULL);
1404 return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1407 PixelAspectRatio::PixelAspectRatio() : h_spacing(0), v_spacing(0) {}
1408 PixelAspectRatio::~PixelAspectRatio() {}
1411 bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
1412 RCHECK(ReadWriteHeaderInternal(buffer) &&
1413 buffer->ReadWriteUInt32(&h_spacing) &&
1414 buffer->ReadWriteUInt32(&v_spacing));
1418 size_t PixelAspectRatio::ComputeSizeInternal() {
1420 if (h_spacing == 0 && v_spacing == 0)
1423 DCHECK(h_spacing != 0 && v_spacing != 0);
1424 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
1427 VideoSampleEntry::VideoSampleEntry()
1428 : format(FOURCC_NULL), data_reference_index(1), width(0), height(0) {}
1430 VideoSampleEntry::~VideoSampleEntry() {}
1432 if (format == FOURCC_NULL) {
1433 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the " 1434 <<
"handler type recovered in its Media ancestor.";
1439 bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1440 std::vector<uint8_t> compressor_name;
1442 DCHECK(buffer->
reader());
1443 format = buffer->
reader()->type();
1445 RCHECK(ReadWriteHeaderInternal(buffer));
1447 const FourCC actual_format = GetActualFormat();
1448 switch (actual_format) {
1451 compressor_name.assign(
1453 kAvcCompressorName + arraysize(kAvcCompressorName));
1457 compressor_name.assign(
1458 kHevcCompressorName,
1459 kHevcCompressorName + arraysize(kHevcCompressorName));
1464 compressor_name.assign(
1466 kVpcCompressorName + arraysize(kVpcCompressorName));
1469 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
1472 compressor_name.resize(kCompressorNameSize);
1475 uint32_t video_resolution = kVideoResolution;
1476 uint16_t video_frame_count = kVideoFrameCount;
1477 uint16_t video_depth = kVideoDepth;
1478 int16_t predefined = -1;
1480 buffer->ReadWriteUInt16(&data_reference_index) &&
1482 buffer->ReadWriteUInt16(&width) &&
1483 buffer->ReadWriteUInt16(&height) &&
1484 buffer->ReadWriteUInt32(&video_resolution) &&
1485 buffer->ReadWriteUInt32(&video_resolution) &&
1487 buffer->ReadWriteUInt16(&video_frame_count) &&
1488 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1489 buffer->ReadWriteUInt16(&video_depth) &&
1490 buffer->ReadWriteInt16(&predefined));
1497 if (format == FOURCC_encv && buffer->
Reading()) {
1500 while (!IsProtectionSchemeSupported(sinf.type.type))
1504 const FourCC actual_format = GetActualFormat();
1506 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1508 DCHECK_EQ(codec_configuration.box_type,
1509 GetCodecConfigurationBoxType(actual_format));
1511 if (codec_configuration.box_type == FOURCC_NULL)
1520 if (format == FOURCC_encv && !buffer->
Reading()) {
1521 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1527 size_t VideoSampleEntry::ComputeSizeInternal() {
1528 const FourCC actual_format = GetActualFormat();
1529 if (actual_format == FOURCC_NULL)
1531 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1532 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1533 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
1534 sizeof(height) +
sizeof(kVideoResolution) * 2 +
1535 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
1536 pixel_aspect.ComputeSize() + sinf.ComputeSize() +
1537 codec_configuration.ComputeSize() + kCompressorNameSize + 6 + 4 + 16 +
1541 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format)
const {
1554 LOG(ERROR) << FourCCToString(format) <<
" is not supported.";
1559 ElementaryStreamDescriptor::ElementaryStreamDescriptor() {}
1560 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
1563 bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
1564 RCHECK(ReadWriteHeaderInternal(buffer));
1566 std::vector<uint8_t> data;
1567 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1568 RCHECK(es_descriptor.Parse(data));
1569 if (es_descriptor.IsAAC()) {
1570 RCHECK(aac_audio_specific_config.Parse(
1571 es_descriptor.decoder_specific_info()));
1574 DCHECK(buffer->
writer());
1575 es_descriptor.Write(buffer->
writer());
1580 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1582 if (es_descriptor.object_type() == ObjectType::kForbidden)
1584 return HeaderSize() + es_descriptor.ComputeSize();
1587 DTSSpecific::DTSSpecific()
1588 : sampling_frequency(0),
1591 pcm_sample_depth(0) {}
1592 DTSSpecific::~DTSSpecific() {}
1595 bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1596 RCHECK(ReadWriteHeaderInternal(buffer) &&
1597 buffer->ReadWriteUInt32(&sampling_frequency) &&
1598 buffer->ReadWriteUInt32(&max_bitrate) &&
1599 buffer->ReadWriteUInt32(&avg_bitrate) &&
1600 buffer->ReadWriteUInt8(&pcm_sample_depth));
1603 RCHECK(buffer->ReadWriteVector(&extra_data, buffer->
BytesLeft()));
1605 if (extra_data.empty()) {
1606 extra_data.assign(kDdtsExtraData,
1607 kDdtsExtraData +
sizeof(kDdtsExtraData));
1609 RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1614 size_t DTSSpecific::ComputeSizeInternal() {
1616 if (sampling_frequency == 0)
1618 return HeaderSize() +
sizeof(sampling_frequency) +
sizeof(max_bitrate) +
1619 sizeof(avg_bitrate) +
sizeof(pcm_sample_depth) +
1620 sizeof(kDdtsExtraData);
1623 AC3Specific::AC3Specific() {}
1624 AC3Specific::~AC3Specific() {}
1628 bool AC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1629 RCHECK(ReadWriteHeaderInternal(buffer) &&
1630 buffer->ReadWriteVector(
1635 size_t AC3Specific::ComputeSizeInternal() {
1639 return HeaderSize() + data.size();
1642 EC3Specific::EC3Specific() {}
1643 EC3Specific::~EC3Specific() {}
1647 bool EC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1648 RCHECK(ReadWriteHeaderInternal(buffer));
1650 RCHECK(buffer->ReadWriteVector(&data, size));
1654 size_t EC3Specific::ComputeSizeInternal() {
1658 return HeaderSize() + data.size();
1661 OpusSpecific::OpusSpecific() : preskip(0) {}
1662 OpusSpecific::~OpusSpecific() {}
1666 bool OpusSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1667 RCHECK(ReadWriteHeaderInternal(buffer));
1669 std::vector<uint8_t> data;
1670 const int kMinOpusSpecificBoxDataSize = 11;
1671 RCHECK(buffer->
BytesLeft() >= kMinOpusSpecificBoxDataSize);
1672 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1673 preskip = data[2] + (data[3] << 8);
1678 writer.AppendInt(FOURCC_Head);
1680 const uint8_t kOpusIdentificationHeaderVersion = 1;
1681 data[0] = kOpusIdentificationHeaderVersion;
1682 writer.AppendVector(data);
1683 writer.SwapBuffer(&opus_identification_header);
1687 const size_t kOpusMagicSignatureSize = 8u;
1688 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1691 const uint8_t kOpusSpecificBoxVersion = 0;
1693 buffer->
writer()->AppendArray(
1694 &opus_identification_header[kOpusMagicSignatureSize + 1],
1695 opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1700 size_t OpusSpecific::ComputeSizeInternal() {
1702 if (opus_identification_header.empty())
1706 const size_t kOpusMagicSignatureSize = 8u;
1707 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1708 return HeaderSize() + opus_identification_header.size() -
1709 kOpusMagicSignatureSize;
1712 FlacSpecific::FlacSpecific() {}
1713 FlacSpecific::~FlacSpecific() {}
1719 bool FlacSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1720 RCHECK(ReadWriteHeaderInternal(buffer));
1722 RCHECK(buffer->ReadWriteVector(&data, size));
1726 size_t FlacSpecific::ComputeSizeInternal() {
1730 return HeaderSize() + data.size();
1733 AudioSampleEntry::AudioSampleEntry()
1734 : format(FOURCC_NULL),
1735 data_reference_index(1),
1740 AudioSampleEntry::~AudioSampleEntry() {}
1743 if (format == FOURCC_NULL) {
1744 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the " 1745 <<
"handler type recovered in its Media ancestor.";
1750 bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1752 DCHECK(buffer->
reader());
1753 format = buffer->
reader()->type();
1755 RCHECK(ReadWriteHeaderInternal(buffer));
1761 buffer->ReadWriteUInt16(&data_reference_index) &&
1763 buffer->ReadWriteUInt16(&channelcount) &&
1764 buffer->ReadWriteUInt16(&samplesize) &&
1766 buffer->ReadWriteUInt32(&samplerate));
1782 if (format == FOURCC_enca) {
1786 while (!IsProtectionSchemeSupported(sinf.type.type))
1789 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1796 size_t AudioSampleEntry::ComputeSizeInternal() {
1797 if (GetActualFormat() == FOURCC_NULL)
1799 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
1800 sizeof(samplesize) +
sizeof(samplerate) + sinf.ComputeSize() +
1801 esds.ComputeSize() + ddts.ComputeSize() + dac3.ComputeSize() +
1802 dec3.ComputeSize() + dops.ComputeSize() + dfla.ComputeSize() +
1808 WebVTTConfigurationBox::WebVTTConfigurationBox() {}
1809 WebVTTConfigurationBox::~WebVTTConfigurationBox() {}
1815 bool WebVTTConfigurationBox::ReadWriteInternal(
BoxBuffer* buffer) {
1816 RCHECK(ReadWriteHeaderInternal(buffer));
1822 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
1823 return HeaderSize() + config.size();
1826 WebVTTSourceLabelBox::WebVTTSourceLabelBox() {}
1827 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() {}
1833 bool WebVTTSourceLabelBox::ReadWriteInternal(
BoxBuffer* buffer) {
1834 RCHECK(ReadWriteHeaderInternal(buffer));
1837 : source_label.size());
1840 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
1841 if (source_label.empty())
1843 return HeaderSize() + source_label.size();
1846 TextSampleEntry::TextSampleEntry() : format(FOURCC_NULL) {}
1847 TextSampleEntry::~TextSampleEntry() {}
1850 if (format == FOURCC_NULL) {
1851 LOG(ERROR) <<
"TextSampleEntry should be parsed according to the " 1852 <<
"handler type recovered in its Media ancestor.";
1857 bool TextSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1859 DCHECK(buffer->
reader());
1860 format = buffer->
reader()->type();
1862 RCHECK(ReadWriteHeaderInternal(buffer));
1865 buffer->ReadWriteUInt16(&data_reference_index));
1867 if (format == FOURCC_wvtt) {
1876 size_t TextSampleEntry::ComputeSizeInternal() {
1878 return HeaderSize() + 6 +
sizeof(data_reference_index) +
1879 config.ComputeSize() + label.ComputeSize();
1882 MediaHeader::MediaHeader()
1883 : creation_time(0), modification_time(0), timescale(0), duration(0) {}
1884 MediaHeader::~MediaHeader() {}
1887 bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1888 RCHECK(ReadWriteHeaderInternal(buffer));
1890 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1893 buffer->ReadWriteUInt32(×cale) &&
1895 language.ReadWrite(buffer) &&
1900 size_t MediaHeader::ComputeSizeInternal() {
1901 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1902 return HeaderSize() +
sizeof(timescale) +
1903 sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
1907 VideoMediaHeader::VideoMediaHeader()
1908 : graphicsmode(0), opcolor_red(0), opcolor_green(0), opcolor_blue(0) {
1909 const uint32_t kVideoMediaHeaderFlags = 1;
1910 flags = kVideoMediaHeaderFlags;
1912 VideoMediaHeader::~VideoMediaHeader() {}
1914 bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1915 RCHECK(ReadWriteHeaderInternal(buffer) &&
1916 buffer->ReadWriteUInt16(&graphicsmode) &&
1917 buffer->ReadWriteUInt16(&opcolor_red) &&
1918 buffer->ReadWriteUInt16(&opcolor_green) &&
1919 buffer->ReadWriteUInt16(&opcolor_blue));
1923 size_t VideoMediaHeader::ComputeSizeInternal() {
1924 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
1925 sizeof(opcolor_green) +
sizeof(opcolor_blue);
1928 SoundMediaHeader::SoundMediaHeader() : balance(0) {}
1929 SoundMediaHeader::~SoundMediaHeader() {}
1931 bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1932 RCHECK(ReadWriteHeaderInternal(buffer) &&
1933 buffer->ReadWriteUInt16(&balance) &&
1938 size_t SoundMediaHeader::ComputeSizeInternal() {
1939 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
1942 SubtitleMediaHeader::SubtitleMediaHeader() {}
1943 SubtitleMediaHeader::~SubtitleMediaHeader() {}
1947 bool SubtitleMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1948 return ReadWriteHeaderInternal(buffer);
1951 size_t SubtitleMediaHeader::ComputeSizeInternal() {
1952 return HeaderSize();
1955 DataEntryUrl::DataEntryUrl() {
1956 const uint32_t kDataEntryUrlFlags = 1;
1957 flags = kDataEntryUrlFlags;
1959 DataEntryUrl::~DataEntryUrl() {}
1961 bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
1962 RCHECK(ReadWriteHeaderInternal(buffer));
1964 RCHECK(buffer->ReadWriteVector(&location, buffer->
BytesLeft()));
1966 RCHECK(buffer->ReadWriteVector(&location, location.size()));
1971 size_t DataEntryUrl::ComputeSizeInternal() {
1972 return HeaderSize() + location.size();
1975 DataReference::DataReference() {
1977 data_entry.resize(1);
1979 DataReference::~DataReference() {}
1981 bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
1982 uint32_t entry_count =
static_cast<uint32_t
>(data_entry.size());
1983 RCHECK(ReadWriteHeaderInternal(buffer) &&
1984 buffer->ReadWriteUInt32(&entry_count));
1985 data_entry.resize(entry_count);
1987 for (uint32_t i = 0; i < entry_count; ++i)
1992 size_t DataReference::ComputeSizeInternal() {
1993 uint32_t count =
static_cast<uint32_t
>(data_entry.size());
1994 size_t box_size = HeaderSize() +
sizeof(count);
1995 for (uint32_t i = 0; i < count; ++i)
1996 box_size += data_entry[i].ComputeSize();
2000 DataInformation::DataInformation() {}
2001 DataInformation::~DataInformation() {}
2004 bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2005 return ReadWriteHeaderInternal(buffer) &&
2010 size_t DataInformation::ComputeSizeInternal() {
2011 return HeaderSize() + dref.ComputeSize();
2014 MediaInformation::MediaInformation() {}
2015 MediaInformation::~MediaInformation() {}
2018 bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2019 RCHECK(ReadWriteHeaderInternal(buffer) &&
2023 switch (sample_table.description.type) {
2040 size_t MediaInformation::ComputeSizeInternal() {
2042 HeaderSize() + dinf.ComputeSize() + sample_table.ComputeSize();
2043 switch (sample_table.description.type) {
2045 box_size += vmhd.ComputeSize();
2048 box_size += smhd.ComputeSize();
2051 box_size += sthd.ComputeSize();
2063 bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
2064 RCHECK(ReadWriteHeaderInternal(buffer) &&
2075 information.sample_table.description.type =
2076 FourCCToTrackType(handler.handler_type);
2078 handler.handler_type =
2079 TrackTypeToFourCC(information.sample_table.description.type);
2080 RCHECK(handler.handler_type != FOURCC_NULL);
2087 size_t Media::ComputeSizeInternal() {
2088 handler.handler_type =
2089 TrackTypeToFourCC(information.sample_table.description.type);
2090 return HeaderSize() + header.ComputeSize() + handler.ComputeSize() +
2091 information.ComputeSize();
2098 bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
2099 RCHECK(ReadWriteHeaderInternal(buffer) &&
2108 size_t Track::ComputeSizeInternal() {
2109 return HeaderSize() + header.ComputeSize() + media.ComputeSize() +
2113 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
2114 MovieExtendsHeader::~MovieExtendsHeader() {}
2117 bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2118 RCHECK(ReadWriteHeaderInternal(buffer));
2119 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2124 size_t MovieExtendsHeader::ComputeSizeInternal() {
2126 if (fragment_duration == 0)
2128 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2129 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2132 TrackExtends::TrackExtends()
2134 default_sample_description_index(0),
2135 default_sample_duration(0),
2136 default_sample_size(0),
2137 default_sample_flags(0) {}
2138 TrackExtends::~TrackExtends() {}
2141 bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2142 RCHECK(ReadWriteHeaderInternal(buffer) &&
2143 buffer->ReadWriteUInt32(&track_id) &&
2144 buffer->ReadWriteUInt32(&default_sample_description_index) &&
2145 buffer->ReadWriteUInt32(&default_sample_duration) &&
2146 buffer->ReadWriteUInt32(&default_sample_size) &&
2147 buffer->ReadWriteUInt32(&default_sample_flags));
2151 size_t TrackExtends::ComputeSizeInternal() {
2152 return HeaderSize() +
sizeof(track_id) +
2153 sizeof(default_sample_description_index) +
2154 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
2155 sizeof(default_sample_flags);
2158 MovieExtends::MovieExtends() {}
2159 MovieExtends::~MovieExtends() {}
2162 bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2163 RCHECK(ReadWriteHeaderInternal(buffer) &&
2167 DCHECK(buffer->
reader());
2170 for (uint32_t i = 0; i < tracks.size(); ++i)
2176 size_t MovieExtends::ComputeSizeInternal() {
2178 if (tracks.size() == 0)
2180 size_t box_size = HeaderSize() + header.ComputeSize();
2181 for (uint32_t i = 0; i < tracks.size(); ++i)
2182 box_size += tracks[i].ComputeSize();
2190 bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
2191 RCHECK(ReadWriteHeaderInternal(buffer) && buffer->
PrepareChildren() &&
2206 for (uint32_t i = 0; i < tracks.size(); ++i)
2209 for (uint32_t i = 0; i < pssh.size(); ++i)
2215 size_t Movie::ComputeSizeInternal() {
2216 size_t box_size = HeaderSize() + header.ComputeSize() +
2217 metadata.ComputeSize() + extends.ComputeSize();
2218 for (uint32_t i = 0; i < tracks.size(); ++i)
2219 box_size += tracks[i].ComputeSize();
2220 for (uint32_t i = 0; i < pssh.size(); ++i)
2221 box_size += pssh[i].ComputeSize();
2225 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
2226 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
2229 bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
2230 RCHECK(ReadWriteHeaderInternal(buffer));
2231 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2236 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2237 version = IsFitIn32Bits(decode_time) ? 0 : 1;
2238 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2241 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
2242 MovieFragmentHeader::~MovieFragmentHeader() {}
2245 bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2246 return ReadWriteHeaderInternal(buffer) &&
2247 buffer->ReadWriteUInt32(&sequence_number);
2250 size_t MovieFragmentHeader::ComputeSizeInternal() {
2251 return HeaderSize() +
sizeof(sequence_number);
2254 TrackFragmentHeader::TrackFragmentHeader()
2256 sample_description_index(0),
2257 default_sample_duration(0),
2258 default_sample_size(0),
2259 default_sample_flags(0) {}
2261 TrackFragmentHeader::~TrackFragmentHeader() {}
2264 bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2265 RCHECK(ReadWriteHeaderInternal(buffer) &&
2266 buffer->ReadWriteUInt32(&track_id));
2268 if (flags & kBaseDataOffsetPresentMask) {
2273 uint64_t base_data_offset;
2274 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2275 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes " 2276 "default-base-is-moof.";
2279 if (flags & kSampleDescriptionIndexPresentMask) {
2280 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2281 }
else if (buffer->
Reading()) {
2282 sample_description_index = 0;
2285 if (flags & kDefaultSampleDurationPresentMask) {
2286 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2287 }
else if (buffer->
Reading()) {
2288 default_sample_duration = 0;
2291 if (flags & kDefaultSampleSizePresentMask) {
2292 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2293 }
else if (buffer->
Reading()) {
2294 default_sample_size = 0;
2297 if (flags & kDefaultSampleFlagsPresentMask)
2298 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2302 size_t TrackFragmentHeader::ComputeSizeInternal() {
2303 size_t box_size = HeaderSize() +
sizeof(track_id);
2304 if (flags & kSampleDescriptionIndexPresentMask)
2305 box_size +=
sizeof(sample_description_index);
2306 if (flags & kDefaultSampleDurationPresentMask)
2307 box_size +=
sizeof(default_sample_duration);
2308 if (flags & kDefaultSampleSizePresentMask)
2309 box_size +=
sizeof(default_sample_size);
2310 if (flags & kDefaultSampleFlagsPresentMask)
2311 box_size +=
sizeof(default_sample_flags);
2315 TrackFragmentRun::TrackFragmentRun() : sample_count(0), data_offset(0) {}
2316 TrackFragmentRun::~TrackFragmentRun() {}
2319 bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
2325 if (flags & kSampleCompTimeOffsetsPresentMask) {
2326 for (uint32_t i = 0; i < sample_count; ++i) {
2327 if (sample_composition_time_offsets[i] < 0) {
2335 RCHECK(ReadWriteHeaderInternal(buffer) &&
2336 buffer->ReadWriteUInt32(&sample_count));
2338 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2339 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2340 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2341 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2342 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2343 bool sample_composition_time_offsets_present =
2344 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2346 if (data_offset_present) {
2347 RCHECK(buffer->ReadWriteUInt32(&data_offset));
2358 uint32_t first_sample_flags(0);
2361 if (first_sample_flags_present)
2362 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2364 if (sample_duration_present)
2365 sample_durations.resize(sample_count);
2366 if (sample_size_present)
2367 sample_sizes.resize(sample_count);
2368 if (sample_flags_present)
2369 sample_flags.resize(sample_count);
2370 if (sample_composition_time_offsets_present)
2371 sample_composition_time_offsets.resize(sample_count);
2373 if (first_sample_flags_present) {
2374 first_sample_flags = sample_flags[0];
2375 DCHECK(sample_flags.size() == 1);
2376 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2379 if (sample_duration_present)
2380 DCHECK(sample_durations.size() == sample_count);
2381 if (sample_size_present)
2382 DCHECK(sample_sizes.size() == sample_count);
2383 if (sample_flags_present)
2384 DCHECK(sample_flags.size() == sample_count);
2385 if (sample_composition_time_offsets_present)
2386 DCHECK(sample_composition_time_offsets.size() == sample_count);
2389 for (uint32_t i = 0; i < sample_count; ++i) {
2390 if (sample_duration_present)
2391 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2392 if (sample_size_present)
2393 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2394 if (sample_flags_present)
2395 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2397 if (sample_composition_time_offsets_present) {
2399 uint32_t sample_offset = sample_composition_time_offsets[i];
2400 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2401 sample_composition_time_offsets[i] = sample_offset;
2403 int32_t sample_offset = sample_composition_time_offsets[i];
2404 RCHECK(buffer->ReadWriteInt32(&sample_offset));
2405 sample_composition_time_offsets[i] = sample_offset;
2411 if (first_sample_flags_present) {
2412 if (sample_flags.size() == 0) {
2413 sample_flags.push_back(first_sample_flags);
2415 sample_flags[0] = first_sample_flags;
2422 size_t TrackFragmentRun::ComputeSizeInternal() {
2423 size_t box_size = HeaderSize() +
sizeof(sample_count);
2424 if (flags & kDataOffsetPresentMask)
2425 box_size +=
sizeof(data_offset);
2426 if (flags & kFirstSampleFlagsPresentMask)
2427 box_size +=
sizeof(uint32_t);
2428 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2429 (flags & kSampleSizePresentMask ? 1 : 0) +
2430 (flags & kSampleFlagsPresentMask ? 1 : 0) +
2431 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2432 box_size += fields *
sizeof(uint32_t) * sample_count;
2436 TrackFragment::TrackFragment() : decode_time_absent(
false) {}
2437 TrackFragment::~TrackFragment() {}
2440 bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2441 RCHECK(ReadWriteHeaderInternal(buffer) &&
2445 DCHECK(buffer->
reader());
2447 if (!decode_time_absent)
2453 if (!decode_time_absent)
2455 for (uint32_t i = 0; i < runs.size(); ++i)
2457 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2459 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2467 size_t TrackFragment::ComputeSizeInternal() {
2468 size_t box_size = HeaderSize() + header.ComputeSize() +
2469 decode_time.ComputeSize() + auxiliary_size.ComputeSize() +
2470 auxiliary_offset.ComputeSize() +
2471 sample_encryption.ComputeSize();
2472 for (uint32_t i = 0; i < runs.size(); ++i)
2473 box_size += runs[i].ComputeSize();
2474 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2475 box_size += sample_group_descriptions[i].ComputeSize();
2476 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2477 box_size += sample_to_groups[i].ComputeSize();
2481 MovieFragment::MovieFragment() {}
2482 MovieFragment::~MovieFragment() {}
2485 bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2486 RCHECK(ReadWriteHeaderInternal(buffer) &&
2495 for (uint32_t i = 0; i < tracks.size(); ++i)
2497 for (uint32_t i = 0; i < pssh.size(); ++i)
2503 size_t MovieFragment::ComputeSizeInternal() {
2504 size_t box_size = HeaderSize() + header.ComputeSize();
2505 for (uint32_t i = 0; i < tracks.size(); ++i)
2506 box_size += tracks[i].ComputeSize();
2507 for (uint32_t i = 0; i < pssh.size(); ++i)
2508 box_size += pssh[i].ComputeSize();
2512 SegmentIndex::SegmentIndex()
2515 earliest_presentation_time(0),
2517 SegmentIndex::~SegmentIndex() {}
2520 bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
2521 RCHECK(ReadWriteHeaderInternal(buffer) &&
2522 buffer->ReadWriteUInt32(&reference_id) &&
2523 buffer->ReadWriteUInt32(×cale));
2525 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2530 uint16_t reference_count =
static_cast<uint16_t
>(references.size());
2532 buffer->ReadWriteUInt16(&reference_count));
2533 references.resize(reference_count);
2535 uint32_t reference_type_size;
2537 for (uint32_t i = 0; i < reference_count; ++i) {
2539 reference_type_size = references[i].referenced_size;
2540 if (references[i].reference_type)
2541 reference_type_size |= (1 << 31);
2542 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2543 if (references[i].starts_with_sap)
2546 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2547 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2548 buffer->ReadWriteUInt32(&sap));
2550 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
2551 references[i].referenced_size = reference_type_size & ~(1 << 31);
2552 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
2553 references[i].sap_type =
2554 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
2555 references[i].sap_delta_time = sap & ~(0xF << 28);
2561 size_t SegmentIndex::ComputeSizeInternal() {
2562 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2563 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
2564 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
2565 3 *
sizeof(uint32_t) * references.size();
2568 MediaData::MediaData() : data_size(0) {}
2569 MediaData::~MediaData() {}
2572 bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
2573 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
2577 size_t MediaData::ComputeSizeInternal() {
2578 return HeaderSize() + data_size;
2581 CueSourceIDBox::CueSourceIDBox() : source_id(kCueSourceIdNotSet) {}
2582 CueSourceIDBox::~CueSourceIDBox() {}
2586 bool CueSourceIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2587 RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteInt32(&source_id));
2591 size_t CueSourceIDBox::ComputeSizeInternal() {
2592 if (source_id == kCueSourceIdNotSet)
2594 return HeaderSize() +
sizeof(source_id);
2597 CueTimeBox::CueTimeBox() {}
2598 CueTimeBox::~CueTimeBox() {}
2604 bool CueTimeBox::ReadWriteInternal(
BoxBuffer* buffer) {
2605 RCHECK(ReadWriteHeaderInternal(buffer));
2611 size_t CueTimeBox::ComputeSizeInternal() {
2612 if (cue_current_time.empty())
2614 return HeaderSize() + cue_current_time.size();
2617 CueIDBox::CueIDBox() {}
2618 CueIDBox::~CueIDBox() {}
2624 bool CueIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2625 RCHECK(ReadWriteHeaderInternal(buffer));
2630 size_t CueIDBox::ComputeSizeInternal() {
2633 return HeaderSize() + cue_id.size();
2636 CueSettingsBox::CueSettingsBox() {}
2637 CueSettingsBox::~CueSettingsBox() {}
2643 bool CueSettingsBox::ReadWriteInternal(
BoxBuffer* buffer) {
2644 RCHECK(ReadWriteHeaderInternal(buffer));
2649 size_t CueSettingsBox::ComputeSizeInternal() {
2650 if (settings.empty())
2652 return HeaderSize() + settings.size();
2655 CuePayloadBox::CuePayloadBox() {}
2656 CuePayloadBox::~CuePayloadBox() {}
2662 bool CuePayloadBox::ReadWriteInternal(
BoxBuffer* buffer) {
2663 RCHECK(ReadWriteHeaderInternal(buffer));
2668 size_t CuePayloadBox::ComputeSizeInternal() {
2669 return HeaderSize() + cue_text.size();
2672 VTTEmptyCueBox::VTTEmptyCueBox() {}
2673 VTTEmptyCueBox::~VTTEmptyCueBox() {}
2679 bool VTTEmptyCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2680 return ReadWriteHeaderInternal(buffer);
2683 size_t VTTEmptyCueBox::ComputeSizeInternal() {
2684 return HeaderSize();
2687 VTTAdditionalTextBox::VTTAdditionalTextBox() {}
2688 VTTAdditionalTextBox::~VTTAdditionalTextBox() {}
2694 bool VTTAdditionalTextBox::ReadWriteInternal(
BoxBuffer* buffer) {
2695 RCHECK(ReadWriteHeaderInternal(buffer));
2697 &cue_additional_text,
2701 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
2702 return HeaderSize() + cue_additional_text.size();
2705 VTTCueBox::VTTCueBox() {}
2706 VTTCueBox::~VTTCueBox() {}
2712 bool VTTCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
2713 RCHECK(ReadWriteHeaderInternal(buffer) &&
2723 size_t VTTCueBox::ComputeSizeInternal() {
2724 return HeaderSize() + cue_source_id.ComputeSize() + cue_id.ComputeSize() +
2725 cue_time.ComputeSize() + cue_settings.ComputeSize() +
2726 cue_payload.ComputeSize();
FourCC BoxType() const override
bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
uint32_t GetTotalSizeOfSubsamples() const
uint32_t ComputeSize() const
FourCC BoxType() const override
FourCC BoxType() const override
All the methods that are virtual are virtual for mocking.
FourCC BoxType() const override
bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
FourCC BoxType() const override