5 #include <packager/media/formats/mp4/box_definitions.h>
10 #include <absl/flags/flag.h>
11 #include <absl/log/check.h>
12 #include <absl/log/log.h>
14 #include <packager/macros/logging.h>
15 #include <packager/media/base/bit_reader.h>
16 #include <packager/media/base/rcheck.h>
17 #include <packager/media/formats/mp4/box_buffer.h>
22 "Android MediaExtractor requires mvex to be written before trak. "
23 "Set the flag to true to comply with the requirement.");
26 const uint32_t kFourCCSize = 4;
29 const uint32_t kCencKeyIdSize = 16;
32 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
37 const char kVideoHandlerName[] =
"VideoHandler";
38 const char kAudioHandlerName[] =
"SoundHandler";
39 const char kTextHandlerName[] =
"TextHandler";
40 const char kSubtitleHandlerName[] =
"SubtitleHandler";
43 const uint32_t kVideoResolution = 0x00480000;
44 const uint16_t kVideoFrameCount = 1;
45 const uint16_t kVideoDepth = 0x0018;
47 const uint32_t kCompressorNameSize = 32u;
48 const char kAv1CompressorName[] =
"\012AOM Coding";
49 const char kAvcCompressorName[] =
"\012AVC Coding";
50 const char kDolbyVisionCompressorName[] =
"\013DOVI Coding";
51 const char kHevcCompressorName[] =
"\013HEVC Coding";
52 const char kVpcCompressorName[] =
"\012VPC Coding";
57 bool IsIvSizeValid(uint8_t per_sample_iv_size) {
58 return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
59 per_sample_iv_size == 16;
76 const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
79 bool IsFitIn32Bits(uint64_t a) {
80 return a <= std::numeric_limits<uint32_t>::max();
83 bool IsFitIn32Bits(int64_t a) {
84 return a <= std::numeric_limits<int32_t>::max() &&
85 a >= std::numeric_limits<int32_t>::min();
88 template <
typename T1,
typename T2>
89 bool IsFitIn32Bits(T1 a1, T2 a2) {
90 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
93 template <
typename T1,
typename T2,
typename T3>
94 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
95 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
106 TrackType FourCCToTrackType(FourCC fourcc) {
121 FourCC TrackTypeToFourCC(TrackType track_type) {
122 switch (track_type) {
136 bool IsProtectionSchemeSupported(FourCC scheme) {
137 return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
138 scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
143 FileType::FileType() =
default;
144 FileType::~FileType() =
default;
150 bool FileType::ReadWriteInternal(
BoxBuffer* buffer) {
152 buffer->ReadWriteFourCC(&major_brand) &&
153 buffer->ReadWriteUInt32(&minor_version));
156 RCHECK(buffer->
BytesLeft() %
sizeof(FourCC) == 0);
157 num_brands = buffer->
BytesLeft() /
sizeof(FourCC);
158 compatible_brands.resize(num_brands);
160 num_brands = compatible_brands.size();
162 for (
size_t i = 0; i < num_brands; ++i)
163 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
167 size_t FileType::ComputeSizeInternal() {
168 return HeaderSize() + kFourCCSize +
sizeof(minor_version) +
169 kFourCCSize * compatible_brands.size();
176 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() =
default;
177 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() =
default;
183 bool ProtectionSystemSpecificHeader::ReadWriteInternal(
BoxBuffer* buffer) {
187 raw_box.assign(reader->data(), reader->data() + reader->size());
189 DCHECK(!raw_box.empty());
190 buffer->
writer()->AppendVector(raw_box);
196 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
197 return raw_box.size();
200 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() =
default;
201 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() =
default;
207 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
212 uint32_t count =
static_cast<uint32_t
>(offsets.size());
213 RCHECK(buffer->ReadWriteUInt32(&count));
214 offsets.resize(count);
216 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
217 for (uint32_t i = 0; i < count; ++i)
222 size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
224 if (offsets.size() == 0)
226 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
227 return HeaderSize() +
sizeof(uint32_t) + num_bytes * offsets.size();
230 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() =
default;
231 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() =
default;
237 bool SampleAuxiliaryInformationSize::ReadWriteInternal(
BoxBuffer* buffer) {
242 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
243 buffer->ReadWriteUInt32(&sample_count));
244 if (default_sample_info_size == 0)
245 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
249 size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
251 if (sample_count == 0)
253 return HeaderSize() +
sizeof(default_sample_info_size) +
254 sizeof(sample_count) +
255 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
261 DCHECK(IsIvSizeValid(iv_size));
264 RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
266 if (!has_subsamples) {
271 uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
272 RCHECK(buffer->ReadWriteUInt16(&subsample_count));
273 RCHECK(subsample_count > 0);
274 subsamples.resize(subsample_count);
275 for (
auto& subsample : subsamples) {
276 RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
277 buffer->ReadWriteUInt32(&subsample.cipher_bytes));
285 DCHECK(IsIvSizeValid(iv_size));
288 initialization_vector.resize(iv_size);
289 RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
291 if (!has_subsamples) {
296 uint16_t subsample_count;
297 RCHECK(reader->Read2(&subsample_count));
298 RCHECK(subsample_count > 0);
299 subsamples.resize(subsample_count);
300 for (
auto& subsample : subsamples) {
301 RCHECK(reader->Read2(&subsample.clear_bytes) &&
302 reader->Read4(&subsample.cipher_bytes));
308 const uint32_t subsample_entry_size =
sizeof(uint16_t) +
sizeof(uint32_t);
309 const uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
310 return static_cast<uint32_t
>(
311 initialization_vector.size() +
313 ? (
sizeof(subsample_count) + subsample_entry_size * subsample_count)
319 for (uint32_t i = 0; i < subsamples.size(); ++i)
320 size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
324 SampleEncryption::SampleEncryption() =
default;
325 SampleEncryption::~SampleEncryption() =
default;
331 bool SampleEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
336 if (buffer->
Reading() && iv_size == SampleEncryption::kInvalidIvSize) {
342 if (!IsIvSizeValid(iv_size)) {
344 <<
"IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
349 uint32_t sample_count =
350 static_cast<uint32_t
>(sample_encryption_entries.size());
351 RCHECK(buffer->ReadWriteUInt32(&sample_count));
353 sample_encryption_entries.resize(sample_count);
354 for (
auto& sample_encryption_entry : sample_encryption_entries) {
355 RCHECK(sample_encryption_entry.ReadWrite(
356 iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
361 size_t SampleEncryption::ComputeSizeInternal() {
362 const uint32_t sample_count =
363 static_cast<uint32_t
>(sample_encryption_entries.size());
364 if (sample_count == 0) {
369 DCHECK(IsIvSizeValid(iv_size));
371 if (flags & kUseSubsampleEncryption) {
372 for (
const SampleEncryptionEntry& sample_encryption_entry :
373 sample_encryption_entries) {
374 box_size += sample_encryption_entry.ComputeSize();
384 std::vector<SampleEncryptionEntry>* l_sample_encryption_entries)
const {
385 DCHECK(IsIvSizeValid(l_iv_size));
389 uint32_t sample_count = 0;
390 RCHECK(reader.Read4(&sample_count));
392 l_sample_encryption_entries->resize(sample_count);
393 for (
auto& sample_encryption_entry : *l_sample_encryption_entries) {
394 RCHECK(sample_encryption_entry.ParseFromBuffer(
395 l_iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) !=
401 OriginalFormat::OriginalFormat() =
default;
402 OriginalFormat::~OriginalFormat() =
default;
408 bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
412 size_t OriginalFormat::ComputeSizeInternal() {
416 SchemeType::SchemeType() =
default;
417 SchemeType::~SchemeType() =
default;
423 bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
425 buffer->ReadWriteUInt32(&version));
429 size_t SchemeType::ComputeSizeInternal() {
430 return HeaderSize() + kFourCCSize +
sizeof(version);
433 TrackEncryption::TrackEncryption() =
default;
434 TrackEncryption::~TrackEncryption() =
default;
440 bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
442 if (default_kid.size() != kCencKeyIdSize) {
443 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
444 <<
" bytes; got " << default_kid.size()
445 <<
". Resized accordingly.";
446 default_kid.resize(kCencKeyIdSize);
448 RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
449 if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
458 uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
459 RCHECK(buffer->ReadWriteUInt8(&pattern));
460 default_crypt_byte_block = pattern >> 4;
461 default_skip_byte_block = pattern & 0x0F;
463 RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
464 buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
465 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
467 if (default_is_protected == 1) {
468 if (default_per_sample_iv_size == 0) {
469 uint8_t default_constant_iv_size =
470 static_cast<uint8_t
>(default_constant_iv.size());
471 RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
472 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
473 RCHECK(buffer->ReadWriteVector(&default_constant_iv,
474 default_constant_iv_size));
476 RCHECK(default_per_sample_iv_size == 8 ||
477 default_per_sample_iv_size == 16);
478 RCHECK(default_constant_iv.empty());
483 RCHECK(default_is_protected == 0);
484 RCHECK(default_per_sample_iv_size == 0);
485 RCHECK(default_constant_iv.empty());
490 size_t TrackEncryption::ComputeSizeInternal() {
491 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize +
492 (default_constant_iv.empty()
494 : (
sizeof(uint8_t) + default_constant_iv.size()));
497 SchemeInfo::SchemeInfo() =
default;
498 SchemeInfo::~SchemeInfo() =
default;
504 bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
510 size_t SchemeInfo::ComputeSizeInternal() {
514 ProtectionSchemeInfo::ProtectionSchemeInfo() =
default;
515 ProtectionSchemeInfo::~ProtectionSchemeInfo() =
default;
521 bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
524 if (IsProtectionSchemeSupported(type.type)) {
527 DLOG(WARNING) <<
"Ignore unsupported protection scheme: "
528 << FourCCToString(type.type);
537 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
539 if (format.format == FOURCC_NULL)
545 MovieHeader::MovieHeader() =
default;
546 MovieHeader::~MovieHeader() =
default;
552 bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
555 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
558 buffer->ReadWriteUInt32(×cale) &&
561 std::vector<uint8_t> matrix(kUnityMatrix,
562 kUnityMatrix + std::size(kUnityMatrix));
563 RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
565 buffer->ReadWriteVector(&matrix, matrix.size()) &&
567 buffer->ReadWriteUInt32(&next_track_id));
571 size_t MovieHeader::ComputeSizeInternal() {
572 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
573 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
574 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
575 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
579 TrackHeader::TrackHeader() {
580 flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
583 TrackHeader::~TrackHeader() =
default;
589 bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
592 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
595 buffer->ReadWriteUInt32(&track_id) &&
602 volume = (width != 0 && height != 0) ? 0 : 0x100;
604 std::vector<uint8_t> matrix(kUnityMatrix,
605 kUnityMatrix + std::size(kUnityMatrix));
607 buffer->ReadWriteInt16(&layer) &&
608 buffer->ReadWriteInt16(&alternate_group) &&
609 buffer->ReadWriteInt16(&volume) &&
611 buffer->ReadWriteVector(&matrix, matrix.size()) &&
612 buffer->ReadWriteUInt32(&width) && buffer->ReadWriteUInt32(&height));
616 size_t TrackHeader::ComputeSizeInternal() {
617 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
619 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
620 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
621 sizeof(height) +
sizeof(kUnityMatrix) + 14;
624 SampleDescription::SampleDescription() =
default;
625 SampleDescription::~SampleDescription() =
default;
631 bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
635 count =
static_cast<uint32_t
>(video_entries.size());
638 count =
static_cast<uint32_t
>(audio_entries.size());
642 count =
static_cast<uint32_t
>(text_entries.size());
645 NOTIMPLEMENTED() <<
"SampleDecryption type " << type
646 <<
" is not handled. Skipping.";
651 BoxReader* reader = buffer->
reader();
653 video_entries.clear();
654 audio_entries.clear();
657 if (type == kVideo) {
658 RCHECK(reader->ReadAllChildren(&video_entries));
659 RCHECK(video_entries.size() == count);
660 }
else if (type == kAudio) {
661 RCHECK(reader->ReadAllChildren(&audio_entries));
662 RCHECK(audio_entries.size() == count);
663 }
else if (type == kText || type == kSubtitle) {
664 RCHECK(reader->ReadAllChildren(&text_entries));
665 RCHECK(text_entries.size() == count);
668 DCHECK_LT(0u, count);
669 if (type == kVideo) {
670 for (uint32_t i = 0; i < count; ++i)
672 }
else if (type == kAudio) {
673 for (uint32_t i = 0; i < count; ++i)
675 }
else if (type == kText || type == kSubtitle) {
676 for (uint32_t i = 0; i < count; ++i)
685 size_t SampleDescription::ComputeSizeInternal() {
687 if (type == kVideo) {
688 for (uint32_t i = 0; i < video_entries.size(); ++i)
690 }
else if (type == kAudio) {
691 for (uint32_t i = 0; i < audio_entries.size(); ++i)
693 }
else if (type == kText || type == kSubtitle) {
694 for (uint32_t i = 0; i < text_entries.size(); ++i)
700 DecodingTimeToSample::DecodingTimeToSample() =
default;
701 DecodingTimeToSample::~DecodingTimeToSample() =
default;
707 bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
708 uint32_t count =
static_cast<uint32_t
>(decoding_time.size());
711 decoding_time.resize(count);
712 for (uint32_t i = 0; i < count; ++i) {
713 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
714 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
719 size_t DecodingTimeToSample::ComputeSizeInternal() {
721 sizeof(DecodingTime) * decoding_time.size();
724 CompositionTimeToSample::CompositionTimeToSample() =
default;
725 CompositionTimeToSample::~CompositionTimeToSample() =
default;
731 bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
732 uint32_t count =
static_cast<uint32_t
>(composition_offset.size());
738 for (uint32_t i = 0; i < count; ++i) {
739 if (composition_offset[i].sample_offset < 0) {
748 composition_offset.resize(count);
749 for (uint32_t i = 0; i < count; ++i) {
750 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
753 uint32_t sample_offset = composition_offset[i].sample_offset;
754 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
755 composition_offset[i].sample_offset = sample_offset;
757 int32_t sample_offset = composition_offset[i].sample_offset;
758 RCHECK(buffer->ReadWriteInt32(&sample_offset));
759 composition_offset[i].sample_offset = sample_offset;
765 size_t CompositionTimeToSample::ComputeSizeInternal() {
767 if (composition_offset.empty())
772 const size_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
774 kCompositionOffsetSize * composition_offset.size();
777 SampleToChunk::SampleToChunk() =
default;
778 SampleToChunk::~SampleToChunk() =
default;
784 bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
785 uint32_t count =
static_cast<uint32_t
>(chunk_info.size());
788 chunk_info.resize(count);
789 for (uint32_t i = 0; i < count; ++i) {
790 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
791 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
792 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
794 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
795 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
800 size_t SampleToChunk::ComputeSizeInternal() {
802 sizeof(ChunkInfo) * chunk_info.size();
805 SampleSize::SampleSize() =
default;
806 SampleSize::~SampleSize() =
default;
812 bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
814 buffer->ReadWriteUInt32(&sample_size) &&
815 buffer->ReadWriteUInt32(&sample_count));
817 if (sample_size == 0) {
819 sizes.resize(sample_count);
821 DCHECK(sample_count == sizes.size());
822 for (uint32_t i = 0; i < sample_count; ++i)
823 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
828 size_t SampleSize::ComputeSizeInternal() {
829 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
830 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
833 CompactSampleSize::CompactSampleSize() =
default;
834 CompactSampleSize::~CompactSampleSize() =
default;
840 bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
841 uint32_t sample_count =
static_cast<uint32_t
>(sizes.size());
843 buffer->ReadWriteUInt8(&field_size) &&
844 buffer->ReadWriteUInt32(&sample_count));
847 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
848 switch (field_size) {
850 for (uint32_t i = 0; i < sample_count; i += 2) {
853 RCHECK(buffer->ReadWriteUInt8(&size));
854 sizes[i] = size >> 4;
855 sizes[i + 1] = size & 0x0F;
857 DCHECK_LT(sizes[i], 16u);
858 DCHECK_LT(sizes[i + 1], 16u);
859 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
860 RCHECK(buffer->ReadWriteUInt8(&size));
865 for (uint32_t i = 0; i < sample_count; ++i) {
866 uint8_t size = sizes[i];
867 RCHECK(buffer->ReadWriteUInt8(&size));
872 for (uint32_t i = 0; i < sample_count; ++i) {
873 uint16_t size = sizes[i];
874 RCHECK(buffer->ReadWriteUInt16(&size));
881 sizes.resize(sample_count);
885 size_t CompactSampleSize::ComputeSizeInternal() {
886 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
887 (field_size * sizes.size() + 7) / 8;
890 ChunkOffset::ChunkOffset() =
default;
891 ChunkOffset::~ChunkOffset() =
default;
897 bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
898 uint32_t count =
static_cast<uint32_t
>(offsets.size());
901 offsets.resize(count);
902 for (uint32_t i = 0; i < count; ++i)
907 size_t ChunkOffset::ComputeSizeInternal() {
908 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
911 ChunkLargeOffset::ChunkLargeOffset() =
default;
912 ChunkLargeOffset::~ChunkLargeOffset() =
default;
918 bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
919 uint32_t count =
static_cast<uint32_t
>(offsets.size());
923 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
925 stco.offsets.swap(offsets);
928 stco.offsets.swap(offsets);
935 offsets.resize(count);
936 for (uint32_t i = 0; i < count; ++i)
937 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
941 size_t ChunkLargeOffset::ComputeSizeInternal() {
942 uint32_t count =
static_cast<uint32_t
>(offsets.size());
943 int use_large_offset =
944 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
946 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
949 SyncSample::SyncSample() =
default;
950 SyncSample::~SyncSample() =
default;
956 bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
957 uint32_t count =
static_cast<uint32_t
>(sample_number.size());
960 sample_number.resize(count);
961 for (uint32_t i = 0; i < count; ++i)
962 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
966 size_t SyncSample::ComputeSizeInternal() {
968 if (sample_number.empty())
971 sizeof(uint32_t) * sample_number.size();
974 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
975 if (!buffer->Reading()) {
976 if (key_id.size() != kCencKeyIdSize) {
977 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
978 <<
" bytes; got " << key_id.size()
979 <<
". Resized accordingly.";
980 key_id.resize(kCencKeyIdSize);
982 RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
985 RCHECK(buffer->IgnoreBytes(1));
987 uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
988 RCHECK(buffer->ReadWriteUInt8(&pattern));
989 crypt_byte_block = pattern >> 4;
990 skip_byte_block = pattern & 0x0F;
992 RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
993 buffer->ReadWriteUInt8(&per_sample_iv_size) &&
994 buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
996 if (is_protected == 1) {
997 if (per_sample_iv_size == 0) {
998 uint8_t constant_iv_size =
static_cast<uint8_t
>(constant_iv.size());
999 RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
1000 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
1001 RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
1003 RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
1004 DCHECK(constant_iv.empty());
1009 RCHECK(is_protected == 0);
1010 RCHECK(per_sample_iv_size == 0);
1015 uint32_t CencSampleEncryptionInfoEntry::ComputeSize()
const {
1016 return static_cast<uint32_t
>(
1017 sizeof(uint32_t) + kCencKeyIdSize +
1018 (constant_iv.empty() ? 0 : (
sizeof(uint8_t) + constant_iv.size())));
1021 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
1022 RCHECK(buffer->ReadWriteInt16(&roll_distance));
1026 uint32_t AudioRollRecoveryEntry::ComputeSize()
const {
1027 return sizeof(roll_distance);
1030 SampleGroupDescription::SampleGroupDescription() =
default;
1031 SampleGroupDescription::~SampleGroupDescription() =
default;
1037 bool SampleGroupDescription::ReadWriteInternal(
BoxBuffer* buffer) {
1039 buffer->ReadWriteUInt32(&grouping_type));
1041 switch (grouping_type) {
1043 return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
1045 return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
1048 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1049 << FourCCToString(
static_cast<FourCC
>(grouping_type));
1054 template <
typename T>
1055 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
1056 std::vector<T>* entries) {
1057 uint32_t default_length = 0;
1058 if (!buffer->Reading()) {
1059 DCHECK(!entries->empty());
1060 default_length = (*entries)[0].ComputeSize();
1061 DCHECK_NE(default_length, 0u);
1064 RCHECK(buffer->ReadWriteUInt32(&default_length));
1066 NOTIMPLEMENTED() <<
"Unsupported SampleGroupDescriptionBox 'sgpd' version "
1067 <<
static_cast<int>(version);
1071 uint32_t count =
static_cast<uint32_t
>(entries->size());
1072 RCHECK(buffer->ReadWriteUInt32(&count));
1073 if (buffer->Reading()) {
1079 entries->resize(count);
1081 for (T& entry : *entries) {
1083 uint32_t description_length = default_length;
1084 if (buffer->Reading() && default_length == 0)
1085 RCHECK(buffer->ReadWriteUInt32(&description_length));
1086 RCHECK(entry.ReadWrite(buffer));
1087 RCHECK(entry.ComputeSize() == description_length);
1089 RCHECK(entry.ReadWrite(buffer));
1095 size_t SampleGroupDescription::ComputeSizeInternal() {
1098 size_t entries_size = 0;
1099 switch (grouping_type) {
1101 for (
const auto& entry : cenc_sample_encryption_info_entries)
1102 entries_size += entry.ComputeSize();
1105 for (
const auto& entry : audio_roll_recovery_entries)
1106 entries_size += entry.ComputeSize();
1110 if (entries_size == 0)
1112 return HeaderSize() +
sizeof(grouping_type) +
1113 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1117 SampleToGroup::SampleToGroup() =
default;
1118 SampleToGroup::~SampleToGroup() =
default;
1124 bool SampleToGroup::ReadWriteInternal(
BoxBuffer* buffer) {
1126 buffer->ReadWriteUInt32(&grouping_type));
1128 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1130 if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
1132 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1133 << FourCCToString(
static_cast<FourCC
>(grouping_type));
1137 uint32_t count =
static_cast<uint32_t
>(entries.size());
1138 RCHECK(buffer->ReadWriteUInt32(&count));
1139 entries.resize(count);
1140 for (uint32_t i = 0; i < count; ++i) {
1141 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1142 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1147 size_t SampleToGroup::ComputeSizeInternal() {
1149 if (entries.empty())
1151 return HeaderSize() +
sizeof(grouping_type) +
1152 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1153 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1156 SampleTable::SampleTable() =
default;
1157 SampleTable::~SampleTable() =
default;
1163 bool SampleTable::ReadWriteInternal(
BoxBuffer* buffer) {
1176 RCHECK(reader->
ReadChild(&sample_size));
1178 CompactSampleSize compact_sample_size;
1179 RCHECK(reader->
ReadChild(&compact_sample_size));
1180 sample_size.sample_size = 0;
1181 sample_size.sample_count =
1182 static_cast<uint32_t
>(compact_sample_size.sizes.size());
1183 sample_size.sizes.swap(compact_sample_size.sizes);
1187 if (reader->
ChildExist(&chunk_large_offset)) {
1188 RCHECK(reader->
ReadChild(&chunk_large_offset));
1190 ChunkOffset chunk_offset;
1191 RCHECK(reader->
ReadChild(&chunk_offset));
1192 chunk_large_offset.offsets.swap(chunk_offset.offsets);
1203 for (
auto& sample_group_description : sample_group_descriptions)
1205 for (
auto& sample_to_group : sample_to_groups)
1211 size_t SampleTable::ComputeSizeInternal() {
1218 for (
auto& sample_group_description : sample_group_descriptions)
1219 box_size += sample_group_description.ComputeSize();
1220 for (
auto& sample_to_group : sample_to_groups)
1221 box_size += sample_to_group.ComputeSize();
1225 EditList::EditList() =
default;
1226 EditList::~EditList() =
default;
1232 bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
1233 uint32_t count =
static_cast<uint32_t
>(edits.size());
1235 edits.resize(count);
1237 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1238 for (uint32_t i = 0; i < count; ++i) {
1241 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1242 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1243 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1248 size_t EditList::ComputeSizeInternal() {
1254 for (uint32_t i = 0; i < edits.size(); ++i) {
1255 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1261 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
1265 Edit::Edit() =
default;
1266 Edit::~Edit() =
default;
1272 bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
1277 size_t Edit::ComputeSizeInternal() {
1279 if (list.edits.empty())
1284 HandlerReference::HandlerReference() =
default;
1285 HandlerReference::~HandlerReference() =
default;
1291 bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
1292 std::vector<uint8_t> handler_name;
1294 switch (handler_type) {
1296 handler_name.assign(kVideoHandlerName,
1297 kVideoHandlerName + std::size(kVideoHandlerName));
1300 handler_name.assign(kAudioHandlerName,
1301 kAudioHandlerName + std::size(kAudioHandlerName));
1304 handler_name.assign(kTextHandlerName,
1305 kTextHandlerName + std::size(kTextHandlerName));
1308 handler_name.assign(
1309 kSubtitleHandlerName,
1310 kSubtitleHandlerName + std::size(kSubtitleHandlerName));
1321 buffer->ReadWriteFourCC(&handler_type));
1324 buffer->ReadWriteVector(&handler_name, handler_name.size()));
1329 size_t HandlerReference::ComputeSizeInternal() {
1331 switch (handler_type) {
1333 box_size +=
sizeof(kVideoHandlerName);
1336 box_size +=
sizeof(kAudioHandlerName);
1339 box_size +=
sizeof(kTextHandlerName);
1342 box_size +=
sizeof(kSubtitleHandlerName);
1352 bool Language::ReadWrite(BoxBuffer* buffer) {
1353 if (buffer->Reading()) {
1356 std::vector<uint8_t> temp;
1357 RCHECK(buffer->ReadWriteVector(&temp, 2));
1359 BitReader bit_reader(&temp[0], 2);
1360 bit_reader.SkipBits(1);
1362 for (
int i = 0; i < 3; ++i) {
1363 CHECK(bit_reader.ReadBits(5, &language[i]));
1364 language[i] += 0x60;
1366 code.assign(language, 3);
1369 const char kUndefinedLanguage[] =
"und";
1371 code = kUndefinedLanguage;
1372 DCHECK_EQ(code.size(), 3u);
1376 for (
int i = 0; i < 3; ++i)
1377 lang |= (code[i] - 0x60) << ((2 - i) * 5);
1378 RCHECK(buffer->ReadWriteUInt16(&lang));
1383 uint32_t Language::ComputeSize()
const {
1388 ID3v2::ID3v2() =
default;
1389 ID3v2::~ID3v2() =
default;
1395 bool ID3v2::ReadWriteInternal(
BoxBuffer* buffer) {
1397 buffer->ReadWriteVector(&id3v2_data, buffer->
Reading()
1399 : id3v2_data.size()));
1403 size_t ID3v2::ComputeSizeInternal() {
1405 return id3v2_data.size() == 0
1407 :
HeaderSize() + language.ComputeSize() + id3v2_data.size();
1410 Metadata::Metadata() =
default;
1411 Metadata::~Metadata() =
default;
1417 bool Metadata::ReadWriteInternal(
BoxBuffer* buffer) {
1423 size_t Metadata::ComputeSizeInternal() {
1426 return id3v2_size == 0 ? 0
1430 CodecConfiguration::CodecConfiguration() =
default;
1431 CodecConfiguration::~CodecConfiguration() =
default;
1439 bool CodecConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1440 DCHECK_NE(box_type, FOURCC_NULL);
1445 if (box_type == FOURCC_vpcC) {
1447 uint8_t vpcc_version = 1;
1448 uint32_t version_flags = vpcc_version << 24;
1449 RCHECK(buffer->ReadWriteUInt32(&version_flags));
1450 vpcc_version = version_flags >> 24;
1451 RCHECK(vpcc_version == 1);
1455 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1457 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1462 size_t CodecConfiguration::ComputeSizeInternal() {
1465 DCHECK_NE(box_type, FOURCC_NULL);
1466 return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1469 ColorParameters::ColorParameters() =
default;
1470 ColorParameters::~ColorParameters() =
default;
1476 bool ColorParameters::ReadWriteInternal(
BoxBuffer* buffer) {
1482 raw_box.assign(reader->data(), reader->data() + reader->size());
1485 RCHECK(reader->ReadFourCC(&color_parameter_type) &&
1486 reader->Read2(&color_primaries) &&
1487 reader->Read2(&transfer_characteristics) &&
1488 reader->Read2(&matrix_coefficients));
1491 if (color_parameter_type == FOURCC_nclx) {
1492 RCHECK(reader->
Read1(&video_full_range_flag));
1496 DCHECK(!raw_box.empty());
1497 buffer->
writer()->AppendVector(raw_box);
1502 size_t ColorParameters::ComputeSizeInternal() {
1503 return raw_box.size();
1506 PixelAspectRatio::PixelAspectRatio() =
default;
1507 PixelAspectRatio::~PixelAspectRatio() =
default;
1513 bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
1515 buffer->ReadWriteUInt32(&h_spacing) &&
1516 buffer->ReadWriteUInt32(&v_spacing));
1520 size_t PixelAspectRatio::ComputeSizeInternal() {
1522 if (h_spacing == 0 && v_spacing == 0)
1525 DCHECK(h_spacing != 0 && v_spacing != 0);
1526 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
1529 VideoSampleEntry::VideoSampleEntry() =
default;
1530 VideoSampleEntry::~VideoSampleEntry() =
default;
1533 if (format == FOURCC_NULL) {
1534 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
1535 <<
"handler type recovered in its Media ancestor.";
1540 bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1541 std::vector<uint8_t> compressor_name;
1543 DCHECK(buffer->
reader());
1544 format = buffer->
reader()->type();
1548 const FourCC actual_format = GetActualFormat();
1549 switch (actual_format) {
1551 compressor_name.assign(std::begin(kAv1CompressorName),
1552 std::end(kAv1CompressorName));
1556 compressor_name.assign(std::begin(kAvcCompressorName),
1557 std::end(kAvcCompressorName));
1561 compressor_name.assign(std::begin(kDolbyVisionCompressorName),
1562 std::end(kDolbyVisionCompressorName));
1566 compressor_name.assign(std::begin(kHevcCompressorName),
1567 std::end(kHevcCompressorName));
1571 compressor_name.assign(std::begin(kVpcCompressorName),
1572 std::end(kVpcCompressorName));
1575 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
1578 compressor_name.resize(kCompressorNameSize);
1581 uint32_t video_resolution = kVideoResolution;
1582 uint16_t video_frame_count = kVideoFrameCount;
1583 uint16_t video_depth = kVideoDepth;
1584 int16_t predefined = -1;
1586 buffer->ReadWriteUInt16(&data_reference_index) &&
1588 buffer->ReadWriteUInt16(&width) && buffer->ReadWriteUInt16(&height) &&
1589 buffer->ReadWriteUInt32(&video_resolution) &&
1590 buffer->ReadWriteUInt32(&video_resolution) &&
1592 buffer->ReadWriteUInt16(&video_frame_count) &&
1593 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1594 buffer->ReadWriteUInt16(&video_depth) &&
1595 buffer->ReadWriteInt16(&predefined));
1602 if (format == FOURCC_encv && buffer->
Reading()) {
1605 while (!IsProtectionSchemeSupported(sinf.type.type))
1609 const FourCC actual_format = GetActualFormat();
1611 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1613 DCHECK_EQ(codec_configuration.box_type,
1614 GetCodecConfigurationBoxType(actual_format));
1616 if (codec_configuration.box_type == FOURCC_NULL)
1622 extra_codec_configs.clear();
1624 const bool is_hevc =
1625 actual_format == FOURCC_dvhe || actual_format == FOURCC_dvh1 ||
1626 actual_format == FOURCC_hev1 || actual_format == FOURCC_hvc1;
1628 for (FourCC fourcc : {FOURCC_dvcC, FOURCC_dvvC, FOURCC_hvcE}) {
1629 CodecConfiguration dv_box;
1630 dv_box.box_type = fourcc;
1632 if (!dv_box.data.empty())
1633 extra_codec_configs.push_back(std::move(dv_box));
1636 const bool is_av1 = actual_format == FOURCC_av01;
1638 for (FourCC fourcc : {FOURCC_dvvC}) {
1639 CodecConfiguration dv_box;
1640 dv_box.box_type = fourcc;
1642 if (!dv_box.data.empty())
1643 extra_codec_configs.push_back(std::move(dv_box));
1647 for (CodecConfiguration& extra_codec_config : extra_codec_configs)
1657 if (format == FOURCC_encv && !buffer->
Reading()) {
1658 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1664 size_t VideoSampleEntry::ComputeSizeInternal() {
1665 const FourCC actual_format = GetActualFormat();
1666 if (actual_format == FOURCC_NULL)
1668 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1669 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1670 size_t size =
HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
1671 sizeof(height) +
sizeof(kVideoResolution) * 2 +
1672 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
1675 kCompressorNameSize + 6 + 4 + 16 +
1677 for (CodecConfiguration& codec_config : extra_codec_configs)
1678 size += codec_config.ComputeSize();
1682 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC l_format)
const {
1698 LOG(ERROR) << FourCCToString(l_format) <<
" is not supported.";
1703 std::vector<uint8_t> VideoSampleEntry::ExtraCodecConfigsAsVector()
const {
1704 BufferWriter buffer;
1705 for (CodecConfiguration codec_config : extra_codec_configs)
1706 codec_config.Write(&buffer);
1707 return std::vector<uint8_t>(buffer.Buffer(), buffer.Buffer() + buffer.Size());
1710 bool VideoSampleEntry::ParseExtraCodecConfigsVector(
1711 const std::vector<uint8_t>& data) {
1712 extra_codec_configs.clear();
1714 while (pos < data.size()) {
1716 std::unique_ptr<BoxReader> box_reader(
1718 RCHECK(!err && box_reader);
1720 CodecConfiguration codec_config;
1721 codec_config.box_type = box_reader->type();
1722 RCHECK(codec_config.Parse(box_reader.get()));
1723 extra_codec_configs.push_back(std::move(codec_config));
1725 pos += box_reader->pos();
1730 ElementaryStreamDescriptor::ElementaryStreamDescriptor() =
default;
1731 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() =
default;
1737 bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
1740 std::vector<uint8_t> data;
1741 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1742 RCHECK(es_descriptor.
Parse(data));
1743 if (es_descriptor.decoder_config_descriptor().
IsAAC()) {
1744 RCHECK(aac_audio_specific_config.
Parse(
1745 es_descriptor.decoder_config_descriptor()
1746 .decoder_specific_info_descriptor()
1750 DCHECK(buffer->
writer());
1756 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1758 if (es_descriptor.decoder_config_descriptor().object_type() ==
1759 ObjectType::kForbidden) {
1765 MHAConfiguration::MHAConfiguration() =
default;
1766 MHAConfiguration::~MHAConfiguration() =
default;
1772 bool MHAConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1774 buffer->ReadWriteVector(
1776 RCHECK(data.size() > 1);
1777 mpeg_h_3da_profile_level_indication = data[1];
1781 size_t MHAConfiguration::ComputeSizeInternal() {
1788 DTSSpecific::DTSSpecific() =
default;
1789 DTSSpecific::~DTSSpecific() =
default;
1796 bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1798 buffer->ReadWriteUInt32(&sampling_frequency) &&
1799 buffer->ReadWriteUInt32(&max_bitrate) &&
1800 buffer->ReadWriteUInt32(&avg_bitrate) &&
1801 buffer->ReadWriteUInt8(&pcm_sample_depth));
1804 RCHECK(buffer->ReadWriteVector(&extra_data, buffer->
BytesLeft()));
1806 if (extra_data.empty()) {
1807 extra_data.assign(kDdtsExtraData,
1808 kDdtsExtraData +
sizeof(kDdtsExtraData));
1810 RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1815 size_t DTSSpecific::ComputeSizeInternal() {
1817 if (sampling_frequency == 0)
1819 return HeaderSize() +
sizeof(sampling_frequency) +
sizeof(max_bitrate) +
1820 sizeof(avg_bitrate) +
sizeof(pcm_sample_depth) +
1821 sizeof(kDdtsExtraData);
1824 UDTSSpecific::UDTSSpecific() =
default;
1825 UDTSSpecific::~UDTSSpecific() =
default;
1831 bool UDTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1833 buffer->ReadWriteVector(
1838 size_t UDTSSpecific::ComputeSizeInternal() {
1845 AC3Specific::AC3Specific() =
default;
1846 AC3Specific::~AC3Specific() =
default;
1852 bool AC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1854 buffer->ReadWriteVector(
1859 size_t AC3Specific::ComputeSizeInternal() {
1866 EC3Specific::EC3Specific() =
default;
1867 EC3Specific::~EC3Specific() =
default;
1873 bool EC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1876 RCHECK(buffer->ReadWriteVector(&data, size));
1880 size_t EC3Specific::ComputeSizeInternal() {
1887 AC4Specific::AC4Specific() =
default;
1888 AC4Specific::~AC4Specific() =
default;
1894 bool AC4Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1897 RCHECK(buffer->ReadWriteVector(&data, size));
1901 size_t AC4Specific::ComputeSizeInternal() {
1908 OpusSpecific::OpusSpecific() =
default;
1909 OpusSpecific::~OpusSpecific() =
default;
1915 bool OpusSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1918 std::vector<uint8_t> data;
1919 const int kMinOpusSpecificBoxDataSize = 11;
1920 RCHECK(buffer->
BytesLeft() >= kMinOpusSpecificBoxDataSize);
1921 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1922 preskip = data[2] + (data[3] << 8);
1927 writer.AppendInt(FOURCC_Head);
1929 const uint8_t kOpusIdentificationHeaderVersion = 1;
1930 data[0] = kOpusIdentificationHeaderVersion;
1931 writer.AppendVector(data);
1932 writer.SwapBuffer(&opus_identification_header);
1936 const size_t kOpusMagicSignatureSize = 8u;
1937 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1940 const uint8_t kOpusSpecificBoxVersion = 0;
1942 buffer->
writer()->AppendArray(
1943 &opus_identification_header[kOpusMagicSignatureSize + 1],
1944 opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1949 size_t OpusSpecific::ComputeSizeInternal() {
1951 if (opus_identification_header.empty())
1955 const size_t kOpusMagicSignatureSize = 8u;
1956 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1957 return HeaderSize() + opus_identification_header.size() -
1958 kOpusMagicSignatureSize;
1961 IAMFSpecific::IAMFSpecific() =
default;
1962 IAMFSpecific::~IAMFSpecific() =
default;
1968 bool IAMFSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1971 RCHECK(buffer->ReadWriteVector(&data, size));
1975 size_t IAMFSpecific::ComputeSizeInternal() {
1982 FlacSpecific::FlacSpecific() =
default;
1983 FlacSpecific::~FlacSpecific() =
default;
1989 bool FlacSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1992 RCHECK(buffer->ReadWriteVector(&data, size));
1996 size_t FlacSpecific::ComputeSizeInternal() {
2003 ALACSpecific::ALACSpecific() =
default;
2004 ALACSpecific::~ALACSpecific() =
default;
2010 bool ALACSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
2013 RCHECK(buffer->ReadWriteVector(&data, size));
2017 size_t ALACSpecific::ComputeSizeInternal() {
2024 AudioSampleEntry::AudioSampleEntry() =
default;
2025 AudioSampleEntry::~AudioSampleEntry() =
default;
2028 if (format == FOURCC_NULL) {
2029 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
2030 <<
"handler type recovered in its Media ancestor.";
2035 bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
2037 DCHECK(buffer->
reader());
2038 format = buffer->
reader()->type();
2046 buffer->ReadWriteUInt16(&data_reference_index) &&
2048 buffer->ReadWriteUInt16(&channelcount) &&
2049 buffer->ReadWriteUInt16(&samplesize) &&
2051 buffer->ReadWriteUInt32(&samplerate));
2072 if (format == FOURCC_enca) {
2076 while (!IsProtectionSchemeSupported(sinf.type.type))
2079 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
2086 size_t AudioSampleEntry::ComputeSizeInternal() {
2087 if (GetActualFormat() == FOURCC_NULL)
2089 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
2090 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
2100 WebVTTConfigurationBox::WebVTTConfigurationBox() =
default;
2101 WebVTTConfigurationBox::~WebVTTConfigurationBox() =
default;
2107 bool WebVTTConfigurationBox::ReadWriteInternal(
BoxBuffer* buffer) {
2113 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
2117 WebVTTSourceLabelBox::WebVTTSourceLabelBox() =
default;
2118 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() =
default;
2124 bool WebVTTSourceLabelBox::ReadWriteInternal(
BoxBuffer* buffer) {
2128 : source_label.size());
2131 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
2132 if (source_label.empty())
2137 TextSampleEntry::TextSampleEntry() =
default;
2138 TextSampleEntry::~TextSampleEntry() =
default;
2141 if (format == FOURCC_NULL) {
2142 LOG(ERROR) <<
"TextSampleEntry should be parsed according to the "
2143 <<
"handler type recovered in its Media ancestor.";
2148 bool TextSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
2150 DCHECK(buffer->
reader());
2151 format = buffer->
reader()->type();
2156 buffer->ReadWriteUInt16(&data_reference_index));
2158 if (format == FOURCC_wvtt) {
2162 }
else if (format == FOURCC_stpp) {
2165 RCHECK(buffer->ReadWriteCString(&namespace_) &&
2166 buffer->ReadWriteCString(&schema_location));
2171 size_t TextSampleEntry::ComputeSizeInternal() {
2173 size_t ret =
HeaderSize() + 6 +
sizeof(data_reference_index);
2174 if (format == FOURCC_wvtt) {
2176 }
else if (format == FOURCC_stpp) {
2178 ret += namespace_.size() + schema_location.size() + 2;
2183 MediaHeader::MediaHeader() =
default;
2184 MediaHeader::~MediaHeader() =
default;
2190 bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2193 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2196 buffer->ReadWriteUInt32(×cale) &&
2198 language.ReadWrite(buffer) &&
2204 size_t MediaHeader::ComputeSizeInternal() {
2205 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
2207 sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
2211 VideoMediaHeader::VideoMediaHeader() {
2212 const uint32_t kVideoMediaHeaderFlags = 1;
2213 flags = kVideoMediaHeaderFlags;
2216 VideoMediaHeader::~VideoMediaHeader() =
default;
2221 bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2223 buffer->ReadWriteUInt16(&graphicsmode) &&
2224 buffer->ReadWriteUInt16(&opcolor_red) &&
2225 buffer->ReadWriteUInt16(&opcolor_green) &&
2226 buffer->ReadWriteUInt16(&opcolor_blue));
2230 size_t VideoMediaHeader::ComputeSizeInternal() {
2231 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
2232 sizeof(opcolor_green) +
sizeof(opcolor_blue);
2235 SoundMediaHeader::SoundMediaHeader() =
default;
2236 SoundMediaHeader::~SoundMediaHeader() =
default;
2242 bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2248 size_t SoundMediaHeader::ComputeSizeInternal() {
2249 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
2252 NullMediaHeader::NullMediaHeader() =
default;
2253 NullMediaHeader::~NullMediaHeader() =
default;
2259 bool NullMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2263 size_t NullMediaHeader::ComputeSizeInternal() {
2267 SubtitleMediaHeader::SubtitleMediaHeader() =
default;
2268 SubtitleMediaHeader::~SubtitleMediaHeader() =
default;
2274 bool SubtitleMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2278 size_t SubtitleMediaHeader::ComputeSizeInternal() {
2282 DataEntryUrl::DataEntryUrl() {
2283 const uint32_t kDataEntryUrlFlags = 1;
2284 flags = kDataEntryUrlFlags;
2287 DataEntryUrl::~DataEntryUrl() =
default;
2292 bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
2295 RCHECK(buffer->ReadWriteVector(&location, buffer->
BytesLeft()));
2297 RCHECK(buffer->ReadWriteVector(&location, location.size()));
2302 size_t DataEntryUrl::ComputeSizeInternal() {
2306 DataReference::DataReference() =
default;
2307 DataReference::~DataReference() =
default;
2312 bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
2313 uint32_t entry_count =
static_cast<uint32_t
>(data_entry.size());
2315 buffer->ReadWriteUInt32(&entry_count));
2316 data_entry.resize(entry_count);
2318 for (uint32_t i = 0; i < entry_count; ++i)
2323 size_t DataReference::ComputeSizeInternal() {
2324 uint32_t count =
static_cast<uint32_t
>(data_entry.size());
2326 for (uint32_t i = 0; i < count; ++i)
2331 DataInformation::DataInformation() =
default;
2332 DataInformation::~DataInformation() =
default;
2338 bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2343 size_t DataInformation::ComputeSizeInternal() {
2347 MediaInformation::MediaInformation() =
default;
2348 MediaInformation::~MediaInformation() =
default;
2354 bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2358 switch (sample_table.description.type) {
2378 size_t MediaInformation::ComputeSizeInternal() {
2381 switch (sample_table.description.type) {
2400 Media::Media() =
default;
2401 Media::~Media() =
default;
2407 bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
2418 information.sample_table.description.type =
2419 FourCCToTrackType(handler.handler_type);
2421 handler.handler_type =
2422 TrackTypeToFourCC(information.sample_table.description.type);
2423 RCHECK(handler.handler_type != FOURCC_NULL);
2430 size_t Media::ComputeSizeInternal() {
2431 handler.handler_type =
2432 TrackTypeToFourCC(information.sample_table.description.type);
2437 Track::Track() =
default;
2438 Track::~Track() =
default;
2444 bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
2452 size_t Track::ComputeSizeInternal() {
2457 MovieExtendsHeader::MovieExtendsHeader() =
default;
2458 MovieExtendsHeader::~MovieExtendsHeader() =
default;
2464 bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2466 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2471 size_t MovieExtendsHeader::ComputeSizeInternal() {
2473 if (fragment_duration == 0)
2475 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2476 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2479 TrackExtends::TrackExtends() =
default;
2480 TrackExtends::~TrackExtends() =
default;
2486 bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2488 buffer->ReadWriteUInt32(&track_id) &&
2489 buffer->ReadWriteUInt32(&default_sample_description_index) &&
2490 buffer->ReadWriteUInt32(&default_sample_duration) &&
2491 buffer->ReadWriteUInt32(&default_sample_size) &&
2492 buffer->ReadWriteUInt32(&default_sample_flags));
2496 size_t TrackExtends::ComputeSizeInternal() {
2498 sizeof(default_sample_description_index) +
2499 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
2500 sizeof(default_sample_flags);
2503 MovieExtends::MovieExtends() =
default;
2504 MovieExtends::~MovieExtends() =
default;
2510 bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2514 DCHECK(buffer->
reader());
2517 for (uint32_t i = 0; i < tracks.size(); ++i)
2523 size_t MovieExtends::ComputeSizeInternal() {
2525 if (tracks.size() == 0)
2528 for (uint32_t i = 0; i < tracks.size(); ++i)
2533 Movie::Movie() =
default;
2534 Movie::~Movie() =
default;
2540 bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
2556 if (absl::GetFlag(FLAGS_mvex_before_trak)) {
2563 for (uint32_t i = 0; i < tracks.size(); ++i)
2565 if (!absl::GetFlag(FLAGS_mvex_before_trak)) {
2568 for (uint32_t i = 0; i < pssh.size(); ++i)
2574 size_t Movie::ComputeSizeInternal() {
2577 for (uint32_t i = 0; i < tracks.size(); ++i)
2579 for (uint32_t i = 0; i < pssh.size(); ++i)
2584 TrackFragmentDecodeTime::TrackFragmentDecodeTime() =
default;
2585 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() =
default;
2591 bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
2593 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2598 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2599 version = IsFitIn32Bits(decode_time) ? 0 : 1;
2600 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2603 MovieFragmentHeader::MovieFragmentHeader() =
default;
2604 MovieFragmentHeader::~MovieFragmentHeader() =
default;
2610 bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2612 buffer->ReadWriteUInt32(&sequence_number);
2615 size_t MovieFragmentHeader::ComputeSizeInternal() {
2616 return HeaderSize() +
sizeof(sequence_number);
2619 TrackFragmentHeader::TrackFragmentHeader() =
default;
2620 TrackFragmentHeader::~TrackFragmentHeader() =
default;
2626 bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2629 if (flags & kBaseDataOffsetPresentMask) {
2634 uint64_t base_data_offset;
2635 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2636 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
2637 "default-base-is-moof.";
2640 if (flags & kSampleDescriptionIndexPresentMask) {
2641 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2642 }
else if (buffer->
Reading()) {
2643 sample_description_index = 0;
2646 if (flags & kDefaultSampleDurationPresentMask) {
2647 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2648 }
else if (buffer->
Reading()) {
2649 default_sample_duration = 0;
2652 if (flags & kDefaultSampleSizePresentMask) {
2653 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2654 }
else if (buffer->
Reading()) {
2655 default_sample_size = 0;
2658 if (flags & kDefaultSampleFlagsPresentMask)
2659 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2663 size_t TrackFragmentHeader::ComputeSizeInternal() {
2665 if (flags & kSampleDescriptionIndexPresentMask)
2666 box_size +=
sizeof(sample_description_index);
2667 if (flags & kDefaultSampleDurationPresentMask)
2668 box_size +=
sizeof(default_sample_duration);
2669 if (flags & kDefaultSampleSizePresentMask)
2670 box_size +=
sizeof(default_sample_size);
2671 if (flags & kDefaultSampleFlagsPresentMask)
2672 box_size +=
sizeof(default_sample_flags);
2676 TrackFragmentRun::TrackFragmentRun() =
default;
2677 TrackFragmentRun::~TrackFragmentRun() =
default;
2683 bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
2689 if (flags & kSampleCompTimeOffsetsPresentMask) {
2690 for (uint32_t i = 0; i < sample_count; ++i) {
2691 if (sample_composition_time_offsets[i] < 0) {
2700 buffer->ReadWriteUInt32(&sample_count));
2702 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2703 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2704 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2705 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2706 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2707 bool sample_composition_time_offsets_present =
2708 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2710 if (data_offset_present) {
2711 RCHECK(buffer->ReadWriteUInt32(&data_offset));
2722 uint32_t first_sample_flags(0);
2725 if (first_sample_flags_present)
2726 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2728 if (sample_duration_present)
2729 sample_durations.resize(sample_count);
2730 if (sample_size_present)
2731 sample_sizes.resize(sample_count);
2732 if (sample_flags_present)
2733 sample_flags.resize(sample_count);
2734 if (sample_composition_time_offsets_present)
2735 sample_composition_time_offsets.resize(sample_count);
2737 if (first_sample_flags_present) {
2738 first_sample_flags = sample_flags[0];
2739 DCHECK(sample_flags.size() == 1);
2740 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2743 if (sample_duration_present)
2744 DCHECK(sample_durations.size() == sample_count);
2745 if (sample_size_present)
2746 DCHECK(sample_sizes.size() == sample_count);
2747 if (sample_flags_present)
2748 DCHECK(sample_flags.size() == sample_count);
2749 if (sample_composition_time_offsets_present)
2750 DCHECK(sample_composition_time_offsets.size() == sample_count);
2753 for (uint32_t i = 0; i < sample_count; ++i) {
2754 if (sample_duration_present)
2755 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2756 if (sample_size_present)
2757 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2758 if (sample_flags_present)
2759 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2761 if (sample_composition_time_offsets_present) {
2763 uint32_t sample_offset = sample_composition_time_offsets[i];
2764 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2765 sample_composition_time_offsets[i] = sample_offset;
2767 int32_t sample_offset = sample_composition_time_offsets[i];
2768 RCHECK(buffer->ReadWriteInt32(&sample_offset));
2769 sample_composition_time_offsets[i] = sample_offset;
2775 if (first_sample_flags_present) {
2776 if (sample_flags.size() == 0) {
2777 sample_flags.push_back(first_sample_flags);
2779 sample_flags[0] = first_sample_flags;
2786 size_t TrackFragmentRun::ComputeSizeInternal() {
2788 if (flags & kDataOffsetPresentMask)
2790 if (flags & kFirstSampleFlagsPresentMask)
2792 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2793 (flags & kSampleSizePresentMask ? 1 : 0) +
2794 (flags & kSampleFlagsPresentMask ? 1 : 0) +
2795 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2796 box_size += fields *
sizeof(uint32_t) * sample_count;
2800 TrackFragment::TrackFragment() =
default;
2801 TrackFragment::~TrackFragment() =
default;
2807 bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2811 DCHECK(buffer->
reader());
2813 if (!decode_time_absent)
2819 if (!decode_time_absent)
2821 for (uint32_t i = 0; i < runs.size(); ++i)
2823 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2825 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2833 size_t TrackFragment::ComputeSizeInternal() {
2838 for (uint32_t i = 0; i < runs.size(); ++i)
2840 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2842 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2847 MovieFragment::MovieFragment() =
default;
2848 MovieFragment::~MovieFragment() =
default;
2854 bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2862 for (uint32_t i = 0; i < tracks.size(); ++i)
2864 for (uint32_t i = 0; i < pssh.size(); ++i)
2870 size_t MovieFragment::ComputeSizeInternal() {
2872 for (uint32_t i = 0; i < tracks.size(); ++i)
2874 for (uint32_t i = 0; i < pssh.size(); ++i)
2879 SegmentIndex::SegmentIndex() =
default;
2880 SegmentIndex::~SegmentIndex() =
default;
2886 bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
2888 buffer->ReadWriteUInt32(&reference_id) &&
2889 buffer->ReadWriteUInt32(×cale));
2891 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2896 uint16_t reference_count;
2897 if (references.size() <= std::numeric_limits<uint16_t>::max()) {
2898 reference_count =
static_cast<uint16_t
>(references.size());
2900 reference_count = std::numeric_limits<uint16_t>::max();
2901 LOG(WARNING) <<
"Seeing " << references.size()
2902 <<
" subsegment references, but at most " << reference_count
2903 <<
" references can be stored in 'sidx' box."
2904 <<
" The extra references are truncated.";
2905 LOG(WARNING) <<
"The stream will not play to the end in DASH.";
2906 LOG(WARNING) <<
"A possible workaround is to increase segment duration.";
2909 buffer->ReadWriteUInt16(&reference_count));
2911 references.resize(reference_count);
2913 uint32_t reference_type_size;
2915 for (uint32_t i = 0; i < reference_count; ++i) {
2917 reference_type_size = references[i].referenced_size;
2918 if (references[i].reference_type)
2919 reference_type_size |= (1 << 31);
2920 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2921 if (references[i].starts_with_sap)
2924 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2925 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2926 buffer->ReadWriteUInt32(&sap));
2928 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
2929 references[i].referenced_size = reference_type_size & ~(1 << 31);
2930 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
2931 references[i].sap_type =
2932 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
2933 references[i].sap_delta_time = sap & ~(0xF << 28);
2939 size_t SegmentIndex::ComputeSizeInternal() {
2940 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2941 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
2942 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
2943 3 *
sizeof(uint32_t) *
2946 static_cast<size_t>(std::numeric_limits<uint16_t>::max()));
2949 MediaData::MediaData() =
default;
2950 MediaData::~MediaData() =
default;
2956 bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
2957 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
2961 size_t MediaData::ComputeSizeInternal() {
2965 CueSourceIDBox::CueSourceIDBox() =
default;
2966 CueSourceIDBox::~CueSourceIDBox() =
default;
2972 bool CueSourceIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
2977 size_t CueSourceIDBox::ComputeSizeInternal() {
2978 if (source_id == kCueSourceIdNotSet)
2983 CueTimeBox::CueTimeBox() =
default;
2984 CueTimeBox::~CueTimeBox() =
default;
2990 bool CueTimeBox::ReadWriteInternal(
BoxBuffer* buffer) {
2997 size_t CueTimeBox::ComputeSizeInternal() {
2998 if (cue_current_time.empty())
3000 return HeaderSize() + cue_current_time.size();
3003 CueIDBox::CueIDBox() =
default;
3004 CueIDBox::~CueIDBox() =
default;
3010 bool CueIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
3016 size_t CueIDBox::ComputeSizeInternal() {
3022 CueSettingsBox::CueSettingsBox() =
default;
3023 CueSettingsBox::~CueSettingsBox() =
default;
3029 bool CueSettingsBox::ReadWriteInternal(
BoxBuffer* buffer) {
3035 size_t CueSettingsBox::ComputeSizeInternal() {
3036 if (settings.empty())
3041 CuePayloadBox::CuePayloadBox() =
default;
3042 CuePayloadBox::~CuePayloadBox() =
default;
3048 bool CuePayloadBox::ReadWriteInternal(
BoxBuffer* buffer) {
3054 size_t CuePayloadBox::ComputeSizeInternal() {
3058 VTTEmptyCueBox::VTTEmptyCueBox() =
default;
3059 VTTEmptyCueBox::~VTTEmptyCueBox() =
default;
3065 bool VTTEmptyCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
3069 size_t VTTEmptyCueBox::ComputeSizeInternal() {
3073 VTTAdditionalTextBox::VTTAdditionalTextBox() =
default;
3074 VTTAdditionalTextBox::~VTTAdditionalTextBox() =
default;
3080 bool VTTAdditionalTextBox::ReadWriteInternal(
BoxBuffer* buffer) {
3083 &cue_additional_text,
3087 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
3088 return HeaderSize() + cue_additional_text.size();
3091 VTTCueBox::VTTCueBox() =
default;
3092 VTTCueBox::~VTTCueBox() =
default;
3098 bool VTTCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
3108 size_t VTTCueBox::ComputeSizeInternal() {
All the methods that are virtual are virtual for mocking.
FourCC BoxType() const override
FourCC BoxType() const override
bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
uint32_t GetTotalSizeOfSubsamples() const
uint32_t ComputeSize() const
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override