5#include <packager/media/formats/mp4/box_definitions.h>
16#include <absl/flags/flag.h>
17#include <absl/log/check.h>
18#include <absl/log/log.h>
20#include <packager/macros/logging.h>
21#include <packager/media/base/bit_reader.h>
22#include <packager/media/base/buffer_writer.h>
23#include <packager/media/base/fourccs.h>
24#include <packager/media/base/rcheck.h>
25#include <packager/media/codecs/es_descriptor.h>
26#include <packager/media/formats/mp4/box_buffer.h>
27#include <packager/media/formats/mp4/box_reader.h>
32 "Android MediaExtractor requires mvex to be written before trak. "
33 "Set the flag to true to comply with the requirement.");
36const uint32_t kFourCCSize = 4;
39const uint32_t kCencKeyIdSize = 16;
42const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
47const char kVideoHandlerName[] =
"VideoHandler";
48const char kAudioHandlerName[] =
"SoundHandler";
49const char kTextHandlerName[] =
"TextHandler";
50const char kSubtitleHandlerName[] =
"SubtitleHandler";
53const uint32_t kVideoResolution = 0x00480000;
54const uint16_t kVideoFrameCount = 1;
55const uint16_t kVideoDepth = 0x0018;
57const uint32_t kCompressorNameSize = 32u;
58const char kAv1CompressorName[] =
"\012AOM Coding";
59const char kAvcCompressorName[] =
"\012AVC Coding";
60const char kDolbyVisionCompressorName[] =
"\013DOVI Coding";
61const char kHevcCompressorName[] =
"\013HEVC Coding";
62const char kVpcCompressorName[] =
"\012VPC Coding";
67bool IsIvSizeValid(uint8_t per_sample_iv_size) {
68 return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
69 per_sample_iv_size == 16;
86const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
89bool IsFitIn32Bits(uint64_t a) {
90 return a <= std::numeric_limits<uint32_t>::max();
93bool IsFitIn32Bits(int64_t a) {
94 return a <= std::numeric_limits<int32_t>::max() &&
95 a >= std::numeric_limits<int32_t>::min();
98template <
typename T1,
typename T2>
99bool IsFitIn32Bits(T1 a1, T2 a2) {
100 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
103template <
typename T1,
typename T2,
typename T3>
104bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
105 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
116TrackType FourCCToTrackType(FourCC fourcc) {
131FourCC TrackTypeToFourCC(TrackType track_type) {
132 switch (track_type) {
146bool IsProtectionSchemeSupported(FourCC scheme) {
147 return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
148 scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
153FileType::FileType() =
default;
154FileType::~FileType() =
default;
160bool FileType::ReadWriteInternal(
BoxBuffer* buffer) {
162 buffer->ReadWriteFourCC(&major_brand) &&
163 buffer->ReadWriteUInt32(&minor_version));
166 RCHECK(buffer->
BytesLeft() %
sizeof(FourCC) == 0);
167 num_brands = buffer->
BytesLeft() /
sizeof(FourCC);
168 compatible_brands.resize(num_brands);
170 num_brands = compatible_brands.size();
172 for (
size_t i = 0; i < num_brands; ++i)
173 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
177size_t FileType::ComputeSizeInternal() {
178 return HeaderSize() + kFourCCSize +
sizeof(minor_version) +
179 kFourCCSize * compatible_brands.size();
186ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() =
default;
187ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() =
default;
193bool ProtectionSystemSpecificHeader::ReadWriteInternal(
BoxBuffer* buffer) {
197 raw_box.assign(reader->data(), reader->data() + reader->size());
199 DCHECK(!raw_box.empty());
200 buffer->
writer()->AppendVector(raw_box);
206size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
207 return raw_box.size();
210SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() =
default;
211SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() =
default;
217bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
222 uint32_t count =
static_cast<uint32_t
>(offsets.size());
223 RCHECK(buffer->ReadWriteUInt32(&count));
224 offsets.resize(count);
226 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
227 for (uint32_t i = 0; i < count; ++i)
232size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
234 if (offsets.size() == 0)
236 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
237 return HeaderSize() +
sizeof(uint32_t) + num_bytes * offsets.size();
240SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() =
default;
241SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() =
default;
247bool SampleAuxiliaryInformationSize::ReadWriteInternal(
BoxBuffer* buffer) {
252 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
253 buffer->ReadWriteUInt32(&sample_count));
254 if (default_sample_info_size == 0)
255 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
259size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
261 if (sample_count == 0)
263 return HeaderSize() +
sizeof(default_sample_info_size) +
264 sizeof(sample_count) +
265 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
271 DCHECK(IsIvSizeValid(iv_size));
274 RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
276 if (!has_subsamples) {
281 uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
282 RCHECK(buffer->ReadWriteUInt16(&subsample_count));
283 RCHECK(subsample_count > 0);
284 subsamples.resize(subsample_count);
285 for (
auto& subsample : subsamples) {
286 RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
287 buffer->ReadWriteUInt32(&subsample.cipher_bytes));
295 DCHECK(IsIvSizeValid(iv_size));
298 initialization_vector.resize(iv_size);
299 RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
301 if (!has_subsamples) {
306 uint16_t subsample_count;
307 RCHECK(reader->Read2(&subsample_count));
308 RCHECK(subsample_count > 0);
309 subsamples.resize(subsample_count);
310 for (
auto& subsample : subsamples) {
311 RCHECK(reader->Read2(&subsample.clear_bytes) &&
312 reader->Read4(&subsample.cipher_bytes));
318 const uint32_t subsample_entry_size =
sizeof(uint16_t) +
sizeof(uint32_t);
319 const uint16_t subsample_count =
static_cast<uint16_t
>(subsamples.size());
320 return static_cast<uint32_t
>(
321 initialization_vector.size() +
323 ? (
sizeof(subsample_count) + subsample_entry_size * subsample_count)
329 for (uint32_t i = 0; i < subsamples.size(); ++i)
330 size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
334SampleEncryption::SampleEncryption() =
default;
335SampleEncryption::~SampleEncryption() =
default;
341bool SampleEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
346 if (buffer->
Reading() && iv_size == SampleEncryption::kInvalidIvSize) {
352 if (!IsIvSizeValid(iv_size)) {
354 <<
"IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
359 uint32_t sample_count =
360 static_cast<uint32_t
>(sample_encryption_entries.size());
361 RCHECK(buffer->ReadWriteUInt32(&sample_count));
363 sample_encryption_entries.resize(sample_count);
364 for (
auto& sample_encryption_entry : sample_encryption_entries) {
365 RCHECK(sample_encryption_entry.ReadWrite(
366 iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
371size_t SampleEncryption::ComputeSizeInternal() {
372 const uint32_t sample_count =
373 static_cast<uint32_t
>(sample_encryption_entries.size());
374 if (sample_count == 0) {
379 DCHECK(IsIvSizeValid(iv_size));
381 if (flags & kUseSubsampleEncryption) {
382 for (
const SampleEncryptionEntry& sample_encryption_entry :
383 sample_encryption_entries) {
384 box_size += sample_encryption_entry.ComputeSize();
394 std::vector<SampleEncryptionEntry>* l_sample_encryption_entries)
const {
395 DCHECK(IsIvSizeValid(l_iv_size));
399 uint32_t sample_count = 0;
400 RCHECK(reader.Read4(&sample_count));
402 l_sample_encryption_entries->resize(sample_count);
403 for (
auto& sample_encryption_entry : *l_sample_encryption_entries) {
404 RCHECK(sample_encryption_entry.ParseFromBuffer(
405 l_iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) !=
411OriginalFormat::OriginalFormat() =
default;
412OriginalFormat::~OriginalFormat() =
default;
418bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
422size_t OriginalFormat::ComputeSizeInternal() {
426SchemeType::SchemeType() =
default;
427SchemeType::~SchemeType() =
default;
433bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
435 buffer->ReadWriteUInt32(&version));
439size_t SchemeType::ComputeSizeInternal() {
440 return HeaderSize() + kFourCCSize +
sizeof(version);
443TrackEncryption::TrackEncryption() =
default;
444TrackEncryption::~TrackEncryption() =
default;
450bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
452 if (default_kid.size() != kCencKeyIdSize) {
453 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
454 <<
" bytes; got " << default_kid.size()
455 <<
". Resized accordingly.";
456 default_kid.resize(kCencKeyIdSize);
458 RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
459 if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
468 uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
469 RCHECK(buffer->ReadWriteUInt8(&pattern));
470 default_crypt_byte_block = pattern >> 4;
471 default_skip_byte_block = pattern & 0x0F;
473 RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
474 buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
475 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
477 if (default_is_protected == 1) {
478 if (default_per_sample_iv_size == 0) {
479 uint8_t default_constant_iv_size =
480 static_cast<uint8_t
>(default_constant_iv.size());
481 RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
482 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
483 RCHECK(buffer->ReadWriteVector(&default_constant_iv,
484 default_constant_iv_size));
486 RCHECK(default_per_sample_iv_size == 8 ||
487 default_per_sample_iv_size == 16);
488 RCHECK(default_constant_iv.empty());
493 RCHECK(default_is_protected == 0);
494 RCHECK(default_per_sample_iv_size == 0);
495 RCHECK(default_constant_iv.empty());
500size_t TrackEncryption::ComputeSizeInternal() {
501 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize +
502 (default_constant_iv.empty()
504 : (
sizeof(uint8_t) + default_constant_iv.size()));
507SchemeInfo::SchemeInfo() =
default;
508SchemeInfo::~SchemeInfo() =
default;
514bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
520size_t SchemeInfo::ComputeSizeInternal() {
524ProtectionSchemeInfo::ProtectionSchemeInfo() =
default;
525ProtectionSchemeInfo::~ProtectionSchemeInfo() =
default;
531bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
534 if (IsProtectionSchemeSupported(type.type)) {
537 DLOG(WARNING) <<
"Ignore unsupported protection scheme: "
538 << FourCCToString(type.type);
547size_t ProtectionSchemeInfo::ComputeSizeInternal() {
549 if (format.format == FOURCC_NULL)
555MovieHeader::MovieHeader() =
default;
556MovieHeader::~MovieHeader() =
default;
562bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
565 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
568 buffer->ReadWriteUInt32(×cale) &&
571 std::vector<uint8_t> matrix(kUnityMatrix,
572 kUnityMatrix + std::size(kUnityMatrix));
573 RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
575 buffer->ReadWriteVector(&matrix, matrix.size()) &&
577 buffer->ReadWriteUInt32(&next_track_id));
581size_t MovieHeader::ComputeSizeInternal() {
582 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
583 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
584 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
585 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
589TrackHeader::TrackHeader() {
590 flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
593TrackHeader::~TrackHeader() =
default;
599bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
602 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
605 buffer->ReadWriteUInt32(&track_id) &&
612 volume = (width != 0 && height != 0) ? 0 : 0x100;
614 std::vector<uint8_t> matrix(kUnityMatrix,
615 kUnityMatrix + std::size(kUnityMatrix));
617 buffer->ReadWriteInt16(&layer) &&
618 buffer->ReadWriteInt16(&alternate_group) &&
619 buffer->ReadWriteInt16(&volume) &&
621 buffer->ReadWriteVector(&matrix, matrix.size()) &&
622 buffer->ReadWriteUInt32(&width) && buffer->ReadWriteUInt32(&height));
626size_t TrackHeader::ComputeSizeInternal() {
627 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
629 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
630 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
631 sizeof(height) +
sizeof(kUnityMatrix) + 14;
634SampleDescription::SampleDescription() =
default;
635SampleDescription::~SampleDescription() =
default;
641bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
645 count =
static_cast<uint32_t
>(video_entries.size());
648 count =
static_cast<uint32_t
>(audio_entries.size());
652 count =
static_cast<uint32_t
>(text_entries.size());
655 NOTIMPLEMENTED() <<
"SampleDecryption type " << type
656 <<
" is not handled. Skipping.";
661 BoxReader* reader = buffer->
reader();
663 video_entries.clear();
664 audio_entries.clear();
667 if (type == kVideo) {
668 RCHECK(reader->ReadAllChildren(&video_entries));
669 RCHECK(video_entries.size() == count);
670 }
else if (type == kAudio) {
671 RCHECK(reader->ReadAllChildren(&audio_entries));
672 RCHECK(audio_entries.size() == count);
673 }
else if (type == kText || type == kSubtitle) {
674 RCHECK(reader->ReadAllChildren(&text_entries));
675 RCHECK(text_entries.size() == count);
678 DCHECK_LT(0u, count);
679 if (type == kVideo) {
680 for (uint32_t i = 0; i < count; ++i)
682 }
else if (type == kAudio) {
683 for (uint32_t i = 0; i < count; ++i)
685 }
else if (type == kText || type == kSubtitle) {
686 for (uint32_t i = 0; i < count; ++i)
695size_t SampleDescription::ComputeSizeInternal() {
697 if (type == kVideo) {
698 for (uint32_t i = 0; i < video_entries.size(); ++i)
700 }
else if (type == kAudio) {
701 for (uint32_t i = 0; i < audio_entries.size(); ++i)
703 }
else if (type == kText || type == kSubtitle) {
704 for (uint32_t i = 0; i < text_entries.size(); ++i)
710DecodingTimeToSample::DecodingTimeToSample() =
default;
711DecodingTimeToSample::~DecodingTimeToSample() =
default;
717bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
718 uint32_t count =
static_cast<uint32_t
>(decoding_time.size());
722 RCHECK(count <= buffer->BytesLeft() /
sizeof(
DecodingTime));
724 decoding_time.resize(count);
725 for (uint32_t i = 0; i < count; ++i) {
726 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
727 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
732size_t DecodingTimeToSample::ComputeSizeInternal() {
734 sizeof(DecodingTime) * decoding_time.size();
737CompositionTimeToSample::CompositionTimeToSample() =
default;
738CompositionTimeToSample::~CompositionTimeToSample() =
default;
744bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
745 uint32_t count =
static_cast<uint32_t
>(composition_offset.size());
751 for (uint32_t i = 0; i < count; ++i) {
752 if (composition_offset[i].sample_offset < 0) {
761 composition_offset.resize(count);
762 for (uint32_t i = 0; i < count; ++i) {
763 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
766 uint32_t sample_offset = composition_offset[i].sample_offset;
767 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
768 composition_offset[i].sample_offset = sample_offset;
770 int32_t sample_offset = composition_offset[i].sample_offset;
771 RCHECK(buffer->ReadWriteInt32(&sample_offset));
772 composition_offset[i].sample_offset = sample_offset;
778size_t CompositionTimeToSample::ComputeSizeInternal() {
780 if (composition_offset.empty())
785 const size_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
787 kCompositionOffsetSize * composition_offset.size();
790SampleToChunk::SampleToChunk() =
default;
791SampleToChunk::~SampleToChunk() =
default;
797bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
798 uint32_t count =
static_cast<uint32_t
>(chunk_info.size());
801 chunk_info.resize(count);
802 for (uint32_t i = 0; i < count; ++i) {
803 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
804 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
805 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
807 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
808 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
813size_t SampleToChunk::ComputeSizeInternal() {
815 sizeof(ChunkInfo) * chunk_info.size();
818SampleSize::SampleSize() =
default;
819SampleSize::~SampleSize() =
default;
825bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
827 buffer->ReadWriteUInt32(&sample_size) &&
828 buffer->ReadWriteUInt32(&sample_count));
830 if (sample_size == 0) {
832 sizes.resize(sample_count);
834 DCHECK(sample_count == sizes.size());
835 for (uint32_t i = 0; i < sample_count; ++i)
836 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
841size_t SampleSize::ComputeSizeInternal() {
842 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
843 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
846CompactSampleSize::CompactSampleSize() =
default;
847CompactSampleSize::~CompactSampleSize() =
default;
853bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
854 uint32_t sample_count =
static_cast<uint32_t
>(sizes.size());
856 buffer->ReadWriteUInt8(&field_size) &&
857 buffer->ReadWriteUInt32(&sample_count));
860 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
861 switch (field_size) {
863 for (uint32_t i = 0; i < sample_count; i += 2) {
866 RCHECK(buffer->ReadWriteUInt8(&size));
867 sizes[i] = size >> 4;
868 sizes[i + 1] = size & 0x0F;
870 DCHECK_LT(sizes[i], 16u);
871 DCHECK_LT(sizes[i + 1], 16u);
872 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
873 RCHECK(buffer->ReadWriteUInt8(&size));
878 for (uint32_t i = 0; i < sample_count; ++i) {
879 uint8_t size = sizes[i];
880 RCHECK(buffer->ReadWriteUInt8(&size));
885 for (uint32_t i = 0; i < sample_count; ++i) {
886 uint16_t size = sizes[i];
887 RCHECK(buffer->ReadWriteUInt16(&size));
894 sizes.resize(sample_count);
898size_t CompactSampleSize::ComputeSizeInternal() {
899 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
900 (field_size * sizes.size() + 7) / 8;
903ChunkOffset::ChunkOffset() =
default;
904ChunkOffset::~ChunkOffset() =
default;
910bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
911 uint32_t count =
static_cast<uint32_t
>(offsets.size());
914 offsets.resize(count);
915 for (uint32_t i = 0; i < count; ++i)
920size_t ChunkOffset::ComputeSizeInternal() {
921 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
924ChunkLargeOffset::ChunkLargeOffset() =
default;
925ChunkLargeOffset::~ChunkLargeOffset() =
default;
931bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
932 uint32_t count =
static_cast<uint32_t
>(offsets.size());
936 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
938 stco.offsets.swap(offsets);
941 stco.offsets.swap(offsets);
948 offsets.resize(count);
949 for (uint32_t i = 0; i < count; ++i)
950 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
954size_t ChunkLargeOffset::ComputeSizeInternal() {
955 uint32_t count =
static_cast<uint32_t
>(offsets.size());
956 int use_large_offset =
957 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
959 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
962SyncSample::SyncSample() =
default;
963SyncSample::~SyncSample() =
default;
969bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
970 uint32_t count =
static_cast<uint32_t
>(sample_number.size());
973 sample_number.resize(count);
974 for (uint32_t i = 0; i < count; ++i)
975 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
979size_t SyncSample::ComputeSizeInternal() {
981 if (sample_number.empty())
984 sizeof(uint32_t) * sample_number.size();
987bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
988 if (!buffer->Reading()) {
989 if (key_id.size() != kCencKeyIdSize) {
990 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
991 <<
" bytes; got " << key_id.size()
992 <<
". Resized accordingly.";
993 key_id.resize(kCencKeyIdSize);
995 RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
998 RCHECK(buffer->IgnoreBytes(1));
1000 uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
1001 RCHECK(buffer->ReadWriteUInt8(&pattern));
1002 crypt_byte_block = pattern >> 4;
1003 skip_byte_block = pattern & 0x0F;
1005 RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
1006 buffer->ReadWriteUInt8(&per_sample_iv_size) &&
1007 buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
1009 if (is_protected == 1) {
1010 if (per_sample_iv_size == 0) {
1011 uint8_t constant_iv_size =
static_cast<uint8_t
>(constant_iv.size());
1012 RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
1013 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
1014 RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
1016 RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
1017 DCHECK(constant_iv.empty());
1022 RCHECK(is_protected == 0);
1023 RCHECK(per_sample_iv_size == 0);
1028uint32_t CencSampleEncryptionInfoEntry::ComputeSize()
const {
1029 return static_cast<uint32_t
>(
1030 sizeof(uint32_t) + kCencKeyIdSize +
1031 (constant_iv.empty() ? 0 : (
sizeof(uint8_t) + constant_iv.size())));
1034bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
1035 RCHECK(buffer->ReadWriteInt16(&roll_distance));
1039uint32_t AudioRollRecoveryEntry::ComputeSize()
const {
1040 return sizeof(roll_distance);
1043SampleGroupDescription::SampleGroupDescription() =
default;
1044SampleGroupDescription::~SampleGroupDescription() =
default;
1050bool SampleGroupDescription::ReadWriteInternal(
BoxBuffer* buffer) {
1052 buffer->ReadWriteUInt32(&grouping_type));
1054 switch (grouping_type) {
1056 return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
1058 return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
1061 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1062 << FourCCToString(
static_cast<FourCC
>(grouping_type));
1067template <
typename T>
1068bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
1069 std::vector<T>* entries) {
1070 uint32_t default_length = 0;
1071 if (!buffer->Reading()) {
1072 DCHECK(!entries->empty());
1073 default_length = (*entries)[0].ComputeSize();
1074 DCHECK_NE(default_length, 0u);
1077 RCHECK(buffer->ReadWriteUInt32(&default_length));
1079 NOTIMPLEMENTED() <<
"Unsupported SampleGroupDescriptionBox 'sgpd' version "
1080 <<
static_cast<int>(version);
1084 uint32_t count =
static_cast<uint32_t
>(entries->size());
1085 RCHECK(buffer->ReadWriteUInt32(&count));
1086 if (buffer->Reading()) {
1092 entries->resize(count);
1094 for (T& entry : *entries) {
1096 uint32_t description_length = default_length;
1097 if (buffer->Reading() && default_length == 0)
1098 RCHECK(buffer->ReadWriteUInt32(&description_length));
1099 RCHECK(entry.ReadWrite(buffer));
1100 RCHECK(entry.ComputeSize() == description_length);
1102 RCHECK(entry.ReadWrite(buffer));
1108size_t SampleGroupDescription::ComputeSizeInternal() {
1111 size_t entries_size = 0;
1112 switch (grouping_type) {
1114 for (
const auto& entry : cenc_sample_encryption_info_entries)
1118 for (
const auto& entry : audio_roll_recovery_entries)
1123 if (entries_size == 0)
1125 return HeaderSize() +
sizeof(grouping_type) +
1126 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1130SampleToGroup::SampleToGroup() =
default;
1131SampleToGroup::~SampleToGroup() =
default;
1137bool SampleToGroup::ReadWriteInternal(
BoxBuffer* buffer) {
1139 buffer->ReadWriteUInt32(&grouping_type));
1141 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1143 if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
1145 DLOG(WARNING) <<
"Ignore unsupported sample group: "
1146 << FourCCToString(
static_cast<FourCC
>(grouping_type));
1150 uint32_t count =
static_cast<uint32_t
>(entries.size());
1151 RCHECK(buffer->ReadWriteUInt32(&count));
1152 entries.resize(count);
1153 for (uint32_t i = 0; i < count; ++i) {
1154 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1155 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1160size_t SampleToGroup::ComputeSizeInternal() {
1162 if (entries.empty())
1164 return HeaderSize() +
sizeof(grouping_type) +
1165 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1166 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1169SampleTable::SampleTable() =
default;
1170SampleTable::~SampleTable() =
default;
1176bool SampleTable::ReadWriteInternal(
BoxBuffer* buffer) {
1189 RCHECK(reader->
ReadChild(&sample_size));
1191 CompactSampleSize compact_sample_size;
1192 RCHECK(reader->
ReadChild(&compact_sample_size));
1193 sample_size.sample_size = 0;
1194 sample_size.sample_count =
1195 static_cast<uint32_t
>(compact_sample_size.sizes.size());
1196 sample_size.sizes.swap(compact_sample_size.sizes);
1200 if (reader->
ChildExist(&chunk_large_offset)) {
1201 RCHECK(reader->
ReadChild(&chunk_large_offset));
1203 ChunkOffset chunk_offset;
1204 RCHECK(reader->
ReadChild(&chunk_offset));
1205 chunk_large_offset.offsets.swap(chunk_offset.offsets);
1216 for (
auto& sample_group_description : sample_group_descriptions)
1217 RCHECK(buffer->ReadWriteChild(&sample_group_description));
1218 for (
auto& sample_to_group : sample_to_groups)
1219 RCHECK(buffer->ReadWriteChild(&sample_to_group));
1224size_t SampleTable::ComputeSizeInternal() {
1231 for (
auto& sample_group_description : sample_group_descriptions)
1233 for (
auto& sample_to_group : sample_to_groups)
1238EditList::EditList() =
default;
1239EditList::~EditList() =
default;
1245bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
1246 uint32_t count =
static_cast<uint32_t
>(edits.size());
1248 edits.resize(count);
1250 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1251 for (uint32_t i = 0; i < count; ++i) {
1254 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1255 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1256 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1261size_t EditList::ComputeSizeInternal() {
1267 for (uint32_t i = 0; i < edits.size(); ++i) {
1268 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1274 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
1278Edit::Edit() =
default;
1279Edit::~Edit() =
default;
1285bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
1290size_t Edit::ComputeSizeInternal() {
1292 if (list.edits.empty())
1297HandlerReference::HandlerReference() =
default;
1298HandlerReference::~HandlerReference() =
default;
1304bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
1305 std::vector<uint8_t> handler_name;
1307 switch (handler_type) {
1309 handler_name.assign(kVideoHandlerName,
1310 kVideoHandlerName + std::size(kVideoHandlerName));
1313 handler_name.assign(kAudioHandlerName,
1314 kAudioHandlerName + std::size(kAudioHandlerName));
1317 handler_name.assign(kTextHandlerName,
1318 kTextHandlerName + std::size(kTextHandlerName));
1321 handler_name.assign(
1322 kSubtitleHandlerName,
1323 kSubtitleHandlerName + std::size(kSubtitleHandlerName));
1334 buffer->ReadWriteFourCC(&handler_type));
1337 buffer->ReadWriteVector(&handler_name, handler_name.size()));
1342size_t HandlerReference::ComputeSizeInternal() {
1344 switch (handler_type) {
1346 box_size +=
sizeof(kVideoHandlerName);
1349 box_size +=
sizeof(kAudioHandlerName);
1352 box_size +=
sizeof(kTextHandlerName);
1355 box_size +=
sizeof(kSubtitleHandlerName);
1365bool Language::ReadWrite(BoxBuffer* buffer) {
1366 if (buffer->Reading()) {
1369 std::vector<uint8_t> temp;
1370 RCHECK(buffer->ReadWriteVector(&temp, 2));
1372 BitReader bit_reader(&temp[0], 2);
1373 bit_reader.SkipBits(1);
1375 for (
int i = 0; i < 3; ++i) {
1376 CHECK(bit_reader.ReadBits(5, &language[i]));
1377 language[i] += 0x60;
1379 code.assign(language, 3);
1382 const char kUndefinedLanguage[] =
"und";
1384 code = kUndefinedLanguage;
1385 DCHECK_EQ(code.size(), 3u);
1389 for (
int i = 0; i < 3; ++i)
1390 lang |= (code[i] - 0x60) << ((2 - i) * 5);
1391 RCHECK(buffer->ReadWriteUInt16(&lang));
1396uint32_t Language::ComputeSize()
const {
1401ID3v2::ID3v2() =
default;
1402ID3v2::~ID3v2() =
default;
1408bool ID3v2::ReadWriteInternal(
BoxBuffer* buffer) {
1410 buffer->ReadWriteVector(&id3v2_data, buffer->
Reading()
1412 : id3v2_data.size()));
1416size_t ID3v2::ComputeSizeInternal() {
1418 return id3v2_data.size() == 0
1420 :
HeaderSize() + language.ComputeSize() + id3v2_data.size();
1423Metadata::Metadata() =
default;
1424Metadata::~Metadata() =
default;
1430bool Metadata::ReadWriteInternal(
BoxBuffer* buffer) {
1436size_t Metadata::ComputeSizeInternal() {
1439 return id3v2_size == 0 ? 0
1443CodecConfiguration::CodecConfiguration() =
default;
1444CodecConfiguration::~CodecConfiguration() =
default;
1452bool CodecConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1453 DCHECK_NE(box_type, FOURCC_NULL);
1458 if (box_type == FOURCC_vpcC) {
1460 uint8_t vpcc_version = 1;
1461 uint32_t version_flags = vpcc_version << 24;
1462 RCHECK(buffer->ReadWriteUInt32(&version_flags));
1463 vpcc_version = version_flags >> 24;
1464 RCHECK(vpcc_version == 1);
1468 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1470 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1475size_t CodecConfiguration::ComputeSizeInternal() {
1478 DCHECK_NE(box_type, FOURCC_NULL);
1479 return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1482ColorParameters::ColorParameters() =
default;
1483ColorParameters::~ColorParameters() =
default;
1489bool ColorParameters::ReadWriteInternal(
BoxBuffer* buffer) {
1495 raw_box.assign(reader->data(), reader->data() + reader->size());
1498 RCHECK(reader->ReadFourCC(&color_parameter_type) &&
1499 reader->Read2(&color_primaries) &&
1500 reader->Read2(&transfer_characteristics) &&
1501 reader->Read2(&matrix_coefficients));
1504 if (color_parameter_type == FOURCC_nclx) {
1505 RCHECK(reader->
Read1(&video_full_range_flag));
1509 DCHECK(!raw_box.empty());
1510 buffer->
writer()->AppendVector(raw_box);
1515size_t ColorParameters::ComputeSizeInternal() {
1516 return raw_box.size();
1519PixelAspectRatio::PixelAspectRatio() =
default;
1520PixelAspectRatio::~PixelAspectRatio() =
default;
1526bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
1528 buffer->ReadWriteUInt32(&h_spacing) &&
1529 buffer->ReadWriteUInt32(&v_spacing));
1533size_t PixelAspectRatio::ComputeSizeInternal() {
1535 if (h_spacing == 0 && v_spacing == 0)
1538 DCHECK(h_spacing != 0 && v_spacing != 0);
1539 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
1542VideoSampleEntry::VideoSampleEntry() =
default;
1543VideoSampleEntry::~VideoSampleEntry() =
default;
1546 if (format == FOURCC_NULL) {
1547 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
1548 <<
"handler type recovered in its Media ancestor.";
1553bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1554 std::vector<uint8_t> compressor_name;
1556 DCHECK(buffer->
reader());
1557 format = buffer->
reader()->type();
1561 const FourCC actual_format = GetActualFormat();
1562 switch (actual_format) {
1564 compressor_name.assign(std::begin(kAv1CompressorName),
1565 std::end(kAv1CompressorName));
1569 compressor_name.assign(std::begin(kAvcCompressorName),
1570 std::end(kAvcCompressorName));
1574 compressor_name.assign(std::begin(kDolbyVisionCompressorName),
1575 std::end(kDolbyVisionCompressorName));
1579 compressor_name.assign(std::begin(kHevcCompressorName),
1580 std::end(kHevcCompressorName));
1584 compressor_name.assign(std::begin(kVpcCompressorName),
1585 std::end(kVpcCompressorName));
1588 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
1591 compressor_name.resize(kCompressorNameSize);
1594 uint32_t video_resolution = kVideoResolution;
1595 uint16_t video_frame_count = kVideoFrameCount;
1596 uint16_t video_depth = kVideoDepth;
1597 int16_t predefined = -1;
1599 buffer->ReadWriteUInt16(&data_reference_index) &&
1601 buffer->ReadWriteUInt16(&width) && buffer->ReadWriteUInt16(&height) &&
1602 buffer->ReadWriteUInt32(&video_resolution) &&
1603 buffer->ReadWriteUInt32(&video_resolution) &&
1605 buffer->ReadWriteUInt16(&video_frame_count) &&
1606 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1607 buffer->ReadWriteUInt16(&video_depth) &&
1608 buffer->ReadWriteInt16(&predefined));
1615 if (format == FOURCC_encv && buffer->
Reading()) {
1618 while (!IsProtectionSchemeSupported(sinf.type.type))
1622 const FourCC actual_format = GetActualFormat();
1624 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1626 DCHECK_EQ(codec_configuration.box_type,
1627 GetCodecConfigurationBoxType(actual_format));
1629 if (codec_configuration.box_type == FOURCC_NULL)
1635 extra_codec_configs.clear();
1637 const bool is_hevc =
1638 actual_format == FOURCC_dvhe || actual_format == FOURCC_dvh1 ||
1639 actual_format == FOURCC_hev1 || actual_format == FOURCC_hvc1;
1641 for (FourCC fourcc : {FOURCC_dvcC, FOURCC_dvvC, FOURCC_hvcE}) {
1642 CodecConfiguration dv_box;
1643 dv_box.box_type = fourcc;
1645 if (!dv_box.data.empty())
1646 extra_codec_configs.push_back(std::move(dv_box));
1648 for (FourCC fourcc : {FOURCC_lhvC, FOURCC_vexu, FOURCC_hfov}) {
1649 CodecConfiguration stereo_box;
1650 stereo_box.box_type = fourcc;
1652 if (!stereo_box.data.empty())
1653 extra_codec_configs.push_back(std::move(stereo_box));
1656 const bool is_av1 = actual_format == FOURCC_av01;
1658 for (FourCC fourcc : {FOURCC_dvvC}) {
1659 CodecConfiguration dv_box;
1660 dv_box.box_type = fourcc;
1662 if (!dv_box.data.empty())
1663 extra_codec_configs.push_back(std::move(dv_box));
1667 for (CodecConfiguration& extra_codec_config : extra_codec_configs)
1668 RCHECK(buffer->ReadWriteChild(&extra_codec_config));
1677 if (format == FOURCC_encv && !buffer->
Reading()) {
1678 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1684size_t VideoSampleEntry::ComputeSizeInternal() {
1685 const FourCC actual_format = GetActualFormat();
1686 if (actual_format == FOURCC_NULL)
1688 codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1689 DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1690 size_t size =
HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
1691 sizeof(height) +
sizeof(kVideoResolution) * 2 +
1692 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
1695 kCompressorNameSize + 6 + 4 + 16 +
1697 for (CodecConfiguration& codec_config : extra_codec_configs)
1702FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC l_format)
const {
1718 LOG(ERROR) << FourCCToString(l_format) <<
" is not supported.";
1723std::vector<uint8_t> VideoSampleEntry::ExtraCodecConfigsAsVector()
const {
1724 BufferWriter buffer;
1725 for (CodecConfiguration codec_config : extra_codec_configs)
1726 codec_config.
Write(&buffer);
1727 return std::vector<uint8_t>(buffer.Buffer(), buffer.Buffer() + buffer.Size());
1730bool VideoSampleEntry::ParseExtraCodecConfigsVector(
1731 const std::vector<uint8_t>& data) {
1732 extra_codec_configs.clear();
1734 while (pos < data.size()) {
1736 std::unique_ptr<BoxReader> box_reader(
1738 RCHECK(!err && box_reader);
1740 CodecConfiguration codec_config;
1741 codec_config.box_type = box_reader->type();
1742 RCHECK(codec_config.Parse(box_reader.get()));
1743 extra_codec_configs.push_back(std::move(codec_config));
1745 pos += box_reader->pos();
1750bool VideoSampleEntry::HaveDolbyVisionConfig()
const {
1751 for (CodecConfiguration codec_config : extra_codec_configs) {
1752 if (codec_config.box_type == FOURCC_dvcC ||
1753 codec_config.box_type == FOURCC_dvvC ||
1754 codec_config.box_type == FOURCC_hvcE)
1760bool VideoSampleEntry::HaveLHEVCConfig()
const {
1761 for (CodecConfiguration codec_config : extra_codec_configs) {
1762 if (codec_config.box_type == FOURCC_lhvC)
1768ElementaryStreamDescriptor::ElementaryStreamDescriptor() =
default;
1769ElementaryStreamDescriptor::~ElementaryStreamDescriptor() =
default;
1775bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
1778 std::vector<uint8_t> data;
1779 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1780 RCHECK(es_descriptor.
Parse(data));
1781 if (es_descriptor.decoder_config_descriptor().
IsAAC()) {
1782 RCHECK(aac_audio_specific_config.
Parse(
1783 es_descriptor.decoder_config_descriptor()
1784 .decoder_specific_info_descriptor()
1788 DCHECK(buffer->
writer());
1794size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1796 if (es_descriptor.decoder_config_descriptor().object_type() ==
1797 ObjectType::kForbidden) {
1803MHAConfiguration::MHAConfiguration() =
default;
1804MHAConfiguration::~MHAConfiguration() =
default;
1810bool MHAConfiguration::ReadWriteInternal(
BoxBuffer* buffer) {
1812 buffer->ReadWriteVector(
1814 RCHECK(data.size() > 1);
1815 mpeg_h_3da_profile_level_indication = data[1];
1819size_t MHAConfiguration::ComputeSizeInternal() {
1826DTSSpecific::DTSSpecific() =
default;
1827DTSSpecific::~DTSSpecific() =
default;
1834bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1836 buffer->ReadWriteUInt32(&sampling_frequency) &&
1837 buffer->ReadWriteUInt32(&max_bitrate) &&
1838 buffer->ReadWriteUInt32(&avg_bitrate) &&
1839 buffer->ReadWriteUInt8(&pcm_sample_depth));
1842 RCHECK(buffer->ReadWriteVector(&extra_data, buffer->
BytesLeft()));
1844 if (extra_data.empty()) {
1845 extra_data.assign(kDdtsExtraData,
1846 kDdtsExtraData +
sizeof(kDdtsExtraData));
1848 RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1853size_t DTSSpecific::ComputeSizeInternal() {
1855 if (sampling_frequency == 0)
1857 return HeaderSize() +
sizeof(sampling_frequency) +
sizeof(max_bitrate) +
1858 sizeof(avg_bitrate) +
sizeof(pcm_sample_depth) +
1859 sizeof(kDdtsExtraData);
1862UDTSSpecific::UDTSSpecific() =
default;
1863UDTSSpecific::~UDTSSpecific() =
default;
1869bool UDTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1871 buffer->ReadWriteVector(
1876size_t UDTSSpecific::ComputeSizeInternal() {
1883AC3Specific::AC3Specific() =
default;
1884AC3Specific::~AC3Specific() =
default;
1890bool AC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1892 buffer->ReadWriteVector(
1897size_t AC3Specific::ComputeSizeInternal() {
1904EC3Specific::EC3Specific() =
default;
1905EC3Specific::~EC3Specific() =
default;
1911bool EC3Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1914 RCHECK(buffer->ReadWriteVector(&data, size));
1918size_t EC3Specific::ComputeSizeInternal() {
1925AC4Specific::AC4Specific() =
default;
1926AC4Specific::~AC4Specific() =
default;
1932bool AC4Specific::ReadWriteInternal(
BoxBuffer* buffer) {
1935 RCHECK(buffer->ReadWriteVector(&data, size));
1939size_t AC4Specific::ComputeSizeInternal() {
1946OpusSpecific::OpusSpecific() =
default;
1947OpusSpecific::~OpusSpecific() =
default;
1953bool OpusSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1956 std::vector<uint8_t> data;
1957 const int kMinOpusSpecificBoxDataSize = 11;
1958 RCHECK(buffer->
BytesLeft() >= kMinOpusSpecificBoxDataSize);
1959 RCHECK(buffer->ReadWriteVector(&data, buffer->
BytesLeft()));
1960 preskip = data[2] + (data[3] << 8);
1965 writer.AppendInt(FOURCC_Head);
1967 const uint8_t kOpusIdentificationHeaderVersion = 1;
1968 data[0] = kOpusIdentificationHeaderVersion;
1969 writer.AppendVector(data);
1970 writer.SwapBuffer(&opus_identification_header);
1974 const size_t kOpusMagicSignatureSize = 8u;
1975 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1978 const uint8_t kOpusSpecificBoxVersion = 0;
1980 buffer->
writer()->AppendArray(
1981 &opus_identification_header[kOpusMagicSignatureSize + 1],
1982 opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1987size_t OpusSpecific::ComputeSizeInternal() {
1989 if (opus_identification_header.empty())
1993 const size_t kOpusMagicSignatureSize = 8u;
1994 DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1995 return HeaderSize() + opus_identification_header.size() -
1996 kOpusMagicSignatureSize;
1999IAMFSpecific::IAMFSpecific() =
default;
2000IAMFSpecific::~IAMFSpecific() =
default;
2006bool IAMFSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
2009 RCHECK(buffer->ReadWriteVector(&data, size));
2013size_t IAMFSpecific::ComputeSizeInternal() {
2020FlacSpecific::FlacSpecific() =
default;
2021FlacSpecific::~FlacSpecific() =
default;
2027bool FlacSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
2030 RCHECK(buffer->ReadWriteVector(&data, size));
2034size_t FlacSpecific::ComputeSizeInternal() {
2041ALACSpecific::ALACSpecific() =
default;
2042ALACSpecific::~ALACSpecific() =
default;
2048bool ALACSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
2051 RCHECK(buffer->ReadWriteVector(&data, size));
2055size_t ALACSpecific::ComputeSizeInternal() {
2062AudioSampleEntry::AudioSampleEntry() =
default;
2063AudioSampleEntry::~AudioSampleEntry() =
default;
2066 if (format == FOURCC_NULL) {
2067 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
2068 <<
"handler type recovered in its Media ancestor.";
2073bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
2075 DCHECK(buffer->
reader());
2076 format = buffer->
reader()->type();
2084 buffer->ReadWriteUInt16(&data_reference_index) &&
2086 buffer->ReadWriteUInt16(&channelcount) &&
2087 buffer->ReadWriteUInt16(&samplesize) &&
2089 buffer->ReadWriteUInt32(&samplerate));
2110 if (format == FOURCC_enca) {
2114 while (!IsProtectionSchemeSupported(sinf.type.type))
2117 DCHECK(IsProtectionSchemeSupported(sinf.type.type));
2124size_t AudioSampleEntry::ComputeSizeInternal() {
2125 if (GetActualFormat() == FOURCC_NULL)
2127 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
2128 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
2138WebVTTConfigurationBox::WebVTTConfigurationBox() =
default;
2139WebVTTConfigurationBox::~WebVTTConfigurationBox() =
default;
2145bool WebVTTConfigurationBox::ReadWriteInternal(
BoxBuffer* buffer) {
2151size_t WebVTTConfigurationBox::ComputeSizeInternal() {
2155WebVTTSourceLabelBox::WebVTTSourceLabelBox() =
default;
2156WebVTTSourceLabelBox::~WebVTTSourceLabelBox() =
default;
2162bool WebVTTSourceLabelBox::ReadWriteInternal(
BoxBuffer* buffer) {
2166 : source_label.size());
2169size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
2170 if (source_label.empty())
2175TextSampleEntry::TextSampleEntry() =
default;
2176TextSampleEntry::~TextSampleEntry() =
default;
2179 if (format == FOURCC_NULL) {
2180 LOG(ERROR) <<
"TextSampleEntry should be parsed according to the "
2181 <<
"handler type recovered in its Media ancestor.";
2186bool TextSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
2188 DCHECK(buffer->
reader());
2189 format = buffer->
reader()->type();
2194 buffer->ReadWriteUInt16(&data_reference_index));
2196 if (format == FOURCC_wvtt) {
2200 }
else if (format == FOURCC_stpp) {
2203 RCHECK(buffer->ReadWriteCString(&namespace_) &&
2204 buffer->ReadWriteCString(&schema_location));
2209size_t TextSampleEntry::ComputeSizeInternal() {
2211 size_t ret =
HeaderSize() + 6 +
sizeof(data_reference_index);
2212 if (format == FOURCC_wvtt) {
2214 }
else if (format == FOURCC_stpp) {
2216 ret += namespace_.size() + schema_location.size() + 2;
2221MediaHeader::MediaHeader() =
default;
2222MediaHeader::~MediaHeader() =
default;
2228bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2231 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2234 buffer->ReadWriteUInt32(×cale) &&
2236 language.ReadWrite(buffer) &&
2242size_t MediaHeader::ComputeSizeInternal() {
2243 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
2245 sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
2249VideoMediaHeader::VideoMediaHeader() {
2250 const uint32_t kVideoMediaHeaderFlags = 1;
2251 flags = kVideoMediaHeaderFlags;
2254VideoMediaHeader::~VideoMediaHeader() =
default;
2259bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2261 buffer->ReadWriteUInt16(&graphicsmode) &&
2262 buffer->ReadWriteUInt16(&opcolor_red) &&
2263 buffer->ReadWriteUInt16(&opcolor_green) &&
2264 buffer->ReadWriteUInt16(&opcolor_blue));
2268size_t VideoMediaHeader::ComputeSizeInternal() {
2269 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
2270 sizeof(opcolor_green) +
sizeof(opcolor_blue);
2273SoundMediaHeader::SoundMediaHeader() =
default;
2274SoundMediaHeader::~SoundMediaHeader() =
default;
2280bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2286size_t SoundMediaHeader::ComputeSizeInternal() {
2287 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
2290NullMediaHeader::NullMediaHeader() =
default;
2291NullMediaHeader::~NullMediaHeader() =
default;
2297bool NullMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2301size_t NullMediaHeader::ComputeSizeInternal() {
2305SubtitleMediaHeader::SubtitleMediaHeader() =
default;
2306SubtitleMediaHeader::~SubtitleMediaHeader() =
default;
2312bool SubtitleMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2316size_t SubtitleMediaHeader::ComputeSizeInternal() {
2320DataEntryUrl::DataEntryUrl() {
2321 const uint32_t kDataEntryUrlFlags = 1;
2322 flags = kDataEntryUrlFlags;
2325DataEntryUrl::~DataEntryUrl() =
default;
2330bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
2333 RCHECK(buffer->ReadWriteVector(&location, buffer->
BytesLeft()));
2335 RCHECK(buffer->ReadWriteVector(&location, location.size()));
2340size_t DataEntryUrl::ComputeSizeInternal() {
2344DataReference::DataReference() =
default;
2345DataReference::~DataReference() =
default;
2350bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
2351 uint32_t entry_count =
static_cast<uint32_t
>(data_entry.size());
2353 buffer->ReadWriteUInt32(&entry_count));
2354 data_entry.resize(entry_count);
2356 for (uint32_t i = 0; i < entry_count; ++i)
2361size_t DataReference::ComputeSizeInternal() {
2362 uint32_t count =
static_cast<uint32_t
>(data_entry.size());
2364 for (uint32_t i = 0; i < count; ++i)
2369DataInformation::DataInformation() =
default;
2370DataInformation::~DataInformation() =
default;
2376bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2381size_t DataInformation::ComputeSizeInternal() {
2385MediaInformation::MediaInformation() =
default;
2386MediaInformation::~MediaInformation() =
default;
2392bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
2396 switch (sample_table.description.type) {
2416size_t MediaInformation::ComputeSizeInternal() {
2419 switch (sample_table.description.type) {
2438Media::Media() =
default;
2439Media::~Media() =
default;
2445bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
2456 information.sample_table.description.type =
2457 FourCCToTrackType(handler.handler_type);
2459 handler.handler_type =
2460 TrackTypeToFourCC(information.sample_table.description.type);
2461 RCHECK(handler.handler_type != FOURCC_NULL);
2468size_t Media::ComputeSizeInternal() {
2469 handler.handler_type =
2470 TrackTypeToFourCC(information.sample_table.description.type);
2475Track::Track() =
default;
2476Track::~Track() =
default;
2482bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
2490size_t Track::ComputeSizeInternal() {
2495MovieExtendsHeader::MovieExtendsHeader() =
default;
2496MovieExtendsHeader::~MovieExtendsHeader() =
default;
2502bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2504 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2509size_t MovieExtendsHeader::ComputeSizeInternal() {
2511 if (fragment_duration == 0)
2513 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2514 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2517TrackExtends::TrackExtends() =
default;
2518TrackExtends::~TrackExtends() =
default;
2524bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2526 buffer->ReadWriteUInt32(&track_id) &&
2527 buffer->ReadWriteUInt32(&default_sample_description_index) &&
2528 buffer->ReadWriteUInt32(&default_sample_duration) &&
2529 buffer->ReadWriteUInt32(&default_sample_size) &&
2530 buffer->ReadWriteUInt32(&default_sample_flags));
2534size_t TrackExtends::ComputeSizeInternal() {
2536 sizeof(default_sample_description_index) +
2537 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
2538 sizeof(default_sample_flags);
2541MovieExtends::MovieExtends() =
default;
2542MovieExtends::~MovieExtends() =
default;
2548bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
2552 DCHECK(buffer->
reader());
2555 for (uint32_t i = 0; i < tracks.size(); ++i)
2561size_t MovieExtends::ComputeSizeInternal() {
2563 if (tracks.size() == 0)
2566 for (uint32_t i = 0; i < tracks.size(); ++i)
2571Movie::Movie() =
default;
2572Movie::~Movie() =
default;
2578bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
2594 if (absl::GetFlag(FLAGS_mvex_before_trak)) {
2601 for (uint32_t i = 0; i < tracks.size(); ++i)
2603 if (!absl::GetFlag(FLAGS_mvex_before_trak)) {
2606 for (uint32_t i = 0; i < pssh.size(); ++i)
2612size_t Movie::ComputeSizeInternal() {
2615 for (uint32_t i = 0; i < tracks.size(); ++i)
2617 for (uint32_t i = 0; i < pssh.size(); ++i)
2622TrackFragmentDecodeTime::TrackFragmentDecodeTime() =
default;
2623TrackFragmentDecodeTime::~TrackFragmentDecodeTime() =
default;
2629bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
2631 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2636size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2637 version = IsFitIn32Bits(decode_time) ? 0 : 1;
2638 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
2641MovieFragmentHeader::MovieFragmentHeader() =
default;
2642MovieFragmentHeader::~MovieFragmentHeader() =
default;
2648bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2650 buffer->ReadWriteUInt32(&sequence_number);
2653size_t MovieFragmentHeader::ComputeSizeInternal() {
2654 return HeaderSize() +
sizeof(sequence_number);
2657TrackFragmentHeader::TrackFragmentHeader() =
default;
2658TrackFragmentHeader::~TrackFragmentHeader() =
default;
2664bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
2667 if (flags & kBaseDataOffsetPresentMask) {
2672 uint64_t base_data_offset;
2673 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2674 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
2675 "default-base-is-moof.";
2678 if (flags & kSampleDescriptionIndexPresentMask) {
2679 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2680 }
else if (buffer->
Reading()) {
2681 sample_description_index = 0;
2684 if (flags & kDefaultSampleDurationPresentMask) {
2685 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2686 }
else if (buffer->
Reading()) {
2687 default_sample_duration = 0;
2690 if (flags & kDefaultSampleSizePresentMask) {
2691 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2692 }
else if (buffer->
Reading()) {
2693 default_sample_size = 0;
2696 if (flags & kDefaultSampleFlagsPresentMask)
2697 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2701size_t TrackFragmentHeader::ComputeSizeInternal() {
2703 if (flags & kSampleDescriptionIndexPresentMask)
2704 box_size +=
sizeof(sample_description_index);
2705 if (flags & kDefaultSampleDurationPresentMask)
2706 box_size +=
sizeof(default_sample_duration);
2707 if (flags & kDefaultSampleSizePresentMask)
2708 box_size +=
sizeof(default_sample_size);
2709 if (flags & kDefaultSampleFlagsPresentMask)
2710 box_size +=
sizeof(default_sample_flags);
2714TrackFragmentRun::TrackFragmentRun() =
default;
2715TrackFragmentRun::~TrackFragmentRun() =
default;
2721bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
2727 if (flags & kSampleCompTimeOffsetsPresentMask) {
2728 for (uint32_t i = 0; i < sample_count; ++i) {
2729 if (sample_composition_time_offsets[i] < 0) {
2738 buffer->ReadWriteUInt32(&sample_count));
2740 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2741 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2742 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2743 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2744 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2745 bool sample_composition_time_offsets_present =
2746 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2748 if (data_offset_present) {
2749 RCHECK(buffer->ReadWriteUInt32(&data_offset));
2760 uint32_t first_sample_flags(0);
2763 if (first_sample_flags_present)
2764 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2766 if (sample_duration_present)
2767 sample_durations.resize(sample_count);
2768 if (sample_size_present)
2769 sample_sizes.resize(sample_count);
2770 if (sample_flags_present)
2771 sample_flags.resize(sample_count);
2772 if (sample_composition_time_offsets_present)
2773 sample_composition_time_offsets.resize(sample_count);
2775 if (first_sample_flags_present) {
2776 first_sample_flags = sample_flags[0];
2777 DCHECK(sample_flags.size() == 1);
2778 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2781 if (sample_duration_present)
2782 DCHECK(sample_durations.size() == sample_count);
2783 if (sample_size_present)
2784 DCHECK(sample_sizes.size() == sample_count);
2785 if (sample_flags_present)
2786 DCHECK(sample_flags.size() == sample_count);
2787 if (sample_composition_time_offsets_present)
2788 DCHECK(sample_composition_time_offsets.size() == sample_count);
2791 for (uint32_t i = 0; i < sample_count; ++i) {
2792 if (sample_duration_present)
2793 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2794 if (sample_size_present)
2795 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2796 if (sample_flags_present)
2797 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2799 if (sample_composition_time_offsets_present) {
2801 uint32_t sample_offset = sample_composition_time_offsets[i];
2802 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2803 sample_composition_time_offsets[i] = sample_offset;
2805 int32_t sample_offset = sample_composition_time_offsets[i];
2806 RCHECK(buffer->ReadWriteInt32(&sample_offset));
2807 sample_composition_time_offsets[i] = sample_offset;
2813 if (first_sample_flags_present) {
2814 if (sample_flags.size() == 0) {
2815 sample_flags.push_back(first_sample_flags);
2817 sample_flags[0] = first_sample_flags;
2824size_t TrackFragmentRun::ComputeSizeInternal() {
2826 if (flags & kDataOffsetPresentMask)
2828 if (flags & kFirstSampleFlagsPresentMask)
2830 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2831 (flags & kSampleSizePresentMask ? 1 : 0) +
2832 (flags & kSampleFlagsPresentMask ? 1 : 0) +
2833 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2834 box_size += fields *
sizeof(uint32_t) * sample_count;
2838TrackFragment::TrackFragment() =
default;
2839TrackFragment::~TrackFragment() =
default;
2845bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2849 DCHECK(buffer->
reader());
2851 if (!decode_time_absent)
2857 if (!decode_time_absent)
2859 for (uint32_t i = 0; i < runs.size(); ++i)
2861 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2863 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2871size_t TrackFragment::ComputeSizeInternal() {
2876 for (uint32_t i = 0; i < runs.size(); ++i)
2878 for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2880 for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2885MovieFragment::MovieFragment() =
default;
2886MovieFragment::~MovieFragment() =
default;
2892bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
2900 for (uint32_t i = 0; i < tracks.size(); ++i)
2902 for (uint32_t i = 0; i < pssh.size(); ++i)
2908size_t MovieFragment::ComputeSizeInternal() {
2910 for (uint32_t i = 0; i < tracks.size(); ++i)
2912 for (uint32_t i = 0; i < pssh.size(); ++i)
2917SegmentIndex::SegmentIndex() =
default;
2918SegmentIndex::~SegmentIndex() =
default;
2924bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
2926 buffer->ReadWriteUInt32(&reference_id) &&
2927 buffer->ReadWriteUInt32(×cale));
2929 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
2934 uint16_t reference_count;
2935 if (references.size() <= std::numeric_limits<uint16_t>::max()) {
2936 reference_count =
static_cast<uint16_t
>(references.size());
2938 reference_count = std::numeric_limits<uint16_t>::max();
2939 LOG(WARNING) <<
"Seeing " << references.size()
2940 <<
" subsegment references, but at most " << reference_count
2941 <<
" references can be stored in 'sidx' box."
2942 <<
" The extra references are truncated.";
2943 LOG(WARNING) <<
"The stream will not play to the end in DASH.";
2944 LOG(WARNING) <<
"A possible workaround is to increase segment duration.";
2947 buffer->ReadWriteUInt16(&reference_count));
2949 references.resize(reference_count);
2951 uint32_t reference_type_size;
2953 for (uint32_t i = 0; i < reference_count; ++i) {
2955 reference_type_size = references[i].referenced_size;
2956 if (references[i].reference_type)
2957 reference_type_size |= (1 << 31);
2958 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2959 if (references[i].starts_with_sap)
2962 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2963 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2964 buffer->ReadWriteUInt32(&sap));
2966 references[i].reference_type = (reference_type_size >> 31) ?
true : false;
2967 references[i].referenced_size = reference_type_size & ~(1 << 31);
2968 references[i].starts_with_sap = (sap >> 31) ?
true : false;
2969 references[i].sap_type =
2970 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
2971 references[i].sap_delta_time = sap & ~(0xF << 28);
2977size_t SegmentIndex::ComputeSizeInternal() {
2978 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2979 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
2980 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
2981 3 *
sizeof(uint32_t) *
2984 static_cast<size_t>(std::numeric_limits<uint16_t>::max()));
2987MediaData::MediaData() =
default;
2988MediaData::~MediaData() =
default;
2994bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
2995 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
2999size_t MediaData::ComputeSizeInternal() {
3003CueSourceIDBox::CueSourceIDBox() =
default;
3004CueSourceIDBox::~CueSourceIDBox() =
default;
3010bool CueSourceIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
3015size_t CueSourceIDBox::ComputeSizeInternal() {
3016 if (source_id == kCueSourceIdNotSet)
3021CueTimeBox::CueTimeBox() =
default;
3022CueTimeBox::~CueTimeBox() =
default;
3028bool CueTimeBox::ReadWriteInternal(
BoxBuffer* buffer) {
3035size_t CueTimeBox::ComputeSizeInternal() {
3036 if (cue_current_time.empty())
3038 return HeaderSize() + cue_current_time.size();
3041CueIDBox::CueIDBox() =
default;
3042CueIDBox::~CueIDBox() =
default;
3048bool CueIDBox::ReadWriteInternal(
BoxBuffer* buffer) {
3054size_t CueIDBox::ComputeSizeInternal() {
3060CueSettingsBox::CueSettingsBox() =
default;
3061CueSettingsBox::~CueSettingsBox() =
default;
3067bool CueSettingsBox::ReadWriteInternal(
BoxBuffer* buffer) {
3073size_t CueSettingsBox::ComputeSizeInternal() {
3074 if (settings.empty())
3079CuePayloadBox::CuePayloadBox() =
default;
3080CuePayloadBox::~CuePayloadBox() =
default;
3086bool CuePayloadBox::ReadWriteInternal(
BoxBuffer* buffer) {
3092size_t CuePayloadBox::ComputeSizeInternal() {
3096VTTEmptyCueBox::VTTEmptyCueBox() =
default;
3097VTTEmptyCueBox::~VTTEmptyCueBox() =
default;
3103bool VTTEmptyCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
3107size_t VTTEmptyCueBox::ComputeSizeInternal() {
3111VTTAdditionalTextBox::VTTAdditionalTextBox() =
default;
3112VTTAdditionalTextBox::~VTTAdditionalTextBox() =
default;
3118bool VTTAdditionalTextBox::ReadWriteInternal(
BoxBuffer* buffer) {
3121 &cue_additional_text,
3125size_t VTTAdditionalTextBox::ComputeSizeInternal() {
3126 return HeaderSize() + cue_additional_text.size();
3129VTTCueBox::VTTCueBox() =
default;
3130VTTCueBox::~VTTCueBox() =
default;
3136bool VTTCueBox::ReadWriteInternal(
BoxBuffer* buffer) {
3146size_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