5 #include "packager/media/formats/mp4/box_definitions.h"
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/formats/mp4/box_buffer.h"
12 #include "packager/media/formats/mp4/rcheck.h"
15 const uint32_t kFourCCSize = 4;
18 const uint32_t kCencKeyIdSize = 16;
21 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
26 const char kVideoHandlerName[] =
"VideoHandler";
27 const char kAudioHandlerName[] =
"SoundHandler";
30 const uint32_t kVideoResolution = 0x00480000;
31 const uint16_t kVideoFrameCount = 1;
32 const uint16_t kVideoDepth = 0x0018;
34 const uint32_t kCompressorNameSize = 32u;
35 const char kAvcCompressorName[] =
"\012AVC Coding";
36 const char kHevcCompressorName[] =
"\013HEVC Coding";
37 const char kVpcCompressorName[] =
"\012VPC Coding";
40 bool IsFitIn32Bits(uint64_t a) {
41 return a <= std::numeric_limits<uint32_t>::max();
44 bool IsFitIn32Bits(int64_t a) {
45 return a <= std::numeric_limits<int32_t>::max() &&
46 a >= std::numeric_limits<int32_t>::min();
49 template <
typename T1,
typename T2>
50 bool IsFitIn32Bits(T1 a1, T2 a2) {
51 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
54 template <
typename T1,
typename T2,
typename T3>
55 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
56 return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
61 namespace edash_packager {
65 FileType::FileType() : major_brand(FOURCC_NULL), minor_version(0) {}
66 FileType::~FileType() {}
69 bool FileType::ReadWriteInternal(
BoxBuffer* buffer) {
71 buffer->ReadWriteFourCC(&major_brand) &&
72 buffer->ReadWriteUInt32(&minor_version));
75 num_brands = (buffer->
Size() - buffer->
Pos()) /
sizeof(FourCC);
76 compatible_brands.resize(num_brands);
78 num_brands = compatible_brands.size();
80 for (
size_t i = 0; i < num_brands; ++i)
81 RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
85 uint32_t FileType::ComputeSizeInternal() {
86 return HeaderSize() + kFourCCSize +
sizeof(minor_version) +
87 kFourCCSize * compatible_brands.size();
92 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {}
93 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {}
96 bool ProtectionSystemSpecificHeader::ReadWriteInternal(
BoxBuffer* buffer) {
97 if (!buffer->
Reading() && !raw_box.empty()) {
99 buffer->
writer()->AppendVector(raw_box);
103 uint32_t size = data.size();
105 buffer->ReadWriteVector(&system_id, 16) &&
106 buffer->ReadWriteUInt32(&size) &&
107 buffer->ReadWriteVector(&data, size));
112 DCHECK(raw_box.empty());
113 BoxReader* reader = buffer->
reader();
115 raw_box.assign(reader->data(), reader->data() + reader->size());
120 uint32_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
121 if (!raw_box.empty()) {
122 return raw_box.size();
124 return HeaderSize() + system_id.size() +
sizeof(uint32_t) + data.size();
128 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {}
129 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
132 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(
BoxBuffer* buffer) {
137 uint32_t count = offsets.size();
138 RCHECK(buffer->ReadWriteUInt32(&count));
139 offsets.resize(count);
141 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
142 for (uint32_t i = 0; i < count; ++i)
147 uint32_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
149 if (offsets.size() == 0)
151 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
152 return HeaderSize() +
sizeof(uint32_t) + num_bytes * offsets.size();
155 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
156 : default_sample_info_size(0), sample_count(0) {}
157 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {}
160 bool SampleAuxiliaryInformationSize::ReadWriteInternal(
BoxBuffer* buffer) {
165 RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
166 buffer->ReadWriteUInt32(&sample_count));
167 if (default_sample_info_size == 0)
168 RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
172 uint32_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
174 if (sample_count == 0)
176 return HeaderSize() +
sizeof(default_sample_info_size) +
177 sizeof(sample_count) +
178 (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
181 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
182 OriginalFormat::~OriginalFormat() {}
185 bool OriginalFormat::ReadWriteInternal(
BoxBuffer* buffer) {
189 uint32_t OriginalFormat::ComputeSizeInternal() {
193 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
194 SchemeType::~SchemeType() {}
197 bool SchemeType::ReadWriteInternal(
BoxBuffer* buffer) {
199 buffer->ReadWriteFourCC(&type) &&
200 buffer->ReadWriteUInt32(&version));
204 uint32_t SchemeType::ComputeSizeInternal() {
205 return HeaderSize() + kFourCCSize +
sizeof(version);
208 TrackEncryption::TrackEncryption()
209 : is_encrypted(false), default_iv_size(0), default_kid(16, 0) {}
210 TrackEncryption::~TrackEncryption() {}
213 bool TrackEncryption::ReadWriteInternal(
BoxBuffer* buffer) {
215 if (default_kid.size() != kCencKeyIdSize) {
216 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
217 <<
" bytes; got " << default_kid.size()
218 <<
". Resized accordingly.";
219 default_kid.resize(kCencKeyIdSize);
223 uint8_t flag = is_encrypted ? 1 : 0;
226 buffer->ReadWriteUInt8(&flag) &&
227 buffer->ReadWriteUInt8(&default_iv_size) &&
228 buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
230 is_encrypted = (flag != 0);
232 RCHECK(default_iv_size == 8 || default_iv_size == 16);
234 RCHECK(default_iv_size == 0);
240 uint32_t TrackEncryption::ComputeSizeInternal() {
241 return HeaderSize() +
sizeof(uint32_t) + kCencKeyIdSize;
244 SchemeInfo::SchemeInfo() {}
245 SchemeInfo::~SchemeInfo() {}
248 bool SchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
254 uint32_t SchemeInfo::ComputeSizeInternal() {
258 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
259 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
262 bool ProtectionSchemeInfo::ReadWriteInternal(
BoxBuffer* buffer) {
267 if (type.type == FOURCC_CENC)
276 uint32_t ProtectionSchemeInfo::ComputeSizeInternal() {
278 if (format.format == FOURCC_NULL)
284 MovieHeader::MovieHeader()
286 modification_time(0),
292 MovieHeader::~MovieHeader() {}
295 bool MovieHeader::ReadWriteInternal(
BoxBuffer* buffer) {
298 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
301 buffer->ReadWriteUInt32(×cale) &&
304 std::vector<uint8_t> matrix(kUnityMatrix,
305 kUnityMatrix + arraysize(kUnityMatrix));
306 RCHECK(buffer->ReadWriteInt32(&rate) &&
307 buffer->ReadWriteInt16(&volume) &&
309 buffer->ReadWriteVector(&matrix, matrix.size()) &&
311 buffer->ReadWriteUInt32(&next_track_id));
315 uint32_t MovieHeader::ComputeSizeInternal() {
316 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
317 return HeaderSize() +
sizeof(uint32_t) * (1 + version) * 3 +
318 sizeof(timescale) +
sizeof(rate) +
sizeof(volume) +
319 sizeof(next_track_id) +
sizeof(kUnityMatrix) + 10 +
323 TrackHeader::TrackHeader()
325 modification_time(0),
333 flags = kTrackEnabled | kTrackInMovie;
335 TrackHeader::~TrackHeader() {}
338 bool TrackHeader::ReadWriteInternal(
BoxBuffer* buffer) {
341 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
344 buffer->ReadWriteUInt32(&track_id) &&
351 volume = (width != 0 && height != 0) ? 0 : 0x100;
353 std::vector<uint8_t> matrix(kUnityMatrix,
354 kUnityMatrix + arraysize(kUnityMatrix));
356 buffer->ReadWriteInt16(&layer) &&
357 buffer->ReadWriteInt16(&alternate_group) &&
358 buffer->ReadWriteInt16(&volume) &&
360 buffer->ReadWriteVector(&matrix, matrix.size()) &&
361 buffer->ReadWriteUInt32(&width) &&
362 buffer->ReadWriteUInt32(&height));
366 uint32_t TrackHeader::ComputeSizeInternal() {
367 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
369 sizeof(uint32_t) * (1 + version) * 3 +
sizeof(layer) +
370 sizeof(alternate_group) +
sizeof(volume) +
sizeof(width) +
371 sizeof(height) +
sizeof(kUnityMatrix) + 14;
374 SampleDescription::SampleDescription() : type(kInvalid) {}
375 SampleDescription::~SampleDescription() {}
378 bool SampleDescription::ReadWriteInternal(
BoxBuffer* buffer) {
381 count = video_entries.size();
383 count = audio_entries.size();
385 buffer->ReadWriteUInt32(&count));
390 video_entries.clear();
391 audio_entries.clear();
394 if (type == kVideo) {
396 RCHECK(video_entries.size() == count);
397 }
else if (type == kAudio) {
399 RCHECK(audio_entries.size() == count);
402 DCHECK_LT(0u, count);
403 if (type == kVideo) {
404 for (uint32_t i = 0; i < count; ++i)
406 }
else if (type == kAudio) {
407 for (uint32_t i = 0; i < count; ++i)
416 uint32_t SampleDescription::ComputeSizeInternal() {
417 uint32_t box_size =
HeaderSize() +
sizeof(uint32_t);
418 if (type == kVideo) {
419 for (uint32_t i = 0; i < video_entries.size(); ++i)
421 }
else if (type == kAudio) {
422 for (uint32_t i = 0; i < audio_entries.size(); ++i)
428 DecodingTimeToSample::DecodingTimeToSample() {}
429 DecodingTimeToSample::~DecodingTimeToSample() {}
432 bool DecodingTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
433 uint32_t count = decoding_time.size();
435 buffer->ReadWriteUInt32(&count));
437 decoding_time.resize(count);
438 for (uint32_t i = 0; i < count; ++i) {
439 RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
440 buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
445 uint32_t DecodingTimeToSample::ComputeSizeInternal() {
447 sizeof(DecodingTime) * decoding_time.size();
450 CompositionTimeToSample::CompositionTimeToSample() {}
451 CompositionTimeToSample::~CompositionTimeToSample() {}
454 bool CompositionTimeToSample::ReadWriteInternal(
BoxBuffer* buffer) {
455 uint32_t count = composition_offset.size();
461 for (uint32_t i = 0; i < count; ++i) {
462 if (composition_offset[i].sample_offset < 0) {
470 buffer->ReadWriteUInt32(&count));
472 composition_offset.resize(count);
473 for (uint32_t i = 0; i < count; ++i) {
474 RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
477 uint32_t sample_offset = composition_offset[i].sample_offset;
478 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
479 composition_offset[i].sample_offset = sample_offset;
481 int32_t sample_offset = composition_offset[i].sample_offset;
482 RCHECK(buffer->ReadWriteInt32(&sample_offset));
483 composition_offset[i].sample_offset = sample_offset;
489 uint32_t CompositionTimeToSample::ComputeSizeInternal() {
491 if (composition_offset.empty())
496 const uint32_t kCompositionOffsetSize =
sizeof(uint32_t) * 2;
498 kCompositionOffsetSize * composition_offset.size();
501 SampleToChunk::SampleToChunk() {}
502 SampleToChunk::~SampleToChunk() {}
505 bool SampleToChunk::ReadWriteInternal(
BoxBuffer* buffer) {
506 uint32_t count = chunk_info.size();
508 buffer->ReadWriteUInt32(&count));
510 chunk_info.resize(count);
511 for (uint32_t i = 0; i < count; ++i) {
512 RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
513 buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
514 buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
516 RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
517 : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
522 uint32_t SampleToChunk::ComputeSizeInternal() {
524 sizeof(ChunkInfo) * chunk_info.size();
527 SampleSize::SampleSize() : sample_size(0), sample_count(0) {}
528 SampleSize::~SampleSize() {}
531 bool SampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
533 buffer->ReadWriteUInt32(&sample_size) &&
534 buffer->ReadWriteUInt32(&sample_count));
536 if (sample_size == 0) {
538 sizes.resize(sample_count);
540 DCHECK(sample_count == sizes.size());
541 for (uint32_t i = 0; i < sample_count; ++i)
542 RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
547 uint32_t SampleSize::ComputeSizeInternal() {
548 return HeaderSize() +
sizeof(sample_size) +
sizeof(sample_count) +
549 (sample_size == 0 ?
sizeof(uint32_t) * sizes.size() : 0);
552 CompactSampleSize::CompactSampleSize() : field_size(0) {}
553 CompactSampleSize::~CompactSampleSize() {}
556 bool CompactSampleSize::ReadWriteInternal(
BoxBuffer* buffer) {
557 uint32_t sample_count = sizes.size();
560 buffer->ReadWriteUInt8(&field_size) &&
561 buffer->ReadWriteUInt32(&sample_count));
564 sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
565 switch (field_size) {
567 for (uint32_t i = 0; i < sample_count; i += 2) {
570 RCHECK(buffer->ReadWriteUInt8(&size));
571 sizes[i] = size >> 4;
572 sizes[i + 1] = size & 0x0F;
574 DCHECK_LT(sizes[i], 16u);
575 DCHECK_LT(sizes[i + 1], 16u);
576 uint8_t size = (sizes[i] << 4) | sizes[i + 1];
577 RCHECK(buffer->ReadWriteUInt8(&size));
582 for (uint32_t i = 0; i < sample_count; ++i) {
583 uint8_t size = sizes[i];
584 RCHECK(buffer->ReadWriteUInt8(&size));
589 for (uint32_t i = 0; i < sample_count; ++i) {
590 uint16_t size = sizes[i];
591 RCHECK(buffer->ReadWriteUInt16(&size));
598 sizes.resize(sample_count);
602 uint32_t CompactSampleSize::ComputeSizeInternal() {
603 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) +
604 (field_size * sizes.size() + 7) / 8;
607 ChunkOffset::ChunkOffset() {}
608 ChunkOffset::~ChunkOffset() {}
611 bool ChunkOffset::ReadWriteInternal(
BoxBuffer* buffer) {
612 uint32_t count = offsets.size();
614 buffer->ReadWriteUInt32(&count));
616 offsets.resize(count);
617 for (uint32_t i = 0; i < count; ++i)
622 uint32_t ChunkOffset::ComputeSizeInternal() {
623 return HeaderSize() +
sizeof(uint32_t) +
sizeof(uint32_t) * offsets.size();
626 ChunkLargeOffset::ChunkLargeOffset() {}
627 ChunkLargeOffset::~ChunkLargeOffset() {}
630 bool ChunkLargeOffset::ReadWriteInternal(
BoxBuffer* buffer) {
631 uint32_t count = offsets.size();
635 if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
637 stco.offsets.swap(offsets);
640 stco.offsets.swap(offsets);
646 buffer->ReadWriteUInt32(&count));
648 offsets.resize(count);
649 for (uint32_t i = 0; i < count; ++i)
650 RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
654 uint32_t ChunkLargeOffset::ComputeSizeInternal() {
655 uint32_t count = offsets.size();
656 int use_large_offset =
657 (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
659 sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
662 SyncSample::SyncSample() {}
663 SyncSample::~SyncSample() {}
666 bool SyncSample::ReadWriteInternal(
BoxBuffer* buffer) {
667 uint32_t count = sample_number.size();
669 buffer->ReadWriteUInt32(&count));
671 sample_number.resize(count);
672 for (uint32_t i = 0; i < count; ++i)
673 RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
677 uint32_t SyncSample::ComputeSizeInternal() {
679 if (sample_number.empty())
682 sizeof(uint32_t) * sample_number.size();
685 SampleTable::SampleTable() {}
686 SampleTable::~SampleTable() {}
689 bool SampleTable::ReadWriteInternal(
BoxBuffer* buffer) {
705 CompactSampleSize compact_sample_size;
706 RCHECK(reader->
ReadChild(&compact_sample_size));
707 sample_size.sample_size = 0;
708 sample_size.sample_count = compact_sample_size.sizes.size();
709 sample_size.sizes.swap(compact_sample_size.sizes);
713 if (reader->
ChildExist(&chunk_large_offset)) {
714 RCHECK(reader->
ReadChild(&chunk_large_offset));
716 ChunkOffset chunk_offset;
717 RCHECK(reader->
ReadChild(&chunk_offset));
718 chunk_large_offset.offsets.swap(chunk_offset.offsets);
728 uint32_t SampleTable::ComputeSizeInternal() {
736 EditList::EditList() {}
737 EditList::~EditList() {}
740 bool EditList::ReadWriteInternal(
BoxBuffer* buffer) {
741 uint32_t count = edits.size();
745 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
746 for (uint32_t i = 0; i < count; ++i) {
749 buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
750 buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
751 buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
756 uint32_t EditList::ComputeSizeInternal() {
762 for (uint32_t i = 0; i < edits.size(); ++i) {
763 if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
769 (
sizeof(uint32_t) * (1 + version) * 2 +
sizeof(int16_t) * 2) *
777 bool Edit::ReadWriteInternal(
BoxBuffer* buffer) {
783 uint32_t Edit::ComputeSizeInternal() {
785 if (list.edits.empty())
790 HandlerReference::HandlerReference() : type(kInvalid) {}
791 HandlerReference::~HandlerReference() {}
794 bool HandlerReference::ReadWriteInternal(
BoxBuffer* buffer) {
795 FourCC hdlr_type = FOURCC_NULL;
796 std::vector<uint8_t> handler_name;
798 if (type == kVideo) {
799 hdlr_type = FOURCC_VIDE;
800 handler_name.assign(kVideoHandlerName,
801 kVideoHandlerName + arraysize(kVideoHandlerName));
802 }
else if (type == kAudio) {
803 hdlr_type = FOURCC_SOUN;
804 handler_name.assign(kAudioHandlerName,
805 kAudioHandlerName + arraysize(kAudioHandlerName));
813 buffer->ReadWriteFourCC(&hdlr_type));
816 if (hdlr_type == FOURCC_VIDE) {
818 }
else if (hdlr_type == FOURCC_SOUN) {
825 buffer->ReadWriteVector(&handler_name, handler_name.size()));
830 uint32_t HandlerReference::ComputeSizeInternal() {
832 (type == kVideo ?
sizeof(kVideoHandlerName)
833 :
sizeof(kAudioHandlerName));
836 CodecConfigurationRecord::CodecConfigurationRecord() : box_type(FOURCC_NULL) {}
837 CodecConfigurationRecord::~CodecConfigurationRecord() {}
844 bool CodecConfigurationRecord::ReadWriteInternal(
BoxBuffer* buffer) {
847 RCHECK(buffer->ReadWriteVector(&data, buffer->
Size() - buffer->
Pos()));
849 RCHECK(buffer->ReadWriteVector(&data, data.size()));
854 uint32_t CodecConfigurationRecord::ComputeSizeInternal() {
860 PixelAspectRatio::PixelAspectRatio() : h_spacing(0), v_spacing(0) {}
861 PixelAspectRatio::~PixelAspectRatio() {}
864 bool PixelAspectRatio::ReadWriteInternal(
BoxBuffer* buffer) {
866 buffer->ReadWriteUInt32(&h_spacing) &&
867 buffer->ReadWriteUInt32(&v_spacing));
871 uint32_t PixelAspectRatio::ComputeSizeInternal() {
873 if (h_spacing == 0 && v_spacing == 0)
876 DCHECK(h_spacing != 0 && v_spacing != 0);
877 return HeaderSize() +
sizeof(h_spacing) +
sizeof(v_spacing);
880 VideoSampleEntry::VideoSampleEntry()
881 : format(FOURCC_NULL), data_reference_index(1), width(0), height(0) {}
883 VideoSampleEntry::~VideoSampleEntry() {}
885 if (format == FOURCC_NULL) {
886 LOG(ERROR) <<
"VideoSampleEntry should be parsed according to the "
887 <<
"handler type recovered in its Media ancestor.";
892 bool VideoSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
893 std::vector<uint8_t> compressor_name;
896 format = buffer->
reader()->type();
900 const FourCC actual_format = GetActualFormat();
901 switch (actual_format) {
903 compressor_name.assign(
905 kAvcCompressorName + arraysize(kAvcCompressorName));
909 compressor_name.assign(
911 kHevcCompressorName + arraysize(kHevcCompressorName));
916 compressor_name.assign(
918 kVpcCompressorName + arraysize(kVpcCompressorName));
921 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
924 compressor_name.resize(kCompressorNameSize);
927 uint32_t video_resolution = kVideoResolution;
928 uint16_t video_frame_count = kVideoFrameCount;
929 uint16_t video_depth = kVideoDepth;
930 int16_t predefined = -1;
932 buffer->ReadWriteUInt16(&data_reference_index) &&
934 buffer->ReadWriteUInt16(&width) &&
935 buffer->ReadWriteUInt16(&height) &&
936 buffer->ReadWriteUInt32(&video_resolution) &&
937 buffer->ReadWriteUInt32(&video_resolution) &&
939 buffer->ReadWriteUInt16(&video_frame_count) &&
940 buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
941 buffer->ReadWriteUInt16(&video_depth) &&
942 buffer->ReadWriteInt16(&predefined));
946 if (format == FOURCC_ENCV) {
950 while (sinf.type.type != FOURCC_CENC) {
959 const FourCC actual_format = GetActualFormat();
960 switch (actual_format) {
962 codec_config_record.box_type = FOURCC_AVCC;
966 codec_config_record.box_type = FOURCC_HVCC;
971 codec_config_record.box_type = FOURCC_VPCC;
974 LOG(ERROR) << FourCCToString(actual_format) <<
" is not supported.";
982 uint32_t VideoSampleEntry::ComputeSizeInternal() {
983 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(width) +
984 sizeof(height) +
sizeof(kVideoResolution) * 2 +
985 sizeof(kVideoFrameCount) +
sizeof(kVideoDepth) +
987 codec_config_record.
ComputeSize() + kCompressorNameSize + 6 + 4 + 16 +
991 ElementaryStreamDescriptor::ElementaryStreamDescriptor() {}
992 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {}
995 bool ElementaryStreamDescriptor::ReadWriteInternal(
BoxBuffer* buffer) {
998 std::vector<uint8_t> data;
999 RCHECK(buffer->ReadWriteVector(&data, buffer->
Size() - buffer->
Pos()));
1000 RCHECK(es_descriptor.Parse(data));
1001 if (es_descriptor.
IsAAC()) {
1002 RCHECK(aac_audio_specific_config.
Parse(
1003 es_descriptor.decoder_specific_info()));
1006 DCHECK(buffer->
writer());
1007 es_descriptor.Write(buffer->
writer());
1012 uint32_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1014 if (es_descriptor.object_type() == kForbidden)
1016 return HeaderSize() + es_descriptor.ComputeSize();
1019 DTSSpecific::DTSSpecific() {}
1020 DTSSpecific::~DTSSpecific() {}
1023 bool DTSSpecific::ReadWriteInternal(
BoxBuffer* buffer) {
1028 buffer->ReadWriteVector(&data, buffer->
Size() - buffer->
Pos()));
1030 RCHECK(buffer->ReadWriteVector(&data, data.size()));
1035 uint32_t DTSSpecific::ComputeSizeInternal() {
1037 if (data.size() == 0)
1042 AudioSampleEntry::AudioSampleEntry()
1043 : format(FOURCC_NULL),
1044 data_reference_index(1),
1049 AudioSampleEntry::~AudioSampleEntry() {}
1052 if (format == FOURCC_NULL) {
1053 LOG(ERROR) <<
"AudioSampleEntry should be parsed according to the "
1054 <<
"handler type recovered in its Media ancestor.";
1059 bool AudioSampleEntry::ReadWriteInternal(
BoxBuffer* buffer) {
1061 DCHECK(buffer->
reader());
1062 format = buffer->
reader()->type();
1070 buffer->ReadWriteUInt16(&data_reference_index) &&
1072 buffer->ReadWriteUInt16(&channelcount) &&
1073 buffer->ReadWriteUInt16(&samplesize) &&
1075 buffer->ReadWriteUInt32(&samplerate));
1080 if (format == FOURCC_ENCA) {
1084 while (sinf.type.type != FOURCC_CENC) {
1099 uint32_t AudioSampleEntry::ComputeSizeInternal() {
1100 return HeaderSize() +
sizeof(data_reference_index) +
sizeof(channelcount) +
1101 sizeof(samplesize) +
sizeof(samplerate) + sinf.
ComputeSize() +
1107 MediaHeader::MediaHeader()
1108 : creation_time(0), modification_time(0), timescale(0), duration(0) {
1111 MediaHeader::~MediaHeader() {}
1114 bool MediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1117 uint8_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1120 buffer->ReadWriteUInt32(×cale) &&
1126 std::vector<uint8_t> temp;
1127 RCHECK(buffer->ReadWriteVector(&temp, 2));
1130 bit_reader.SkipBits(1);
1131 for (
int i = 0; i < 3; ++i) {
1132 CHECK(bit_reader.ReadBits(5, &language[i]));
1133 language[i] += 0x60;
1138 const char kUndefinedLanguage[] =
"und";
1139 if (language[0] == 0)
1140 strcpy(language, kUndefinedLanguage);
1144 for (
int i = 0; i < 3; ++i)
1145 lang |= (language[i] - 0x60) << ((2 - i) * 5);
1146 RCHECK(buffer->ReadWriteUInt16(&lang));
1153 uint32_t MediaHeader::ComputeSizeInternal() {
1154 version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1156 sizeof(uint32_t) * (1 + version) * 3 + 2 +
1160 VideoMediaHeader::VideoMediaHeader()
1161 : graphicsmode(0), opcolor_red(0), opcolor_green(0), opcolor_blue(0) {
1162 const uint32_t kVideoMediaHeaderFlags = 1;
1163 flags = kVideoMediaHeaderFlags;
1165 VideoMediaHeader::~VideoMediaHeader() {}
1167 bool VideoMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1169 buffer->ReadWriteUInt16(&graphicsmode) &&
1170 buffer->ReadWriteUInt16(&opcolor_red) &&
1171 buffer->ReadWriteUInt16(&opcolor_green) &&
1172 buffer->ReadWriteUInt16(&opcolor_blue));
1176 uint32_t VideoMediaHeader::ComputeSizeInternal() {
1177 return HeaderSize() +
sizeof(graphicsmode) +
sizeof(opcolor_red) +
1178 sizeof(opcolor_green) +
sizeof(opcolor_blue);
1181 SoundMediaHeader::SoundMediaHeader() : balance(0) {}
1182 SoundMediaHeader::~SoundMediaHeader() {}
1184 bool SoundMediaHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1186 buffer->ReadWriteUInt16(&balance) &&
1191 uint32_t SoundMediaHeader::ComputeSizeInternal() {
1192 return HeaderSize() +
sizeof(balance) +
sizeof(uint16_t);
1195 DataEntryUrl::DataEntryUrl() {
1196 const uint32_t kDataEntryUrlFlags = 1;
1197 flags = kDataEntryUrlFlags;
1199 DataEntryUrl::~DataEntryUrl() {}
1201 bool DataEntryUrl::ReadWriteInternal(
BoxBuffer* buffer) {
1204 RCHECK(buffer->ReadWriteVector(&location, buffer->
Size() - buffer->
Pos()));
1206 RCHECK(buffer->ReadWriteVector(&location, location.size()));
1211 uint32_t DataEntryUrl::ComputeSizeInternal() {
1215 DataReference::DataReference() {
1217 data_entry.resize(1);
1219 DataReference::~DataReference() {}
1221 bool DataReference::ReadWriteInternal(
BoxBuffer* buffer) {
1222 uint32_t entry_count = data_entry.size();
1224 buffer->ReadWriteUInt32(&entry_count));
1225 data_entry.resize(entry_count);
1227 for (uint32_t i = 0; i < entry_count; ++i)
1232 uint32_t DataReference::ComputeSizeInternal() {
1233 uint32_t count = data_entry.size();
1234 uint32_t box_size =
HeaderSize() +
sizeof(count);
1235 for (uint32_t i = 0; i < count; ++i)
1240 DataInformation::DataInformation() {}
1241 DataInformation::~DataInformation() {}
1244 bool DataInformation::ReadWriteInternal(
BoxBuffer* buffer) {
1250 uint32_t DataInformation::ComputeSizeInternal() {
1254 MediaInformation::MediaInformation() {}
1255 MediaInformation::~MediaInformation() {}
1258 bool MediaInformation::ReadWriteInternal(
BoxBuffer* buffer) {
1263 if (sample_table.description.type == kVideo)
1265 else if (sample_table.description.type == kAudio)
1273 uint32_t MediaInformation::ComputeSizeInternal() {
1276 if (sample_table.description.type == kVideo)
1278 else if (sample_table.description.type == kAudio)
1287 bool Media::ReadWriteInternal(
BoxBuffer* buffer) {
1299 information.sample_table.description.type = handler.type;
1301 DCHECK_EQ(information.sample_table.description.type, handler.type);
1307 uint32_t Media::ComputeSizeInternal() {
1316 bool Track::ReadWriteInternal(
BoxBuffer* buffer) {
1325 uint32_t Track::ComputeSizeInternal() {
1330 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
1331 MovieExtendsHeader::~MovieExtendsHeader() {}
1334 bool MovieExtendsHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1336 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1341 uint32_t MovieExtendsHeader::ComputeSizeInternal() {
1343 if (fragment_duration == 0)
1345 version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
1346 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
1349 TrackExtends::TrackExtends()
1351 default_sample_description_index(0),
1352 default_sample_duration(0),
1353 default_sample_size(0),
1354 default_sample_flags(0) {}
1355 TrackExtends::~TrackExtends() {}
1358 bool TrackExtends::ReadWriteInternal(
BoxBuffer* buffer) {
1360 buffer->ReadWriteUInt32(&track_id) &&
1361 buffer->ReadWriteUInt32(&default_sample_description_index) &&
1362 buffer->ReadWriteUInt32(&default_sample_duration) &&
1363 buffer->ReadWriteUInt32(&default_sample_size) &&
1364 buffer->ReadWriteUInt32(&default_sample_flags));
1368 uint32_t TrackExtends::ComputeSizeInternal() {
1370 sizeof(default_sample_description_index) +
1371 sizeof(default_sample_duration) +
sizeof(default_sample_size) +
1372 sizeof(default_sample_flags);
1375 MovieExtends::MovieExtends() {}
1376 MovieExtends::~MovieExtends() {}
1379 bool MovieExtends::ReadWriteInternal(
BoxBuffer* buffer) {
1384 DCHECK(buffer->
reader());
1387 for (uint32_t i = 0; i < tracks.size(); ++i)
1393 uint32_t MovieExtends::ComputeSizeInternal() {
1395 if (tracks.size() == 0)
1398 for (uint32_t i = 0; i < tracks.size(); ++i)
1407 bool Movie::ReadWriteInternal(
BoxBuffer* buffer) {
1418 for (uint32_t i = 0; i < tracks.size(); ++i)
1420 for (uint32_t i = 0; i < pssh.size(); ++i)
1426 uint32_t Movie::ComputeSizeInternal() {
1429 for (uint32_t i = 0; i < tracks.size(); ++i)
1431 for (uint32_t i = 0; i < pssh.size(); ++i)
1436 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
1437 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {}
1440 bool TrackFragmentDecodeTime::ReadWriteInternal(
BoxBuffer* buffer) {
1442 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1447 uint32_t TrackFragmentDecodeTime::ComputeSizeInternal() {
1448 version = IsFitIn32Bits(decode_time) ? 0 : 1;
1449 return HeaderSize() +
sizeof(uint32_t) * (1 + version);
1452 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
1453 MovieFragmentHeader::~MovieFragmentHeader() {}
1456 bool MovieFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1458 buffer->ReadWriteUInt32(&sequence_number);
1461 uint32_t MovieFragmentHeader::ComputeSizeInternal() {
1462 return HeaderSize() +
sizeof(sequence_number);
1465 TrackFragmentHeader::TrackFragmentHeader()
1467 sample_description_index(0),
1468 default_sample_duration(0),
1469 default_sample_size(0),
1470 default_sample_flags(0) {}
1472 TrackFragmentHeader::~TrackFragmentHeader() {}
1475 bool TrackFragmentHeader::ReadWriteInternal(
BoxBuffer* buffer) {
1477 buffer->ReadWriteUInt32(&track_id));
1479 if (flags & kBaseDataOffsetPresentMask) {
1484 uint64_t base_data_offset;
1485 RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
1486 DLOG(WARNING) <<
"base-data-offset-present is not expected. Assumes "
1487 "default-base-is-moof.";
1490 if (flags & kSampleDescriptionIndexPresentMask) {
1491 RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
1492 }
else if (buffer->
Reading()) {
1493 sample_description_index = 0;
1496 if (flags & kDefaultSampleDurationPresentMask) {
1497 RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
1498 }
else if (buffer->
Reading()) {
1499 default_sample_duration = 0;
1502 if (flags & kDefaultSampleSizePresentMask) {
1503 RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
1504 }
else if (buffer->
Reading()) {
1505 default_sample_size = 0;
1508 if (flags & kDefaultSampleFlagsPresentMask)
1509 RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
1513 uint32_t TrackFragmentHeader::ComputeSizeInternal() {
1514 uint32_t box_size =
HeaderSize() +
sizeof(track_id);
1515 if (flags & kSampleDescriptionIndexPresentMask)
1516 box_size +=
sizeof(sample_description_index);
1517 if (flags & kDefaultSampleDurationPresentMask)
1518 box_size +=
sizeof(default_sample_duration);
1519 if (flags & kDefaultSampleSizePresentMask)
1520 box_size +=
sizeof(default_sample_size);
1521 if (flags & kDefaultSampleFlagsPresentMask)
1522 box_size +=
sizeof(default_sample_flags);
1526 TrackFragmentRun::TrackFragmentRun() : sample_count(0), data_offset(0) {}
1527 TrackFragmentRun::~TrackFragmentRun() {}
1530 bool TrackFragmentRun::ReadWriteInternal(
BoxBuffer* buffer) {
1536 if (flags & kSampleCompTimeOffsetsPresentMask) {
1537 for (uint32_t i = 0; i < sample_count; ++i) {
1538 if (sample_composition_time_offsets[i] < 0) {
1547 buffer->ReadWriteUInt32(&sample_count));
1549 bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
1550 bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
1551 bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
1552 bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
1553 bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
1554 bool sample_composition_time_offsets_present =
1555 (flags & kSampleCompTimeOffsetsPresentMask) != 0;
1557 if (data_offset_present) {
1558 RCHECK(buffer->ReadWriteUInt32(&data_offset));
1569 uint32_t first_sample_flags;
1572 if (first_sample_flags_present)
1573 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
1575 if (sample_duration_present)
1576 sample_durations.resize(sample_count);
1577 if (sample_size_present)
1578 sample_sizes.resize(sample_count);
1579 if (sample_flags_present)
1580 sample_flags.resize(sample_count);
1581 if (sample_composition_time_offsets_present)
1582 sample_composition_time_offsets.resize(sample_count);
1584 if (first_sample_flags_present) {
1585 first_sample_flags = sample_flags[0];
1586 DCHECK(sample_flags.size() == 1);
1587 RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
1590 if (sample_duration_present)
1591 DCHECK(sample_durations.size() == sample_count);
1592 if (sample_size_present)
1593 DCHECK(sample_sizes.size() == sample_count);
1594 if (sample_flags_present)
1595 DCHECK(sample_flags.size() == sample_count);
1596 if (sample_composition_time_offsets_present)
1597 DCHECK(sample_composition_time_offsets.size() == sample_count);
1600 for (uint32_t i = 0; i < sample_count; ++i) {
1601 if (sample_duration_present)
1602 RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
1603 if (sample_size_present)
1604 RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
1605 if (sample_flags_present)
1606 RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
1608 if (sample_composition_time_offsets_present) {
1610 uint32_t sample_offset = sample_composition_time_offsets[i];
1611 RCHECK(buffer->ReadWriteUInt32(&sample_offset));
1612 sample_composition_time_offsets[i] = sample_offset;
1614 int32_t sample_offset = sample_composition_time_offsets[i];
1615 RCHECK(buffer->ReadWriteInt32(&sample_offset));
1616 sample_composition_time_offsets[i] = sample_offset;
1622 if (first_sample_flags_present) {
1623 if (sample_flags.size() == 0) {
1624 sample_flags.push_back(first_sample_flags);
1626 sample_flags[0] = first_sample_flags;
1633 uint32_t TrackFragmentRun::ComputeSizeInternal() {
1634 uint32_t box_size =
HeaderSize() +
sizeof(sample_count);
1635 if (flags & kDataOffsetPresentMask)
1636 box_size +=
sizeof(data_offset);
1637 if (flags & kFirstSampleFlagsPresentMask)
1638 box_size +=
sizeof(uint32_t);
1639 uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
1640 (flags & kSampleSizePresentMask ? 1 : 0) +
1641 (flags & kSampleFlagsPresentMask ? 1 : 0) +
1642 (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
1643 box_size += fields *
sizeof(uint32_t) * sample_count;
1647 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
1648 SampleToGroup::~SampleToGroup() {}
1651 bool SampleToGroup::ReadWriteInternal(
BoxBuffer* buffer) {
1653 buffer->ReadWriteUInt32(&grouping_type));
1655 RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1657 if (grouping_type != FOURCC_SEIG) {
1659 DLOG(WARNING) <<
"Sample group "
1660 << FourCCToString(static_cast<FourCC>(grouping_type))
1661 <<
" is not supported.";
1665 uint32_t count = entries.size();
1666 RCHECK(buffer->ReadWriteUInt32(&count));
1667 entries.resize(count);
1668 for (uint32_t i = 0; i < count; ++i) {
1669 RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1670 buffer->ReadWriteUInt32(&entries[i].group_description_index));
1675 uint32_t SampleToGroup::ComputeSizeInternal() {
1677 if (entries.empty())
1679 return HeaderSize() +
sizeof(grouping_type) +
1680 (version == 1 ?
sizeof(grouping_type_parameter) : 0) +
1681 sizeof(uint32_t) + entries.size() *
sizeof(entries[0]);
1684 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1685 : is_encrypted(false), iv_size(0) {
1687 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {};
1689 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
1690 SampleGroupDescription::~SampleGroupDescription() {}
1693 bool SampleGroupDescription::ReadWriteInternal(
BoxBuffer* buffer) {
1695 buffer->ReadWriteUInt32(&grouping_type));
1697 if (grouping_type != FOURCC_SEIG) {
1699 DLOG(WARNING) <<
"Sample group '" << grouping_type <<
"' is not supported.";
1703 const size_t kEntrySize =
sizeof(uint32_t) + kCencKeyIdSize;
1704 uint32_t default_length = 0;
1707 RCHECK(buffer->ReadWriteUInt32(&default_length));
1708 RCHECK(default_length == 0 || default_length >= kEntrySize);
1710 default_length = kEntrySize;
1711 RCHECK(buffer->ReadWriteUInt32(&default_length));
1715 uint32_t count = entries.size();
1716 RCHECK(buffer->ReadWriteUInt32(&count));
1717 entries.resize(count);
1718 for (uint32_t i = 0; i < count; ++i) {
1720 if (buffer->
Reading() && default_length == 0) {
1721 uint32_t description_length = 0;
1722 RCHECK(buffer->ReadWriteUInt32(&description_length));
1723 RCHECK(description_length >= kEntrySize);
1728 if (entries[i].key_id.size() != kCencKeyIdSize) {
1729 LOG(WARNING) <<
"CENC defines key id length of " << kCencKeyIdSize
1730 <<
" bytes; got " << entries[i].key_id.size()
1731 <<
". Resized accordingly.";
1732 entries[i].key_id.resize(kCencKeyIdSize);
1736 uint8_t flag = entries[i].is_encrypted ? 1 : 0;
1738 buffer->ReadWriteUInt8(&flag) &&
1739 buffer->ReadWriteUInt8(&entries[i].iv_size) &&
1740 buffer->ReadWriteVector(&entries[i].key_id, kCencKeyIdSize));
1743 entries[i].is_encrypted = (flag != 0);
1744 if (entries[i].is_encrypted) {
1745 RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
1747 RCHECK(entries[i].iv_size == 0);
1754 uint32_t SampleGroupDescription::ComputeSizeInternal() {
1758 if (entries.empty())
1760 const size_t kEntrySize =
sizeof(uint32_t) + kCencKeyIdSize;
1761 return HeaderSize() +
sizeof(grouping_type) +
1762 (version == 1 ?
sizeof(uint32_t) : 0) +
sizeof(uint32_t) +
1763 entries.size() * kEntrySize;
1766 TrackFragment::TrackFragment() : decode_time_absent(false) {}
1767 TrackFragment::~TrackFragment() {}
1770 bool TrackFragment::ReadWriteInternal(
BoxBuffer* buffer) {
1775 DCHECK(buffer->
reader());
1777 if (!decode_time_absent)
1785 while (sample_to_group.grouping_type != FOURCC_SEIG &&
1789 while (sample_group_description.grouping_type != FOURCC_SEIG &&
1794 if (!decode_time_absent)
1796 for (uint32_t i = 0; i < runs.size(); ++i)
1805 uint32_t TrackFragment::ComputeSizeInternal() {
1810 for (uint32_t i = 0; i < runs.size(); ++i)
1815 MovieFragment::MovieFragment() {}
1816 MovieFragment::~MovieFragment() {}
1819 bool MovieFragment::ReadWriteInternal(
BoxBuffer* buffer) {
1829 for (uint32_t i = 0; i < tracks.size(); ++i)
1831 for (uint32_t i = 0; i < pssh.size(); ++i)
1837 uint32_t MovieFragment::ComputeSizeInternal() {
1839 for (uint32_t i = 0; i < tracks.size(); ++i)
1841 for (uint32_t i = 0; i < pssh.size(); ++i)
1846 SegmentIndex::SegmentIndex()
1849 earliest_presentation_time(0),
1851 SegmentIndex::~SegmentIndex() {}
1854 bool SegmentIndex::ReadWriteInternal(
BoxBuffer* buffer) {
1856 buffer->ReadWriteUInt32(&reference_id) &&
1857 buffer->ReadWriteUInt32(×cale));
1859 size_t num_bytes = (version == 1) ?
sizeof(uint64_t) :
sizeof(uint32_t);
1864 uint16_t reference_count = references.size();
1866 buffer->ReadWriteUInt16(&reference_count));
1867 references.resize(reference_count);
1869 uint32_t reference_type_size;
1871 for (uint32_t i = 0; i < reference_count; ++i) {
1873 reference_type_size = references[i].referenced_size;
1874 if (references[i].reference_type)
1875 reference_type_size |= (1 << 31);
1876 sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
1877 if (references[i].starts_with_sap)
1880 RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
1881 buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
1882 buffer->ReadWriteUInt32(&sap));
1884 references[i].reference_type = (reference_type_size >> 31) ?
true :
false;
1885 references[i].referenced_size = reference_type_size & ~(1 << 31);
1886 references[i].starts_with_sap = (sap >> 31) ?
true :
false;
1887 references[i].sap_type =
1888 static_cast<SegmentReference::SAPType
>((sap >> 28) & 0x07);
1889 references[i].sap_delta_time = sap & ~(0xF << 28);
1895 uint32_t SegmentIndex::ComputeSizeInternal() {
1896 version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
1897 return HeaderSize() +
sizeof(reference_id) +
sizeof(timescale) +
1898 sizeof(uint32_t) * (1 + version) * 2 + 2 *
sizeof(uint16_t) +
1899 3 *
sizeof(uint32_t) * references.size();
1902 MediaData::MediaData() : data_size(0) {}
1903 MediaData::~MediaData() {}
1906 bool MediaData::ReadWriteInternal(
BoxBuffer* buffer) {
1907 NOTIMPLEMENTED() <<
"Actual data is parsed and written separately.";
1911 uint32_t MediaData::ComputeSizeInternal() {
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override