Shaka Packager SDK
box_definitions.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp4/box_definitions.h"
6 
7 #include <limits>
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/macros.h"
12 #include "packager/media/base/rcheck.h"
13 #include "packager/media/formats/mp4/box_buffer.h"
14 
15 namespace {
16 const uint32_t kFourCCSize = 4;
17 
18 // Key Id size as defined in CENC spec.
19 const uint32_t kCencKeyIdSize = 16;
20 
21 // 9 uint32_t in big endian formatted array.
22 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
24  0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
25 
26 // Default entries for HandlerReference box.
27 const char kVideoHandlerName[] = "VideoHandler";
28 const char kAudioHandlerName[] = "SoundHandler";
29 const char kTextHandlerName[] = "TextHandler";
30 
31 // Default values for VideoSampleEntry box.
32 const uint32_t kVideoResolution = 0x00480000; // 72 dpi.
33 const uint16_t kVideoFrameCount = 1;
34 const uint16_t kVideoDepth = 0x0018;
35 
36 const uint32_t kCompressorNameSize = 32u;
37 const char kAv1CompressorName[] = "\012AOM Coding";
38 const char kAvcCompressorName[] = "\012AVC Coding";
39 const char kHevcCompressorName[] = "\013HEVC Coding";
40 const char kVpcCompressorName[] = "\012VPC Coding";
41 
42 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
43 // 64-bit (8-byte) or 128-bit (16-byte).
44 // |per_sample_iv_size| of 0 means constant_iv is used.
45 bool IsIvSizeValid(uint8_t per_sample_iv_size) {
46  return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
47  per_sample_iv_size == 16;
48 }
49 
50 // Default values to construct the following fields in ddts box. Values are set
51 // according to FFMPEG.
52 // bit(2) FrameDuration; // 3 = 4096
53 // bit(5) StreamConstruction; // 18
54 // bit(1) CoreLFEPresent; // 0 = none
55 // bit(6) CoreLayout; // 31 = ignore core layout
56 // bit(14) CoreSize; // 0
57 // bit(1) StereoDownmix // 0 = none
58 // bit(3) RepresentationType; // 4
59 // bit(16) ChannelLayout; // 0xf = 5.1 channel layout.
60 // bit(1) MultiAssetFlag // 0 = single asset
61 // bit(1) LBRDurationMod // 0 = ignore
62 // bit(1) ReservedBoxPresent // 0 = none
63 // bit(5) Reserved // 0
64 const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
65 
66 // Utility functions to check if the 64bit integers can fit in 32bit integer.
67 bool IsFitIn32Bits(uint64_t a) {
68  return a <= std::numeric_limits<uint32_t>::max();
69 }
70 
71 bool IsFitIn32Bits(int64_t a) {
72  return a <= std::numeric_limits<int32_t>::max() &&
73  a >= std::numeric_limits<int32_t>::min();
74 }
75 
76 template <typename T1, typename T2>
77 bool IsFitIn32Bits(T1 a1, T2 a2) {
78  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
79 }
80 
81 template <typename T1, typename T2, typename T3>
82 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
83  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
84 }
85 
86 } // namespace
87 
88 namespace shaka {
89 namespace media {
90 namespace mp4 {
91 
92 namespace {
93 
94 TrackType FourCCToTrackType(FourCC fourcc) {
95  switch (fourcc) {
96  case FOURCC_vide:
97  return kVideo;
98  case FOURCC_soun:
99  return kAudio;
100  case FOURCC_text:
101  return kText;
102  default:
103  return kInvalid;
104  }
105 }
106 
107 FourCC TrackTypeToFourCC(TrackType track_type) {
108  switch (track_type) {
109  case kVideo:
110  return FOURCC_vide;
111  case kAudio:
112  return FOURCC_soun;
113  case kText:
114  return FOURCC_text;
115  default:
116  return FOURCC_NULL;
117  }
118 }
119 
120 bool IsProtectionSchemeSupported(FourCC scheme) {
121  return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
122  scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
123 }
124 
125 } // namespace
126 
127 FileType::FileType() = default;
128 FileType::~FileType() = default;
129 
130 FourCC FileType::BoxType() const {
131  return FOURCC_ftyp;
132 }
133 
134 bool FileType::ReadWriteInternal(BoxBuffer* buffer) {
135  RCHECK(ReadWriteHeaderInternal(buffer) &&
136  buffer->ReadWriteFourCC(&major_brand) &&
137  buffer->ReadWriteUInt32(&minor_version));
138  size_t num_brands;
139  if (buffer->Reading()) {
140  RCHECK(buffer->BytesLeft() % sizeof(FourCC) == 0);
141  num_brands = buffer->BytesLeft() / sizeof(FourCC);
142  compatible_brands.resize(num_brands);
143  } else {
144  num_brands = compatible_brands.size();
145  }
146  for (size_t i = 0; i < num_brands; ++i)
147  RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
148  return true;
149 }
150 
151 size_t FileType::ComputeSizeInternal() {
152  return HeaderSize() + kFourCCSize + sizeof(minor_version) +
153  kFourCCSize * compatible_brands.size();
154 }
155 
156 FourCC SegmentType::BoxType() const {
157  return FOURCC_styp;
158 }
159 
160 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() = default;
161 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() = default;
162 
164  return FOURCC_pssh;
165 }
166 
167 bool ProtectionSystemSpecificHeader::ReadWriteInternal(BoxBuffer* buffer) {
168  if (buffer->Reading()) {
169  BoxReader* reader = buffer->reader();
170  DCHECK(reader);
171  raw_box.assign(reader->data(), reader->data() + reader->size());
172  } else {
173  DCHECK(!raw_box.empty());
174  buffer->writer()->AppendVector(raw_box);
175  }
176 
177  return true;
178 }
179 
180 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
181  return raw_box.size();
182 }
183 
184 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() = default;
185 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() = default;
186 
188  return FOURCC_saio;
189 }
190 
191 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(BoxBuffer* buffer) {
192  RCHECK(ReadWriteHeaderInternal(buffer));
193  if (flags & 1)
194  RCHECK(buffer->IgnoreBytes(8)); // aux_info_type and parameter.
195 
196  uint32_t count = static_cast<uint32_t>(offsets.size());
197  RCHECK(buffer->ReadWriteUInt32(&count));
198  offsets.resize(count);
199 
200  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
201  for (uint32_t i = 0; i < count; ++i)
202  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], num_bytes));
203  return true;
204 }
205 
206 size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
207  // This box is optional. Skip it if it is empty.
208  if (offsets.size() == 0)
209  return 0;
210  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
211  return HeaderSize() + sizeof(uint32_t) + num_bytes * offsets.size();
212 }
213 
214 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() = default;
215 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() = default;
216 
218  return FOURCC_saiz;
219 }
220 
221 bool SampleAuxiliaryInformationSize::ReadWriteInternal(BoxBuffer* buffer) {
222  RCHECK(ReadWriteHeaderInternal(buffer));
223  if (flags & 1)
224  RCHECK(buffer->IgnoreBytes(8));
225 
226  RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
227  buffer->ReadWriteUInt32(&sample_count));
228  if (default_sample_info_size == 0)
229  RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
230  return true;
231 }
232 
233 size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
234  // This box is optional. Skip it if it is empty.
235  if (sample_count == 0)
236  return 0;
237  return HeaderSize() + sizeof(default_sample_info_size) +
238  sizeof(sample_count) +
239  (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
240 }
241 
242 bool SampleEncryptionEntry::ReadWrite(uint8_t iv_size,
243  bool has_subsamples,
244  BoxBuffer* buffer) {
245  DCHECK(IsIvSizeValid(iv_size));
246  DCHECK(buffer);
247 
248  RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
249 
250  if (!has_subsamples) {
251  subsamples.clear();
252  return true;
253  }
254 
255  uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
256  RCHECK(buffer->ReadWriteUInt16(&subsample_count));
257  RCHECK(subsample_count > 0);
258  subsamples.resize(subsample_count);
259  for (auto& subsample : subsamples) {
260  RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
261  buffer->ReadWriteUInt32(&subsample.cipher_bytes));
262  }
263  return true;
264 }
265 
267  bool has_subsamples,
268  BufferReader* reader) {
269  DCHECK(IsIvSizeValid(iv_size));
270  DCHECK(reader);
271 
272  initialization_vector.resize(iv_size);
273  RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
274 
275  if (!has_subsamples) {
276  subsamples.clear();
277  return true;
278  }
279 
280  uint16_t subsample_count;
281  RCHECK(reader->Read2(&subsample_count));
282  RCHECK(subsample_count > 0);
283  subsamples.resize(subsample_count);
284  for (auto& subsample : subsamples) {
285  RCHECK(reader->Read2(&subsample.clear_bytes) &&
286  reader->Read4(&subsample.cipher_bytes));
287  }
288  return true;
289 }
290 
292  const uint32_t subsample_entry_size = sizeof(uint16_t) + sizeof(uint32_t);
293  const uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
294  return static_cast<uint32_t>(
295  initialization_vector.size() +
296  (subsample_count > 0
297  ? (sizeof(subsample_count) + subsample_entry_size * subsample_count)
298  : 0));
299 }
300 
302  uint32_t size = 0;
303  for (uint32_t i = 0; i < subsamples.size(); ++i)
304  size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
305  return size;
306 }
307 
308 SampleEncryption::SampleEncryption() = default;
309 SampleEncryption::~SampleEncryption() = default;
310 
312  return FOURCC_senc;
313 }
314 
315 bool SampleEncryption::ReadWriteInternal(BoxBuffer* buffer) {
316  RCHECK(ReadWriteHeaderInternal(buffer));
317 
318  // If we don't know |iv_size|, store sample encryption data to parse later
319  // after we know iv_size.
320  if (buffer->Reading() && iv_size == SampleEncryption::kInvalidIvSize) {
321  RCHECK(
322  buffer->ReadWriteVector(&sample_encryption_data, buffer->BytesLeft()));
323  return true;
324  }
325 
326  if (!IsIvSizeValid(iv_size)) {
327  LOG(ERROR)
328  << "IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
329  << iv_size;
330  return false;
331  }
332 
333  uint32_t sample_count =
334  static_cast<uint32_t>(sample_encryption_entries.size());
335  RCHECK(buffer->ReadWriteUInt32(&sample_count));
336 
337  sample_encryption_entries.resize(sample_count);
338  for (auto& sample_encryption_entry : sample_encryption_entries) {
339  RCHECK(sample_encryption_entry.ReadWrite(
340  iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
341  }
342  return true;
343 }
344 
345 size_t SampleEncryption::ComputeSizeInternal() {
346  const uint32_t sample_count =
347  static_cast<uint32_t>(sample_encryption_entries.size());
348  if (sample_count == 0) {
349  // Sample encryption box is optional. Skip it if it is empty.
350  return 0;
351  }
352 
353  DCHECK(IsIvSizeValid(iv_size));
354  size_t box_size = HeaderSize() + sizeof(sample_count);
355  if (flags & kUseSubsampleEncryption) {
356  for (const SampleEncryptionEntry& sample_encryption_entry :
357  sample_encryption_entries) {
358  box_size += sample_encryption_entry.ComputeSize();
359  }
360  } else {
361  box_size += sample_count * iv_size;
362  }
363  return box_size;
364 }
365 
367  uint8_t iv_size,
368  std::vector<SampleEncryptionEntry>* sample_encryption_entries) const {
369  DCHECK(IsIvSizeValid(iv_size));
370 
371  BufferReader reader(sample_encryption_data.data(),
372  sample_encryption_data.size());
373  uint32_t sample_count = 0;
374  RCHECK(reader.Read4(&sample_count));
375 
376  sample_encryption_entries->resize(sample_count);
377  for (auto& sample_encryption_entry : *sample_encryption_entries) {
378  RCHECK(sample_encryption_entry.ParseFromBuffer(
379  iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) != 0);
380  }
381  return true;
382 }
383 
384 OriginalFormat::OriginalFormat() = default;
385 OriginalFormat::~OriginalFormat() = default;
386 
387 FourCC OriginalFormat::BoxType() const {
388  return FOURCC_frma;
389 }
390 
391 bool OriginalFormat::ReadWriteInternal(BoxBuffer* buffer) {
392  return ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&format);
393 }
394 
395 size_t OriginalFormat::ComputeSizeInternal() {
396  return HeaderSize() + kFourCCSize;
397 }
398 
399 SchemeType::SchemeType() = default;
400 SchemeType::~SchemeType() = default;
401 
402 FourCC SchemeType::BoxType() const {
403  return FOURCC_schm;
404 }
405 
406 bool SchemeType::ReadWriteInternal(BoxBuffer* buffer) {
407  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&type) &&
408  buffer->ReadWriteUInt32(&version));
409  return true;
410 }
411 
412 size_t SchemeType::ComputeSizeInternal() {
413  return HeaderSize() + kFourCCSize + sizeof(version);
414 }
415 
416 TrackEncryption::TrackEncryption() = default;
417 TrackEncryption::~TrackEncryption() = default;
418 
419 FourCC TrackEncryption::BoxType() const {
420  return FOURCC_tenc;
421 }
422 
423 bool TrackEncryption::ReadWriteInternal(BoxBuffer* buffer) {
424  if (!buffer->Reading()) {
425  if (default_kid.size() != kCencKeyIdSize) {
426  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
427  << " bytes; got " << default_kid.size()
428  << ". Resized accordingly.";
429  default_kid.resize(kCencKeyIdSize);
430  }
431  RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
432  if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
433  // Version 1 box is needed for pattern-based encryption.
434  version = 1;
435  }
436  }
437 
438  RCHECK(ReadWriteHeaderInternal(buffer) &&
439  buffer->IgnoreBytes(1)); // reserved.
440 
441  uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
442  RCHECK(buffer->ReadWriteUInt8(&pattern));
443  default_crypt_byte_block = pattern >> 4;
444  default_skip_byte_block = pattern & 0x0F;
445 
446  RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
447  buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
448  buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
449 
450  if (default_is_protected == 1) {
451  if (default_per_sample_iv_size == 0) { // For constant iv.
452  uint8_t default_constant_iv_size =
453  static_cast<uint8_t>(default_constant_iv.size());
454  RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
455  RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
456  RCHECK(buffer->ReadWriteVector(&default_constant_iv,
457  default_constant_iv_size));
458  } else {
459  RCHECK(default_per_sample_iv_size == 8 ||
460  default_per_sample_iv_size == 16);
461  RCHECK(default_constant_iv.empty());
462  }
463  } else {
464  // Expect |default_is_protected| to be 0, i.e. not protected. Other values
465  // of |default_is_protected| is not supported.
466  RCHECK(default_is_protected == 0);
467  RCHECK(default_per_sample_iv_size == 0);
468  RCHECK(default_constant_iv.empty());
469  }
470  return true;
471 }
472 
473 size_t TrackEncryption::ComputeSizeInternal() {
474  return HeaderSize() + sizeof(uint32_t) + kCencKeyIdSize +
475  (default_constant_iv.empty()
476  ? 0
477  : (sizeof(uint8_t) + default_constant_iv.size()));
478 }
479 
480 SchemeInfo::SchemeInfo() = default;
481 SchemeInfo::~SchemeInfo() = default;
482 
483 FourCC SchemeInfo::BoxType() const {
484  return FOURCC_schi;
485 }
486 
487 bool SchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
488  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
489  buffer->ReadWriteChild(&track_encryption));
490  return true;
491 }
492 
493 size_t SchemeInfo::ComputeSizeInternal() {
494  return HeaderSize() + track_encryption.ComputeSize();
495 }
496 
497 ProtectionSchemeInfo::ProtectionSchemeInfo() = default;
498 ProtectionSchemeInfo::~ProtectionSchemeInfo() = default;
499 
501  return FOURCC_sinf;
502 }
503 
504 bool ProtectionSchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
505  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
506  buffer->ReadWriteChild(&format) && buffer->ReadWriteChild(&type));
507  if (IsProtectionSchemeSupported(type.type)) {
508  RCHECK(buffer->ReadWriteChild(&info));
509  } else {
510  DLOG(WARNING) << "Ignore unsupported protection scheme: "
511  << FourCCToString(type.type);
512  }
513  // Other protection schemes are silently ignored. Since the protection scheme
514  // type can't be determined until this box is opened, we return 'true' for
515  // non-CENC protection scheme types. It is the parent box's responsibility to
516  // ensure that this scheme type is a supported one.
517  return true;
518 }
519 
520 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
521  // Skip sinf box if it is not initialized.
522  if (format.format == FOURCC_NULL)
523  return 0;
524  return HeaderSize() + format.ComputeSize() + type.ComputeSize() +
525  info.ComputeSize();
526 }
527 
528 MovieHeader::MovieHeader() = default;
529 MovieHeader::~MovieHeader() = default;
530 
531 FourCC MovieHeader::BoxType() const {
532  return FOURCC_mvhd;
533 }
534 
535 bool MovieHeader::ReadWriteInternal(BoxBuffer* buffer) {
536  RCHECK(ReadWriteHeaderInternal(buffer));
537 
538  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
539  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
540  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
541  buffer->ReadWriteUInt32(&timescale) &&
542  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
543 
544  std::vector<uint8_t> matrix(kUnityMatrix,
545  kUnityMatrix + arraysize(kUnityMatrix));
546  RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
547  buffer->IgnoreBytes(10) && // reserved
548  buffer->ReadWriteVector(&matrix, matrix.size()) &&
549  buffer->IgnoreBytes(24) && // predefined zero
550  buffer->ReadWriteUInt32(&next_track_id));
551  return true;
552 }
553 
554 size_t MovieHeader::ComputeSizeInternal() {
555  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
556  return HeaderSize() + sizeof(uint32_t) * (1 + version) * 3 +
557  sizeof(timescale) + sizeof(rate) + sizeof(volume) +
558  sizeof(next_track_id) + sizeof(kUnityMatrix) + 10 +
559  24; // 10 bytes reserved, 24 bytes predefined.
560 }
561 
562 TrackHeader::TrackHeader() {
563  flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
564 }
565 
566 TrackHeader::~TrackHeader() = default;
567 
568 FourCC TrackHeader::BoxType() const {
569  return FOURCC_tkhd;
570 }
571 
572 bool TrackHeader::ReadWriteInternal(BoxBuffer* buffer) {
573  RCHECK(ReadWriteHeaderInternal(buffer));
574 
575  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
576  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
577  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
578  buffer->ReadWriteUInt32(&track_id) &&
579  buffer->IgnoreBytes(4) && // reserved
580  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
581 
582  if (!buffer->Reading()) {
583  // Set default value for volume, if track is audio, 0x100 else 0.
584  if (volume == -1)
585  volume = (width != 0 && height != 0) ? 0 : 0x100;
586  }
587  std::vector<uint8_t> matrix(kUnityMatrix,
588  kUnityMatrix + arraysize(kUnityMatrix));
589  RCHECK(buffer->IgnoreBytes(8) && // reserved
590  buffer->ReadWriteInt16(&layer) &&
591  buffer->ReadWriteInt16(&alternate_group) &&
592  buffer->ReadWriteInt16(&volume) &&
593  buffer->IgnoreBytes(2) && // reserved
594  buffer->ReadWriteVector(&matrix, matrix.size()) &&
595  buffer->ReadWriteUInt32(&width) && buffer->ReadWriteUInt32(&height));
596  return true;
597 }
598 
599 size_t TrackHeader::ComputeSizeInternal() {
600  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
601  return HeaderSize() + sizeof(track_id) +
602  sizeof(uint32_t) * (1 + version) * 3 + sizeof(layer) +
603  sizeof(alternate_group) + sizeof(volume) + sizeof(width) +
604  sizeof(height) + sizeof(kUnityMatrix) + 14; // 14 bytes reserved.
605 }
606 
607 SampleDescription::SampleDescription() = default;
608 SampleDescription::~SampleDescription() = default;
609 
611  return FOURCC_stsd;
612 }
613 
614 bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
615  uint32_t count = 0;
616  switch (type) {
617  case kVideo:
618  count = static_cast<uint32_t>(video_entries.size());
619  break;
620  case kAudio:
621  count = static_cast<uint32_t>(audio_entries.size());
622  break;
623  case kText:
624  count = static_cast<uint32_t>(text_entries.size());
625  break;
626  default:
627  NOTIMPLEMENTED() << "SampleDecryption type " << type
628  << " is not handled. Skipping.";
629  }
630  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
631 
632  if (buffer->Reading()) {
633  BoxReader* reader = buffer->reader();
634  DCHECK(reader);
635  video_entries.clear();
636  audio_entries.clear();
637  // Note: this value is preset before scanning begins. See comments in the
638  // Parse(Media*) function.
639  if (type == kVideo) {
640  RCHECK(reader->ReadAllChildren(&video_entries));
641  RCHECK(video_entries.size() == count);
642  } else if (type == kAudio) {
643  RCHECK(reader->ReadAllChildren(&audio_entries));
644  RCHECK(audio_entries.size() == count);
645  } else if (type == kText) {
646  RCHECK(reader->ReadAllChildren(&text_entries));
647  RCHECK(text_entries.size() == count);
648  }
649  } else {
650  DCHECK_LT(0u, count);
651  if (type == kVideo) {
652  for (uint32_t i = 0; i < count; ++i)
653  RCHECK(buffer->ReadWriteChild(&video_entries[i]));
654  } else if (type == kAudio) {
655  for (uint32_t i = 0; i < count; ++i)
656  RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
657  } else if (type == kText) {
658  for (uint32_t i = 0; i < count; ++i)
659  RCHECK(buffer->ReadWriteChild(&text_entries[i]));
660  } else {
661  NOTIMPLEMENTED();
662  }
663  }
664  return true;
665 }
666 
667 size_t SampleDescription::ComputeSizeInternal() {
668  size_t box_size = HeaderSize() + sizeof(uint32_t);
669  if (type == kVideo) {
670  for (uint32_t i = 0; i < video_entries.size(); ++i)
671  box_size += video_entries[i].ComputeSize();
672  } else if (type == kAudio) {
673  for (uint32_t i = 0; i < audio_entries.size(); ++i)
674  box_size += audio_entries[i].ComputeSize();
675  } else if (type == kText) {
676  for (uint32_t i = 0; i < text_entries.size(); ++i)
677  box_size += text_entries[i].ComputeSize();
678  }
679  return box_size;
680 }
681 
682 DecodingTimeToSample::DecodingTimeToSample() = default;
683 DecodingTimeToSample::~DecodingTimeToSample() = default;
684 
686  return FOURCC_stts;
687 }
688 
689 bool DecodingTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
690  uint32_t count = static_cast<uint32_t>(decoding_time.size());
691  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
692 
693  decoding_time.resize(count);
694  for (uint32_t i = 0; i < count; ++i) {
695  RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
696  buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
697  }
698  return true;
699 }
700 
701 size_t DecodingTimeToSample::ComputeSizeInternal() {
702  return HeaderSize() + sizeof(uint32_t) +
703  sizeof(DecodingTime) * decoding_time.size();
704 }
705 
706 CompositionTimeToSample::CompositionTimeToSample() = default;
707 CompositionTimeToSample::~CompositionTimeToSample() = default;
708 
710  return FOURCC_ctts;
711 }
712 
713 bool CompositionTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
714  uint32_t count = static_cast<uint32_t>(composition_offset.size());
715  if (!buffer->Reading()) {
716  // Determine whether version 0 or version 1 should be used.
717  // Use version 0 if possible, use version 1 if there is a negative
718  // sample_offset value.
719  version = 0;
720  for (uint32_t i = 0; i < count; ++i) {
721  if (composition_offset[i].sample_offset < 0) {
722  version = 1;
723  break;
724  }
725  }
726  }
727 
728  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
729 
730  composition_offset.resize(count);
731  for (uint32_t i = 0; i < count; ++i) {
732  RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
733 
734  if (version == 0) {
735  uint32_t sample_offset = composition_offset[i].sample_offset;
736  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
737  composition_offset[i].sample_offset = sample_offset;
738  } else {
739  int32_t sample_offset = composition_offset[i].sample_offset;
740  RCHECK(buffer->ReadWriteInt32(&sample_offset));
741  composition_offset[i].sample_offset = sample_offset;
742  }
743  }
744  return true;
745 }
746 
747 size_t CompositionTimeToSample::ComputeSizeInternal() {
748  // This box is optional. Skip it if it is empty.
749  if (composition_offset.empty())
750  return 0;
751  // Structure CompositionOffset contains |sample_offset| (uint32_t) and
752  // |sample_offset| (int64_t). The actual size of |sample_offset| is
753  // 4 bytes (uint32_t for version 0 and int32_t for version 1).
754  const size_t kCompositionOffsetSize = sizeof(uint32_t) * 2;
755  return HeaderSize() + sizeof(uint32_t) +
756  kCompositionOffsetSize * composition_offset.size();
757 }
758 
759 SampleToChunk::SampleToChunk() = default;
760 SampleToChunk::~SampleToChunk() = default;
761 
762 FourCC SampleToChunk::BoxType() const {
763  return FOURCC_stsc;
764 }
765 
766 bool SampleToChunk::ReadWriteInternal(BoxBuffer* buffer) {
767  uint32_t count = static_cast<uint32_t>(chunk_info.size());
768  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
769 
770  chunk_info.resize(count);
771  for (uint32_t i = 0; i < count; ++i) {
772  RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
773  buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
774  buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
775  // first_chunk values are always increasing.
776  RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
777  : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
778  }
779  return true;
780 }
781 
782 size_t SampleToChunk::ComputeSizeInternal() {
783  return HeaderSize() + sizeof(uint32_t) +
784  sizeof(ChunkInfo) * chunk_info.size();
785 }
786 
787 SampleSize::SampleSize() = default;
788 SampleSize::~SampleSize() = default;
789 
790 FourCC SampleSize::BoxType() const {
791  return FOURCC_stsz;
792 }
793 
794 bool SampleSize::ReadWriteInternal(BoxBuffer* buffer) {
795  RCHECK(ReadWriteHeaderInternal(buffer) &&
796  buffer->ReadWriteUInt32(&sample_size) &&
797  buffer->ReadWriteUInt32(&sample_count));
798 
799  if (sample_size == 0) {
800  if (buffer->Reading())
801  sizes.resize(sample_count);
802  else
803  DCHECK(sample_count == sizes.size());
804  for (uint32_t i = 0; i < sample_count; ++i)
805  RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
806  }
807  return true;
808 }
809 
810 size_t SampleSize::ComputeSizeInternal() {
811  return HeaderSize() + sizeof(sample_size) + sizeof(sample_count) +
812  (sample_size == 0 ? sizeof(uint32_t) * sizes.size() : 0);
813 }
814 
815 CompactSampleSize::CompactSampleSize() = default;
816 CompactSampleSize::~CompactSampleSize() = default;
817 
819  return FOURCC_stz2;
820 }
821 
822 bool CompactSampleSize::ReadWriteInternal(BoxBuffer* buffer) {
823  uint32_t sample_count = static_cast<uint32_t>(sizes.size());
824  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->IgnoreBytes(3) &&
825  buffer->ReadWriteUInt8(&field_size) &&
826  buffer->ReadWriteUInt32(&sample_count));
827 
828  // Reserve one more entry if field size is 4 bits.
829  sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
830  switch (field_size) {
831  case 4:
832  for (uint32_t i = 0; i < sample_count; i += 2) {
833  if (buffer->Reading()) {
834  uint8_t size = 0;
835  RCHECK(buffer->ReadWriteUInt8(&size));
836  sizes[i] = size >> 4;
837  sizes[i + 1] = size & 0x0F;
838  } else {
839  DCHECK_LT(sizes[i], 16u);
840  DCHECK_LT(sizes[i + 1], 16u);
841  uint8_t size = (sizes[i] << 4) | sizes[i + 1];
842  RCHECK(buffer->ReadWriteUInt8(&size));
843  }
844  }
845  break;
846  case 8:
847  for (uint32_t i = 0; i < sample_count; ++i) {
848  uint8_t size = sizes[i];
849  RCHECK(buffer->ReadWriteUInt8(&size));
850  sizes[i] = size;
851  }
852  break;
853  case 16:
854  for (uint32_t i = 0; i < sample_count; ++i) {
855  uint16_t size = sizes[i];
856  RCHECK(buffer->ReadWriteUInt16(&size));
857  sizes[i] = size;
858  }
859  break;
860  default:
861  RCHECK(false);
862  }
863  sizes.resize(sample_count);
864  return true;
865 }
866 
867 size_t CompactSampleSize::ComputeSizeInternal() {
868  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) +
869  (field_size * sizes.size() + 7) / 8;
870 }
871 
872 ChunkOffset::ChunkOffset() = default;
873 ChunkOffset::~ChunkOffset() = default;
874 
875 FourCC ChunkOffset::BoxType() const {
876  return FOURCC_stco;
877 }
878 
879 bool ChunkOffset::ReadWriteInternal(BoxBuffer* buffer) {
880  uint32_t count = static_cast<uint32_t>(offsets.size());
881  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
882 
883  offsets.resize(count);
884  for (uint32_t i = 0; i < count; ++i)
885  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], sizeof(uint32_t)));
886  return true;
887 }
888 
889 size_t ChunkOffset::ComputeSizeInternal() {
890  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) * offsets.size();
891 }
892 
893 ChunkLargeOffset::ChunkLargeOffset() = default;
894 ChunkLargeOffset::~ChunkLargeOffset() = default;
895 
897  return FOURCC_co64;
898 }
899 
900 bool ChunkLargeOffset::ReadWriteInternal(BoxBuffer* buffer) {
901  uint32_t count = static_cast<uint32_t>(offsets.size());
902 
903  if (!buffer->Reading()) {
904  // Switch to ChunkOffset box if it is able to fit in 32 bits offset.
905  if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
906  ChunkOffset stco;
907  stco.offsets.swap(offsets);
908  DCHECK(buffer->writer());
909  stco.Write(buffer->writer());
910  stco.offsets.swap(offsets);
911  return true;
912  }
913  }
914 
915  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
916 
917  offsets.resize(count);
918  for (uint32_t i = 0; i < count; ++i)
919  RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
920  return true;
921 }
922 
923 size_t ChunkLargeOffset::ComputeSizeInternal() {
924  uint32_t count = static_cast<uint32_t>(offsets.size());
925  int use_large_offset =
926  (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
927  return HeaderSize() + sizeof(count) +
928  sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
929 }
930 
931 SyncSample::SyncSample() = default;
932 SyncSample::~SyncSample() = default;
933 
934 FourCC SyncSample::BoxType() const {
935  return FOURCC_stss;
936 }
937 
938 bool SyncSample::ReadWriteInternal(BoxBuffer* buffer) {
939  uint32_t count = static_cast<uint32_t>(sample_number.size());
940  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
941 
942  sample_number.resize(count);
943  for (uint32_t i = 0; i < count; ++i)
944  RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
945  return true;
946 }
947 
948 size_t SyncSample::ComputeSizeInternal() {
949  // Sync sample box is optional. Skip it if it is empty.
950  if (sample_number.empty())
951  return 0;
952  return HeaderSize() + sizeof(uint32_t) +
953  sizeof(uint32_t) * sample_number.size();
954 }
955 
956 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
957  if (!buffer->Reading()) {
958  if (key_id.size() != kCencKeyIdSize) {
959  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
960  << " bytes; got " << key_id.size()
961  << ". Resized accordingly.";
962  key_id.resize(kCencKeyIdSize);
963  }
964  RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
965  }
966 
967  RCHECK(buffer->IgnoreBytes(1)); // reserved.
968 
969  uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
970  RCHECK(buffer->ReadWriteUInt8(&pattern));
971  crypt_byte_block = pattern >> 4;
972  skip_byte_block = pattern & 0x0F;
973 
974  RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
975  buffer->ReadWriteUInt8(&per_sample_iv_size) &&
976  buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
977 
978  if (is_protected == 1) {
979  if (per_sample_iv_size == 0) { // For constant iv.
980  uint8_t constant_iv_size = static_cast<uint8_t>(constant_iv.size());
981  RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
982  RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
983  RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
984  } else {
985  RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
986  DCHECK(constant_iv.empty());
987  }
988  } else {
989  // Expect |is_protected| to be 0, i.e. not protected. Other values of
990  // |is_protected| is not supported.
991  RCHECK(is_protected == 0);
992  RCHECK(per_sample_iv_size == 0);
993  }
994  return true;
995 }
996 
997 uint32_t CencSampleEncryptionInfoEntry::ComputeSize() const {
998  return static_cast<uint32_t>(
999  sizeof(uint32_t) + kCencKeyIdSize +
1000  (constant_iv.empty() ? 0 : (sizeof(uint8_t) + constant_iv.size())));
1001 }
1002 
1003 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
1004  RCHECK(buffer->ReadWriteInt16(&roll_distance));
1005  return true;
1006 }
1007 
1008 uint32_t AudioRollRecoveryEntry::ComputeSize() const {
1009  return sizeof(roll_distance);
1010 }
1011 
1012 SampleGroupDescription::SampleGroupDescription() = default;
1013 SampleGroupDescription::~SampleGroupDescription() = default;
1014 
1016  return FOURCC_sgpd;
1017 }
1018 
1019 bool SampleGroupDescription::ReadWriteInternal(BoxBuffer* buffer) {
1020  RCHECK(ReadWriteHeaderInternal(buffer) &&
1021  buffer->ReadWriteUInt32(&grouping_type));
1022 
1023  switch (grouping_type) {
1024  case FOURCC_seig:
1025  return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
1026  case FOURCC_roll:
1027  return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
1028  default:
1029  DCHECK(buffer->Reading());
1030  DLOG(WARNING) << "Ignore unsupported sample group: "
1031  << FourCCToString(static_cast<FourCC>(grouping_type));
1032  return true;
1033  }
1034 }
1035 
1036 template <typename T>
1037 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
1038  std::vector<T>* entries) {
1039  uint32_t default_length = 0;
1040  if (!buffer->Reading()) {
1041  DCHECK(!entries->empty());
1042  default_length = (*entries)[0].ComputeSize();
1043  DCHECK_NE(default_length, 0u);
1044  }
1045  if (version == 1)
1046  RCHECK(buffer->ReadWriteUInt32(&default_length));
1047  if (version >= 2) {
1048  NOTIMPLEMENTED() << "Unsupported SampleGroupDescriptionBox 'sgpd' version "
1049  << static_cast<int>(version);
1050  return false;
1051  }
1052 
1053  uint32_t count = static_cast<uint32_t>(entries->size());
1054  RCHECK(buffer->ReadWriteUInt32(&count));
1055  RCHECK(count != 0);
1056  entries->resize(count);
1057 
1058  for (T& entry : *entries) {
1059  if (version == 1) {
1060  uint32_t description_length = default_length;
1061  if (buffer->Reading() && default_length == 0)
1062  RCHECK(buffer->ReadWriteUInt32(&description_length));
1063  RCHECK(entry.ReadWrite(buffer));
1064  RCHECK(entry.ComputeSize() == description_length);
1065  } else {
1066  RCHECK(entry.ReadWrite(buffer));
1067  }
1068  }
1069  return true;
1070 }
1071 
1072 size_t SampleGroupDescription::ComputeSizeInternal() {
1073  // Version 0 is obsoleted, so always generate version 1 box.
1074  version = 1;
1075  size_t entries_size = 0;
1076  switch (grouping_type) {
1077  case FOURCC_seig:
1078  for (const auto& entry : cenc_sample_encryption_info_entries)
1079  entries_size += entry.ComputeSize();
1080  break;
1081  case FOURCC_roll:
1082  for (const auto& entry : audio_roll_recovery_entries)
1083  entries_size += entry.ComputeSize();
1084  break;
1085  }
1086  // This box is optional. Skip it if it is not used.
1087  if (entries_size == 0)
1088  return 0;
1089  return HeaderSize() + sizeof(grouping_type) +
1090  (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) +
1091  entries_size;
1092 }
1093 
1094 SampleToGroup::SampleToGroup() = default;
1095 SampleToGroup::~SampleToGroup() = default;
1096 
1097 FourCC SampleToGroup::BoxType() const {
1098  return FOURCC_sbgp;
1099 }
1100 
1101 bool SampleToGroup::ReadWriteInternal(BoxBuffer* buffer) {
1102  RCHECK(ReadWriteHeaderInternal(buffer) &&
1103  buffer->ReadWriteUInt32(&grouping_type));
1104  if (version == 1)
1105  RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
1106 
1107  if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
1108  DCHECK(buffer->Reading());
1109  DLOG(WARNING) << "Ignore unsupported sample group: "
1110  << FourCCToString(static_cast<FourCC>(grouping_type));
1111  return true;
1112  }
1113 
1114  uint32_t count = static_cast<uint32_t>(entries.size());
1115  RCHECK(buffer->ReadWriteUInt32(&count));
1116  entries.resize(count);
1117  for (uint32_t i = 0; i < count; ++i) {
1118  RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
1119  buffer->ReadWriteUInt32(&entries[i].group_description_index));
1120  }
1121  return true;
1122 }
1123 
1124 size_t SampleToGroup::ComputeSizeInternal() {
1125  // This box is optional. Skip it if it is not used.
1126  if (entries.empty())
1127  return 0;
1128  return HeaderSize() + sizeof(grouping_type) +
1129  (version == 1 ? sizeof(grouping_type_parameter) : 0) +
1130  sizeof(uint32_t) + entries.size() * sizeof(entries[0]);
1131 }
1132 
1133 SampleTable::SampleTable() = default;
1134 SampleTable::~SampleTable() = default;
1135 
1136 FourCC SampleTable::BoxType() const {
1137  return FOURCC_stbl;
1138 }
1139 
1140 bool SampleTable::ReadWriteInternal(BoxBuffer* buffer) {
1141  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
1142  buffer->ReadWriteChild(&description) &&
1143  buffer->ReadWriteChild(&decoding_time_to_sample) &&
1144  buffer->TryReadWriteChild(&composition_time_to_sample) &&
1145  buffer->ReadWriteChild(&sample_to_chunk));
1146 
1147  if (buffer->Reading()) {
1148  BoxReader* reader = buffer->reader();
1149  DCHECK(reader);
1150 
1151  // Either SampleSize or CompactSampleSize must present.
1152  if (reader->ChildExist(&sample_size)) {
1153  RCHECK(reader->ReadChild(&sample_size));
1154  } else {
1155  CompactSampleSize compact_sample_size;
1156  RCHECK(reader->ReadChild(&compact_sample_size));
1157  sample_size.sample_size = 0;
1158  sample_size.sample_count =
1159  static_cast<uint32_t>(compact_sample_size.sizes.size());
1160  sample_size.sizes.swap(compact_sample_size.sizes);
1161  }
1162 
1163  // Either ChunkOffset or ChunkLargeOffset must present.
1164  if (reader->ChildExist(&chunk_large_offset)) {
1165  RCHECK(reader->ReadChild(&chunk_large_offset));
1166  } else {
1167  ChunkOffset chunk_offset;
1168  RCHECK(reader->ReadChild(&chunk_offset));
1169  chunk_large_offset.offsets.swap(chunk_offset.offsets);
1170  }
1171  } else {
1172  RCHECK(buffer->ReadWriteChild(&sample_size) &&
1173  buffer->ReadWriteChild(&chunk_large_offset));
1174  }
1175  RCHECK(buffer->TryReadWriteChild(&sync_sample));
1176  if (buffer->Reading()) {
1177  RCHECK(buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
1178  buffer->reader()->TryReadChildren(&sample_to_groups));
1179  } else {
1180  for (auto& sample_group_description : sample_group_descriptions)
1181  RCHECK(buffer->ReadWriteChild(&sample_group_description));
1182  for (auto& sample_to_group : sample_to_groups)
1183  RCHECK(buffer->ReadWriteChild(&sample_to_group));
1184  }
1185  return true;
1186 }
1187 
1188 size_t SampleTable::ComputeSizeInternal() {
1189  size_t box_size = HeaderSize() + description.ComputeSize() +
1190  decoding_time_to_sample.ComputeSize() +
1191  composition_time_to_sample.ComputeSize() +
1192  sample_to_chunk.ComputeSize() + sample_size.ComputeSize() +
1193  chunk_large_offset.ComputeSize() +
1194  sync_sample.ComputeSize();
1195  for (auto& sample_group_description : sample_group_descriptions)
1196  box_size += sample_group_description.ComputeSize();
1197  for (auto& sample_to_group : sample_to_groups)
1198  box_size += sample_to_group.ComputeSize();
1199  return box_size;
1200 }
1201 
1202 EditList::EditList() = default;
1203 EditList::~EditList() = default;
1204 
1205 FourCC EditList::BoxType() const {
1206  return FOURCC_elst;
1207 }
1208 
1209 bool EditList::ReadWriteInternal(BoxBuffer* buffer) {
1210  uint32_t count = static_cast<uint32_t>(edits.size());
1211  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
1212  edits.resize(count);
1213 
1214  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
1215  for (uint32_t i = 0; i < count; ++i) {
1216  RCHECK(
1217  buffer->ReadWriteUInt64NBytes(&edits[i].segment_duration, num_bytes) &&
1218  buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
1219  buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
1220  buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
1221  }
1222  return true;
1223 }
1224 
1225 size_t EditList::ComputeSizeInternal() {
1226  // EditList box is optional. Skip it if it is empty.
1227  if (edits.empty())
1228  return 0;
1229 
1230  version = 0;
1231  for (uint32_t i = 0; i < edits.size(); ++i) {
1232  if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
1233  version = 1;
1234  break;
1235  }
1236  }
1237  return HeaderSize() + sizeof(uint32_t) +
1238  (sizeof(uint32_t) * (1 + version) * 2 + sizeof(int16_t) * 2) *
1239  edits.size();
1240 }
1241 
1242 Edit::Edit() = default;
1243 Edit::~Edit() = default;
1244 
1245 FourCC Edit::BoxType() const {
1246  return FOURCC_edts;
1247 }
1248 
1249 bool Edit::ReadWriteInternal(BoxBuffer* buffer) {
1250  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
1251  buffer->ReadWriteChild(&list);
1252 }
1253 
1254 size_t Edit::ComputeSizeInternal() {
1255  // Edit box is optional. Skip it if it is empty.
1256  if (list.edits.empty())
1257  return 0;
1258  return HeaderSize() + list.ComputeSize();
1259 }
1260 
1261 HandlerReference::HandlerReference() = default;
1262 HandlerReference::~HandlerReference() = default;
1263 
1265  return FOURCC_hdlr;
1266 }
1267 
1268 bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
1269  std::vector<uint8_t> handler_name;
1270  if (!buffer->Reading()) {
1271  switch (handler_type) {
1272  case FOURCC_vide:
1273  handler_name.assign(kVideoHandlerName,
1274  kVideoHandlerName + arraysize(kVideoHandlerName));
1275  break;
1276  case FOURCC_soun:
1277  handler_name.assign(kAudioHandlerName,
1278  kAudioHandlerName + arraysize(kAudioHandlerName));
1279  break;
1280  case FOURCC_text:
1281  handler_name.assign(kTextHandlerName,
1282  kTextHandlerName + arraysize(kTextHandlerName));
1283  break;
1284  case FOURCC_ID32:
1285  break;
1286  default:
1287  NOTIMPLEMENTED();
1288  return false;
1289  }
1290  }
1291  RCHECK(ReadWriteHeaderInternal(buffer) &&
1292  buffer->IgnoreBytes(4) && // predefined.
1293  buffer->ReadWriteFourCC(&handler_type));
1294  if (!buffer->Reading()) {
1295  RCHECK(buffer->IgnoreBytes(12) && // reserved.
1296  buffer->ReadWriteVector(&handler_name, handler_name.size()));
1297  }
1298  return true;
1299 }
1300 
1301 size_t HandlerReference::ComputeSizeInternal() {
1302  size_t box_size = HeaderSize() + kFourCCSize + 16; // 16 bytes Reserved
1303  switch (handler_type) {
1304  case FOURCC_vide:
1305  box_size += sizeof(kVideoHandlerName);
1306  break;
1307  case FOURCC_soun:
1308  box_size += sizeof(kAudioHandlerName);
1309  break;
1310  case FOURCC_text:
1311  box_size += sizeof(kTextHandlerName);
1312  break;
1313  case FOURCC_ID32:
1314  break;
1315  default:
1316  NOTIMPLEMENTED();
1317  }
1318  return box_size;
1319 }
1320 
1321 bool Language::ReadWrite(BoxBuffer* buffer) {
1322  if (buffer->Reading()) {
1323  // Read language codes into temp first then use BitReader to read the
1324  // values. ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
1325  std::vector<uint8_t> temp;
1326  RCHECK(buffer->ReadWriteVector(&temp, 2));
1327 
1328  BitReader bit_reader(&temp[0], 2);
1329  bit_reader.SkipBits(1);
1330  char language[3];
1331  for (int i = 0; i < 3; ++i) {
1332  CHECK(bit_reader.ReadBits(5, &language[i]));
1333  language[i] += 0x60;
1334  }
1335  code.assign(language, 3);
1336  } else {
1337  // Set up default language if it is not set.
1338  const char kUndefinedLanguage[] = "und";
1339  if (code.empty())
1340  code = kUndefinedLanguage;
1341  DCHECK_EQ(code.size(), 3u);
1342 
1343  // Lang format: bit(1) pad, unsigned int(5)[3] language.
1344  uint16_t lang = 0;
1345  for (int i = 0; i < 3; ++i)
1346  lang |= (code[i] - 0x60) << ((2 - i) * 5);
1347  RCHECK(buffer->ReadWriteUInt16(&lang));
1348  }
1349  return true;
1350 }
1351 
1352 uint32_t Language::ComputeSize() const {
1353  // ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
1354  return 2;
1355 }
1356 
1357 ID3v2::ID3v2() = default;
1358 ID3v2::~ID3v2() = default;
1359 
1360 FourCC ID3v2::BoxType() const {
1361  return FOURCC_ID32;
1362 }
1363 
1364 bool ID3v2::ReadWriteInternal(BoxBuffer* buffer) {
1365  RCHECK(ReadWriteHeaderInternal(buffer) && language.ReadWrite(buffer) &&
1366  buffer->ReadWriteVector(&id3v2_data, buffer->Reading()
1367  ? buffer->BytesLeft()
1368  : id3v2_data.size()));
1369  return true;
1370 }
1371 
1372 size_t ID3v2::ComputeSizeInternal() {
1373  // Skip ID3v2 box generation if there is no id3 data.
1374  return id3v2_data.size() == 0
1375  ? 0
1376  : HeaderSize() + language.ComputeSize() + id3v2_data.size();
1377 }
1378 
1379 Metadata::Metadata() = default;
1380 Metadata::~Metadata() = default;
1381 
1382 FourCC Metadata::BoxType() const {
1383  return FOURCC_meta;
1384 }
1385 
1386 bool Metadata::ReadWriteInternal(BoxBuffer* buffer) {
1387  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
1388  buffer->ReadWriteChild(&handler) && buffer->TryReadWriteChild(&id3v2));
1389  return true;
1390 }
1391 
1392 size_t Metadata::ComputeSizeInternal() {
1393  size_t id3v2_size = id3v2.ComputeSize();
1394  // Skip metadata box generation if there is no metadata box.
1395  return id3v2_size == 0 ? 0
1396  : HeaderSize() + handler.ComputeSize() + id3v2_size;
1397 }
1398 
1399 CodecConfiguration::CodecConfiguration() = default;
1400 CodecConfiguration::~CodecConfiguration() = default;
1401 
1403  // CodecConfiguration box should be parsed according to format recovered in
1404  // VideoSampleEntry. |box_type| is determined dynamically there.
1405  return box_type;
1406 }
1407 
1408 bool CodecConfiguration::ReadWriteInternal(BoxBuffer* buffer) {
1409  DCHECK_NE(box_type, FOURCC_NULL);
1410  RCHECK(ReadWriteHeaderInternal(buffer));
1411 
1412  // VPCodecConfiguration box inherits from FullBox instead of Box. The extra 4
1413  // bytes are handled here.
1414  if (box_type == FOURCC_vpcC) {
1415  // Only version 1 box is supported.
1416  uint8_t vpcc_version = 1;
1417  uint32_t version_flags = vpcc_version << 24;
1418  RCHECK(buffer->ReadWriteUInt32(&version_flags));
1419  vpcc_version = version_flags >> 24;
1420  RCHECK(vpcc_version == 1);
1421  }
1422 
1423  if (buffer->Reading()) {
1424  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
1425  } else {
1426  RCHECK(buffer->ReadWriteVector(&data, data.size()));
1427  }
1428  return true;
1429 }
1430 
1431 size_t CodecConfiguration::ComputeSizeInternal() {
1432  if (data.empty())
1433  return 0;
1434  DCHECK_NE(box_type, FOURCC_NULL);
1435  return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
1436 }
1437 
1438 PixelAspectRatio::PixelAspectRatio() = default;
1439 PixelAspectRatio::~PixelAspectRatio() = default;
1440 
1442  return FOURCC_pasp;
1443 }
1444 
1445 bool PixelAspectRatio::ReadWriteInternal(BoxBuffer* buffer) {
1446  RCHECK(ReadWriteHeaderInternal(buffer) &&
1447  buffer->ReadWriteUInt32(&h_spacing) &&
1448  buffer->ReadWriteUInt32(&v_spacing));
1449  return true;
1450 }
1451 
1452 size_t PixelAspectRatio::ComputeSizeInternal() {
1453  // This box is optional. Skip it if it is not initialized.
1454  if (h_spacing == 0 && v_spacing == 0)
1455  return 0;
1456  // Both values must be positive.
1457  DCHECK(h_spacing != 0 && v_spacing != 0);
1458  return HeaderSize() + sizeof(h_spacing) + sizeof(v_spacing);
1459 }
1460 
1461 VideoSampleEntry::VideoSampleEntry() = default;
1462 VideoSampleEntry::~VideoSampleEntry() = default;
1463 
1465  if (format == FOURCC_NULL) {
1466  LOG(ERROR) << "VideoSampleEntry should be parsed according to the "
1467  << "handler type recovered in its Media ancestor.";
1468  }
1469  return format;
1470 }
1471 
1472 bool VideoSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
1473  std::vector<uint8_t> compressor_name;
1474  if (buffer->Reading()) {
1475  DCHECK(buffer->reader());
1476  format = buffer->reader()->type();
1477  } else {
1478  RCHECK(ReadWriteHeaderInternal(buffer));
1479 
1480  const FourCC actual_format = GetActualFormat();
1481  switch (actual_format) {
1482  case FOURCC_av01:
1483  compressor_name.assign(std::begin(kAv1CompressorName),
1484  std::end(kAv1CompressorName));
1485  break;
1486  case FOURCC_avc1:
1487  case FOURCC_avc3:
1488  compressor_name.assign(std::begin(kAvcCompressorName),
1489  std::end(kAvcCompressorName));
1490  break;
1491  case FOURCC_hev1:
1492  case FOURCC_hvc1:
1493  compressor_name.assign(std::begin(kHevcCompressorName),
1494  std::end(kHevcCompressorName));
1495  break;
1496  case FOURCC_vp08:
1497  case FOURCC_vp09:
1498  compressor_name.assign(std::begin(kVpcCompressorName),
1499  std::end(kVpcCompressorName));
1500  break;
1501  default:
1502  LOG(ERROR) << FourCCToString(actual_format) << " is not supported.";
1503  return false;
1504  }
1505  compressor_name.resize(kCompressorNameSize);
1506  }
1507 
1508  uint32_t video_resolution = kVideoResolution;
1509  uint16_t video_frame_count = kVideoFrameCount;
1510  uint16_t video_depth = kVideoDepth;
1511  int16_t predefined = -1;
1512  RCHECK(buffer->IgnoreBytes(6) && // reserved.
1513  buffer->ReadWriteUInt16(&data_reference_index) &&
1514  buffer->IgnoreBytes(16) && // predefined 0.
1515  buffer->ReadWriteUInt16(&width) && buffer->ReadWriteUInt16(&height) &&
1516  buffer->ReadWriteUInt32(&video_resolution) &&
1517  buffer->ReadWriteUInt32(&video_resolution) &&
1518  buffer->IgnoreBytes(4) && // reserved.
1519  buffer->ReadWriteUInt16(&video_frame_count) &&
1520  buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
1521  buffer->ReadWriteUInt16(&video_depth) &&
1522  buffer->ReadWriteInt16(&predefined));
1523 
1524  RCHECK(buffer->PrepareChildren());
1525 
1526  // This has to happen before reading codec configuration box as the actual
1527  // format is read from sinf.format.format, which is needed to parse the codec
1528  // configuration box.
1529  if (format == FOURCC_encv && buffer->Reading()) {
1530  // Continue scanning until a supported protection scheme is found, or
1531  // until we run out of protection schemes.
1532  while (!IsProtectionSchemeSupported(sinf.type.type))
1533  RCHECK(buffer->ReadWriteChild(&sinf));
1534  }
1535 
1536  const FourCC actual_format = GetActualFormat();
1537  if (buffer->Reading()) {
1538  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1539  } else {
1540  DCHECK_EQ(codec_configuration.box_type,
1541  GetCodecConfigurationBoxType(actual_format));
1542  }
1543  if (codec_configuration.box_type == FOURCC_NULL)
1544  return false;
1545 
1546  RCHECK(buffer->ReadWriteChild(&codec_configuration));
1547  RCHECK(buffer->TryReadWriteChild(&pixel_aspect));
1548 
1549  // Somehow Edge does not support having sinf box before codec_configuration,
1550  // box, so just do it in the end of VideoSampleEntry. See
1551  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
1552  if (format == FOURCC_encv && !buffer->Reading()) {
1553  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1554  RCHECK(buffer->ReadWriteChild(&sinf));
1555  }
1556  return true;
1557 }
1558 
1559 size_t VideoSampleEntry::ComputeSizeInternal() {
1560  const FourCC actual_format = GetActualFormat();
1561  if (actual_format == FOURCC_NULL)
1562  return 0;
1563  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
1564  DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
1565  return HeaderSize() + sizeof(data_reference_index) + sizeof(width) +
1566  sizeof(height) + sizeof(kVideoResolution) * 2 +
1567  sizeof(kVideoFrameCount) + sizeof(kVideoDepth) +
1568  pixel_aspect.ComputeSize() + sinf.ComputeSize() +
1569  codec_configuration.ComputeSize() + kCompressorNameSize + 6 + 4 + 16 +
1570  2; // 6 + 4 bytes reserved, 16 + 2 bytes predefined.
1571 }
1572 
1573 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format) const {
1574  switch (format) {
1575  case FOURCC_av01:
1576  return FOURCC_av1C;
1577  case FOURCC_avc1:
1578  case FOURCC_avc3:
1579  return FOURCC_avcC;
1580  case FOURCC_hev1:
1581  case FOURCC_hvc1:
1582  return FOURCC_hvcC;
1583  case FOURCC_vp08:
1584  case FOURCC_vp09:
1585  return FOURCC_vpcC;
1586  default:
1587  LOG(ERROR) << FourCCToString(format) << " is not supported.";
1588  return FOURCC_NULL;
1589  }
1590 }
1591 
1592 ElementaryStreamDescriptor::ElementaryStreamDescriptor() = default;
1593 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() = default;
1594 
1596  return FOURCC_esds;
1597 }
1598 
1599 bool ElementaryStreamDescriptor::ReadWriteInternal(BoxBuffer* buffer) {
1600  RCHECK(ReadWriteHeaderInternal(buffer));
1601  if (buffer->Reading()) {
1602  std::vector<uint8_t> data;
1603  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
1604  RCHECK(es_descriptor.Parse(data));
1605  if (es_descriptor.IsAAC()) {
1606  RCHECK(aac_audio_specific_config.Parse(
1607  es_descriptor.decoder_specific_info()));
1608  }
1609  } else {
1610  DCHECK(buffer->writer());
1611  es_descriptor.Write(buffer->writer());
1612  }
1613  return true;
1614 }
1615 
1616 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
1617  // This box is optional. Skip it if not initialized.
1618  if (es_descriptor.object_type() == ObjectType::kForbidden)
1619  return 0;
1620  return HeaderSize() + es_descriptor.ComputeSize();
1621 }
1622 
1623 DTSSpecific::DTSSpecific() = default;
1624 DTSSpecific::~DTSSpecific() = default;
1625 ;
1626 
1627 FourCC DTSSpecific::BoxType() const {
1628  return FOURCC_ddts;
1629 }
1630 
1631 bool DTSSpecific::ReadWriteInternal(BoxBuffer* buffer) {
1632  RCHECK(ReadWriteHeaderInternal(buffer) &&
1633  buffer->ReadWriteUInt32(&sampling_frequency) &&
1634  buffer->ReadWriteUInt32(&max_bitrate) &&
1635  buffer->ReadWriteUInt32(&avg_bitrate) &&
1636  buffer->ReadWriteUInt8(&pcm_sample_depth));
1637 
1638  if (buffer->Reading()) {
1639  RCHECK(buffer->ReadWriteVector(&extra_data, buffer->BytesLeft()));
1640  } else {
1641  if (extra_data.empty()) {
1642  extra_data.assign(kDdtsExtraData,
1643  kDdtsExtraData + sizeof(kDdtsExtraData));
1644  }
1645  RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
1646  }
1647  return true;
1648 }
1649 
1650 size_t DTSSpecific::ComputeSizeInternal() {
1651  // This box is optional. Skip it if not initialized.
1652  if (sampling_frequency == 0)
1653  return 0;
1654  return HeaderSize() + sizeof(sampling_frequency) + sizeof(max_bitrate) +
1655  sizeof(avg_bitrate) + sizeof(pcm_sample_depth) +
1656  sizeof(kDdtsExtraData);
1657 }
1658 
1659 AC3Specific::AC3Specific() = default;
1660 AC3Specific::~AC3Specific() = default;
1661 
1662 FourCC AC3Specific::BoxType() const {
1663  return FOURCC_dac3;
1664 }
1665 
1666 bool AC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
1667  RCHECK(ReadWriteHeaderInternal(buffer) &&
1668  buffer->ReadWriteVector(
1669  &data, buffer->Reading() ? buffer->BytesLeft() : data.size()));
1670  return true;
1671 }
1672 
1673 size_t AC3Specific::ComputeSizeInternal() {
1674  // This box is optional. Skip it if not initialized.
1675  if (data.empty())
1676  return 0;
1677  return HeaderSize() + data.size();
1678 }
1679 
1680 EC3Specific::EC3Specific() = default;
1681 EC3Specific::~EC3Specific() = default;
1682 
1683 FourCC EC3Specific::BoxType() const {
1684  return FOURCC_dec3;
1685 }
1686 
1687 bool EC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
1688  RCHECK(ReadWriteHeaderInternal(buffer));
1689  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
1690  RCHECK(buffer->ReadWriteVector(&data, size));
1691  return true;
1692 }
1693 
1694 size_t EC3Specific::ComputeSizeInternal() {
1695  // This box is optional. Skip it if not initialized.
1696  if (data.empty())
1697  return 0;
1698  return HeaderSize() + data.size();
1699 }
1700 
1701 OpusSpecific::OpusSpecific() = default;
1702 OpusSpecific::~OpusSpecific() = default;
1703 
1704 FourCC OpusSpecific::BoxType() const {
1705  return FOURCC_dOps;
1706 }
1707 
1708 bool OpusSpecific::ReadWriteInternal(BoxBuffer* buffer) {
1709  RCHECK(ReadWriteHeaderInternal(buffer));
1710  if (buffer->Reading()) {
1711  std::vector<uint8_t> data;
1712  const int kMinOpusSpecificBoxDataSize = 11;
1713  RCHECK(buffer->BytesLeft() >= kMinOpusSpecificBoxDataSize);
1714  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
1715  preskip = data[2] + (data[3] << 8);
1716 
1717  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
1718  BufferWriter writer;
1719  writer.AppendInt(FOURCC_Opus);
1720  writer.AppendInt(FOURCC_Head);
1721  // The version must always be 1.
1722  const uint8_t kOpusIdentificationHeaderVersion = 1;
1723  data[0] = kOpusIdentificationHeaderVersion;
1724  writer.AppendVector(data);
1725  writer.SwapBuffer(&opus_identification_header);
1726  } else {
1727  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
1728  // The first 8 bytes is "magic signature".
1729  const size_t kOpusMagicSignatureSize = 8u;
1730  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1731  // https://www.opus-codec.org/docs/opus_in_isobmff.html
1732  // The version field shall be set to 0.
1733  const uint8_t kOpusSpecificBoxVersion = 0;
1734  buffer->writer()->AppendInt(kOpusSpecificBoxVersion);
1735  buffer->writer()->AppendArray(
1736  &opus_identification_header[kOpusMagicSignatureSize + 1],
1737  opus_identification_header.size() - kOpusMagicSignatureSize - 1);
1738  }
1739  return true;
1740 }
1741 
1742 size_t OpusSpecific::ComputeSizeInternal() {
1743  // This box is optional. Skip it if not initialized.
1744  if (opus_identification_header.empty())
1745  return 0;
1746  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
1747  // The first 8 bytes is "magic signature".
1748  const size_t kOpusMagicSignatureSize = 8u;
1749  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
1750  return HeaderSize() + opus_identification_header.size() -
1751  kOpusMagicSignatureSize;
1752 }
1753 
1754 FlacSpecific::FlacSpecific() = default;
1755 FlacSpecific::~FlacSpecific() = default;
1756 
1757 FourCC FlacSpecific::BoxType() const {
1758  return FOURCC_dfLa;
1759 }
1760 
1761 bool FlacSpecific::ReadWriteInternal(BoxBuffer* buffer) {
1762  RCHECK(ReadWriteHeaderInternal(buffer));
1763  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
1764  RCHECK(buffer->ReadWriteVector(&data, size));
1765  return true;
1766 }
1767 
1768 size_t FlacSpecific::ComputeSizeInternal() {
1769  // This box is optional. Skip it if not initialized.
1770  if (data.empty())
1771  return 0;
1772  return HeaderSize() + data.size();
1773 }
1774 
1775 AudioSampleEntry::AudioSampleEntry() = default;
1776 AudioSampleEntry::~AudioSampleEntry() = default;
1777 
1779  if (format == FOURCC_NULL) {
1780  LOG(ERROR) << "AudioSampleEntry should be parsed according to the "
1781  << "handler type recovered in its Media ancestor.";
1782  }
1783  return format;
1784 }
1785 
1786 bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
1787  if (buffer->Reading()) {
1788  DCHECK(buffer->reader());
1789  format = buffer->reader()->type();
1790  } else {
1791  RCHECK(ReadWriteHeaderInternal(buffer));
1792  }
1793 
1794  // Convert from integer to 16.16 fixed point for writing.
1795  samplerate <<= 16;
1796  RCHECK(buffer->IgnoreBytes(6) && // reserved.
1797  buffer->ReadWriteUInt16(&data_reference_index) &&
1798  buffer->IgnoreBytes(8) && // reserved.
1799  buffer->ReadWriteUInt16(&channelcount) &&
1800  buffer->ReadWriteUInt16(&samplesize) &&
1801  buffer->IgnoreBytes(4) && // predefined.
1802  buffer->ReadWriteUInt32(&samplerate));
1803  // Convert from 16.16 fixed point to integer.
1804  samplerate >>= 16;
1805 
1806  RCHECK(buffer->PrepareChildren());
1807 
1808  RCHECK(buffer->TryReadWriteChild(&esds));
1809  RCHECK(buffer->TryReadWriteChild(&ddts));
1810  RCHECK(buffer->TryReadWriteChild(&dac3));
1811  RCHECK(buffer->TryReadWriteChild(&dec3));
1812  RCHECK(buffer->TryReadWriteChild(&dops));
1813  RCHECK(buffer->TryReadWriteChild(&dfla));
1814 
1815  // Somehow Edge does not support having sinf box before codec_configuration,
1816  // box, so just do it in the end of AudioSampleEntry. See
1817  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
1818  if (format == FOURCC_enca) {
1819  if (buffer->Reading()) {
1820  // Continue scanning until a supported protection scheme is found, or
1821  // until we run out of protection schemes.
1822  while (!IsProtectionSchemeSupported(sinf.type.type))
1823  RCHECK(buffer->ReadWriteChild(&sinf));
1824  } else {
1825  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
1826  RCHECK(buffer->ReadWriteChild(&sinf));
1827  }
1828  }
1829  return true;
1830 }
1831 
1832 size_t AudioSampleEntry::ComputeSizeInternal() {
1833  if (GetActualFormat() == FOURCC_NULL)
1834  return 0;
1835  return HeaderSize() + sizeof(data_reference_index) + sizeof(channelcount) +
1836  sizeof(samplesize) + sizeof(samplerate) + sinf.ComputeSize() +
1837  esds.ComputeSize() + ddts.ComputeSize() + dac3.ComputeSize() +
1838  dec3.ComputeSize() + dops.ComputeSize() + dfla.ComputeSize() +
1839  // Reserved and predefined bytes.
1840  6 + 8 + // 6 + 8 bytes reserved.
1841  4; // 4 bytes predefined.
1842 }
1843 
1844 WebVTTConfigurationBox::WebVTTConfigurationBox() = default;
1845 WebVTTConfigurationBox::~WebVTTConfigurationBox() = default;
1846 
1848  return FOURCC_vttC;
1849 }
1850 
1851 bool WebVTTConfigurationBox::ReadWriteInternal(BoxBuffer* buffer) {
1852  RCHECK(ReadWriteHeaderInternal(buffer));
1853  return buffer->ReadWriteString(
1854  &config, buffer->Reading() ? buffer->BytesLeft() : config.size());
1855 }
1856 
1857 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
1858  return HeaderSize() + config.size();
1859 }
1860 
1861 WebVTTSourceLabelBox::WebVTTSourceLabelBox() = default;
1862 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() = default;
1863 
1865  return FOURCC_vlab;
1866 }
1867 
1868 bool WebVTTSourceLabelBox::ReadWriteInternal(BoxBuffer* buffer) {
1869  RCHECK(ReadWriteHeaderInternal(buffer));
1870  return buffer->ReadWriteString(&source_label, buffer->Reading()
1871  ? buffer->BytesLeft()
1872  : source_label.size());
1873 }
1874 
1875 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
1876  if (source_label.empty())
1877  return 0;
1878  return HeaderSize() + source_label.size();
1879 }
1880 
1881 TextSampleEntry::TextSampleEntry() = default;
1882 TextSampleEntry::~TextSampleEntry() = default;
1883 
1885  if (format == FOURCC_NULL) {
1886  LOG(ERROR) << "TextSampleEntry should be parsed according to the "
1887  << "handler type recovered in its Media ancestor.";
1888  }
1889  return format;
1890 }
1891 
1892 bool TextSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
1893  if (buffer->Reading()) {
1894  DCHECK(buffer->reader());
1895  format = buffer->reader()->type();
1896  } else {
1897  RCHECK(ReadWriteHeaderInternal(buffer));
1898  }
1899  RCHECK(buffer->IgnoreBytes(6) && // reserved for SampleEntry.
1900  buffer->ReadWriteUInt16(&data_reference_index));
1901 
1902  if (format == FOURCC_wvtt) {
1903  // TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
1904  RCHECK(buffer->PrepareChildren() && buffer->ReadWriteChild(&config) &&
1905  buffer->ReadWriteChild(&label));
1906  }
1907  return true;
1908 }
1909 
1910 size_t TextSampleEntry::ComputeSizeInternal() {
1911  // 6 for the (anonymous) reserved bytes for SampleEntry class.
1912  return HeaderSize() + 6 + sizeof(data_reference_index) +
1913  config.ComputeSize() + label.ComputeSize();
1914 }
1915 
1916 MediaHeader::MediaHeader() = default;
1917 MediaHeader::~MediaHeader() = default;
1918 
1919 FourCC MediaHeader::BoxType() const {
1920  return FOURCC_mdhd;
1921 }
1922 
1923 bool MediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
1924  RCHECK(ReadWriteHeaderInternal(buffer));
1925 
1926  uint8_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
1927  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
1928  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
1929  buffer->ReadWriteUInt32(&timescale) &&
1930  buffer->ReadWriteUInt64NBytes(&duration, num_bytes) &&
1931  language.ReadWrite(buffer) &&
1932  // predefined.
1933  buffer->IgnoreBytes(2));
1934  return true;
1935 }
1936 
1937 size_t MediaHeader::ComputeSizeInternal() {
1938  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
1939  return HeaderSize() + sizeof(timescale) +
1940  sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
1941  2; // 2 bytes predefined.
1942 }
1943 
1944 VideoMediaHeader::VideoMediaHeader() {
1945  const uint32_t kVideoMediaHeaderFlags = 1;
1946  flags = kVideoMediaHeaderFlags;
1947 }
1948 
1949 VideoMediaHeader::~VideoMediaHeader() = default;
1950 
1952  return FOURCC_vmhd;
1953 }
1954 bool VideoMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
1955  RCHECK(ReadWriteHeaderInternal(buffer) &&
1956  buffer->ReadWriteUInt16(&graphicsmode) &&
1957  buffer->ReadWriteUInt16(&opcolor_red) &&
1958  buffer->ReadWriteUInt16(&opcolor_green) &&
1959  buffer->ReadWriteUInt16(&opcolor_blue));
1960  return true;
1961 }
1962 
1963 size_t VideoMediaHeader::ComputeSizeInternal() {
1964  return HeaderSize() + sizeof(graphicsmode) + sizeof(opcolor_red) +
1965  sizeof(opcolor_green) + sizeof(opcolor_blue);
1966 }
1967 
1968 SoundMediaHeader::SoundMediaHeader() = default;
1969 SoundMediaHeader::~SoundMediaHeader() = default;
1970 
1972  return FOURCC_smhd;
1973 }
1974 
1975 bool SoundMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
1976  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt16(&balance) &&
1977  buffer->IgnoreBytes(2)); // reserved.
1978  return true;
1979 }
1980 
1981 size_t SoundMediaHeader::ComputeSizeInternal() {
1982  return HeaderSize() + sizeof(balance) + sizeof(uint16_t);
1983 }
1984 
1985 SubtitleMediaHeader::SubtitleMediaHeader() = default;
1986 SubtitleMediaHeader::~SubtitleMediaHeader() = default;
1987 
1989  return FOURCC_sthd;
1990 }
1991 
1992 bool SubtitleMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
1993  return ReadWriteHeaderInternal(buffer);
1994 }
1995 
1996 size_t SubtitleMediaHeader::ComputeSizeInternal() {
1997  return HeaderSize();
1998 }
1999 
2000 DataEntryUrl::DataEntryUrl() {
2001  const uint32_t kDataEntryUrlFlags = 1;
2002  flags = kDataEntryUrlFlags;
2003 }
2004 
2005 DataEntryUrl::~DataEntryUrl() = default;
2006 
2007 FourCC DataEntryUrl::BoxType() const {
2008  return FOURCC_url;
2009 }
2010 bool DataEntryUrl::ReadWriteInternal(BoxBuffer* buffer) {
2011  RCHECK(ReadWriteHeaderInternal(buffer));
2012  if (buffer->Reading()) {
2013  RCHECK(buffer->ReadWriteVector(&location, buffer->BytesLeft()));
2014  } else {
2015  RCHECK(buffer->ReadWriteVector(&location, location.size()));
2016  }
2017  return true;
2018 }
2019 
2020 size_t DataEntryUrl::ComputeSizeInternal() {
2021  return HeaderSize() + location.size();
2022 }
2023 
2024 DataReference::DataReference() = default;
2025 DataReference::~DataReference() = default;
2026 
2027 FourCC DataReference::BoxType() const {
2028  return FOURCC_dref;
2029 }
2030 bool DataReference::ReadWriteInternal(BoxBuffer* buffer) {
2031  uint32_t entry_count = static_cast<uint32_t>(data_entry.size());
2032  RCHECK(ReadWriteHeaderInternal(buffer) &&
2033  buffer->ReadWriteUInt32(&entry_count));
2034  data_entry.resize(entry_count);
2035  RCHECK(buffer->PrepareChildren());
2036  for (uint32_t i = 0; i < entry_count; ++i)
2037  RCHECK(buffer->ReadWriteChild(&data_entry[i]));
2038  return true;
2039 }
2040 
2041 size_t DataReference::ComputeSizeInternal() {
2042  uint32_t count = static_cast<uint32_t>(data_entry.size());
2043  size_t box_size = HeaderSize() + sizeof(count);
2044  for (uint32_t i = 0; i < count; ++i)
2045  box_size += data_entry[i].ComputeSize();
2046  return box_size;
2047 }
2048 
2049 DataInformation::DataInformation() = default;
2050 DataInformation::~DataInformation() = default;
2051 
2053  return FOURCC_dinf;
2054 }
2055 
2056 bool DataInformation::ReadWriteInternal(BoxBuffer* buffer) {
2057  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2058  buffer->ReadWriteChild(&dref);
2059 }
2060 
2061 size_t DataInformation::ComputeSizeInternal() {
2062  return HeaderSize() + dref.ComputeSize();
2063 }
2064 
2065 MediaInformation::MediaInformation() = default;
2066 MediaInformation::~MediaInformation() = default;
2067 
2069  return FOURCC_minf;
2070 }
2071 
2072 bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
2073  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2074  buffer->ReadWriteChild(&dinf) &&
2075  buffer->ReadWriteChild(&sample_table));
2076  switch (sample_table.description.type) {
2077  case kVideo:
2078  RCHECK(buffer->ReadWriteChild(&vmhd));
2079  break;
2080  case kAudio:
2081  RCHECK(buffer->ReadWriteChild(&smhd));
2082  break;
2083  case kText:
2084  RCHECK(buffer->TryReadWriteChild(&sthd));
2085  break;
2086  default:
2087  NOTIMPLEMENTED();
2088  }
2089  // Hint is not supported for now.
2090  return true;
2091 }
2092 
2093 size_t MediaInformation::ComputeSizeInternal() {
2094  size_t box_size =
2095  HeaderSize() + dinf.ComputeSize() + sample_table.ComputeSize();
2096  switch (sample_table.description.type) {
2097  case kVideo:
2098  box_size += vmhd.ComputeSize();
2099  break;
2100  case kAudio:
2101  box_size += smhd.ComputeSize();
2102  break;
2103  case kText:
2104  box_size += sthd.ComputeSize();
2105  break;
2106  default:
2107  NOTIMPLEMENTED();
2108  }
2109  return box_size;
2110 }
2111 
2112 Media::Media() = default;
2113 Media::~Media() = default;
2114 
2115 FourCC Media::BoxType() const {
2116  return FOURCC_mdia;
2117 }
2118 
2119 bool Media::ReadWriteInternal(BoxBuffer* buffer) {
2120  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2121  buffer->ReadWriteChild(&header));
2122  if (buffer->Reading()) {
2123  RCHECK(buffer->ReadWriteChild(&handler));
2124  // Maddeningly, the HandlerReference box specifies how to parse the
2125  // SampleDescription box, making the latter the only box (of those that we
2126  // support) which cannot be parsed correctly on its own (or even with
2127  // information from its strict ancestor tree). We thus copy the handler type
2128  // to the sample description box *before* parsing it to provide this
2129  // information while parsing.
2130  information.sample_table.description.type =
2131  FourCCToTrackType(handler.handler_type);
2132  } else {
2133  handler.handler_type =
2134  TrackTypeToFourCC(information.sample_table.description.type);
2135  RCHECK(handler.handler_type != FOURCC_NULL);
2136  RCHECK(buffer->ReadWriteChild(&handler));
2137  }
2138  RCHECK(buffer->ReadWriteChild(&information));
2139  return true;
2140 }
2141 
2142 size_t Media::ComputeSizeInternal() {
2143  handler.handler_type =
2144  TrackTypeToFourCC(information.sample_table.description.type);
2145  return HeaderSize() + header.ComputeSize() + handler.ComputeSize() +
2146  information.ComputeSize();
2147 }
2148 
2149 Track::Track() = default;
2150 Track::~Track() = default;
2151 
2152 FourCC Track::BoxType() const {
2153  return FOURCC_trak;
2154 }
2155 
2156 bool Track::ReadWriteInternal(BoxBuffer* buffer) {
2157  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2158  buffer->ReadWriteChild(&header) && buffer->ReadWriteChild(&media) &&
2159  buffer->TryReadWriteChild(&edit) &&
2160  buffer->TryReadWriteChild(&sample_encryption));
2161  return true;
2162 }
2163 
2164 size_t Track::ComputeSizeInternal() {
2165  return HeaderSize() + header.ComputeSize() + media.ComputeSize() +
2166  edit.ComputeSize();
2167 }
2168 
2169 MovieExtendsHeader::MovieExtendsHeader() = default;
2170 MovieExtendsHeader::~MovieExtendsHeader() = default;
2171 
2173  return FOURCC_mehd;
2174 }
2175 
2176 bool MovieExtendsHeader::ReadWriteInternal(BoxBuffer* buffer) {
2177  RCHECK(ReadWriteHeaderInternal(buffer));
2178  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
2179  RCHECK(buffer->ReadWriteUInt64NBytes(&fragment_duration, num_bytes));
2180  return true;
2181 }
2182 
2183 size_t MovieExtendsHeader::ComputeSizeInternal() {
2184  // This box is optional. Skip it if it is not used.
2185  if (fragment_duration == 0)
2186  return 0;
2187  version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
2188  return HeaderSize() + sizeof(uint32_t) * (1 + version);
2189 }
2190 
2191 TrackExtends::TrackExtends() = default;
2192 TrackExtends::~TrackExtends() = default;
2193 
2194 FourCC TrackExtends::BoxType() const {
2195  return FOURCC_trex;
2196 }
2197 
2198 bool TrackExtends::ReadWriteInternal(BoxBuffer* buffer) {
2199  RCHECK(ReadWriteHeaderInternal(buffer) &&
2200  buffer->ReadWriteUInt32(&track_id) &&
2201  buffer->ReadWriteUInt32(&default_sample_description_index) &&
2202  buffer->ReadWriteUInt32(&default_sample_duration) &&
2203  buffer->ReadWriteUInt32(&default_sample_size) &&
2204  buffer->ReadWriteUInt32(&default_sample_flags));
2205  return true;
2206 }
2207 
2208 size_t TrackExtends::ComputeSizeInternal() {
2209  return HeaderSize() + sizeof(track_id) +
2210  sizeof(default_sample_description_index) +
2211  sizeof(default_sample_duration) + sizeof(default_sample_size) +
2212  sizeof(default_sample_flags);
2213 }
2214 
2215 MovieExtends::MovieExtends() = default;
2216 MovieExtends::~MovieExtends() = default;
2217 
2218 FourCC MovieExtends::BoxType() const {
2219  return FOURCC_mvex;
2220 }
2221 
2222 bool MovieExtends::ReadWriteInternal(BoxBuffer* buffer) {
2223  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2224  buffer->TryReadWriteChild(&header));
2225  if (buffer->Reading()) {
2226  DCHECK(buffer->reader());
2227  RCHECK(buffer->reader()->ReadChildren(&tracks));
2228  } else {
2229  for (uint32_t i = 0; i < tracks.size(); ++i)
2230  RCHECK(buffer->ReadWriteChild(&tracks[i]));
2231  }
2232  return true;
2233 }
2234 
2235 size_t MovieExtends::ComputeSizeInternal() {
2236  // This box is optional. Skip it if it does not contain any track.
2237  if (tracks.size() == 0)
2238  return 0;
2239  size_t box_size = HeaderSize() + header.ComputeSize();
2240  for (uint32_t i = 0; i < tracks.size(); ++i)
2241  box_size += tracks[i].ComputeSize();
2242  return box_size;
2243 }
2244 
2245 Movie::Movie() = default;
2246 Movie::~Movie() = default;
2247 
2248 FourCC Movie::BoxType() const {
2249  return FOURCC_moov;
2250 }
2251 
2252 bool Movie::ReadWriteInternal(BoxBuffer* buffer) {
2253  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2254  buffer->ReadWriteChild(&header));
2255  if (buffer->Reading()) {
2256  BoxReader* reader = buffer->reader();
2257  DCHECK(reader);
2258  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChild(&extends) &&
2259  reader->TryReadChildren(&pssh));
2260  } else {
2261  // The 'meta' box is not well formed in the video captured by Android's
2262  // default camera app: spec indicates that it is a FullBox but it is written
2263  // as a Box. This results in the box failed to be parsed. See
2264  // https://github.com/google/shaka-packager/issues/319 for details.
2265  // We do not care the content of metadata box in the source content, so just
2266  // skip reading the box.
2267  RCHECK(buffer->TryReadWriteChild(&metadata));
2268  for (uint32_t i = 0; i < tracks.size(); ++i)
2269  RCHECK(buffer->ReadWriteChild(&tracks[i]));
2270  RCHECK(buffer->TryReadWriteChild(&extends));
2271  for (uint32_t i = 0; i < pssh.size(); ++i)
2272  RCHECK(buffer->ReadWriteChild(&pssh[i]));
2273  }
2274  return true;
2275 }
2276 
2277 size_t Movie::ComputeSizeInternal() {
2278  size_t box_size = HeaderSize() + header.ComputeSize() +
2279  metadata.ComputeSize() + extends.ComputeSize();
2280  for (uint32_t i = 0; i < tracks.size(); ++i)
2281  box_size += tracks[i].ComputeSize();
2282  for (uint32_t i = 0; i < pssh.size(); ++i)
2283  box_size += pssh[i].ComputeSize();
2284  return box_size;
2285 }
2286 
2287 TrackFragmentDecodeTime::TrackFragmentDecodeTime() = default;
2288 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() = default;
2289 
2291  return FOURCC_tfdt;
2292 }
2293 
2294 bool TrackFragmentDecodeTime::ReadWriteInternal(BoxBuffer* buffer) {
2295  RCHECK(ReadWriteHeaderInternal(buffer));
2296  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
2297  RCHECK(buffer->ReadWriteUInt64NBytes(&decode_time, num_bytes));
2298  return true;
2299 }
2300 
2301 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
2302  version = IsFitIn32Bits(decode_time) ? 0 : 1;
2303  return HeaderSize() + sizeof(uint32_t) * (1 + version);
2304 }
2305 
2306 MovieFragmentHeader::MovieFragmentHeader() = default;
2307 MovieFragmentHeader::~MovieFragmentHeader() = default;
2308 
2310  return FOURCC_mfhd;
2311 }
2312 
2313 bool MovieFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
2314  return ReadWriteHeaderInternal(buffer) &&
2315  buffer->ReadWriteUInt32(&sequence_number);
2316 }
2317 
2318 size_t MovieFragmentHeader::ComputeSizeInternal() {
2319  return HeaderSize() + sizeof(sequence_number);
2320 }
2321 
2322 TrackFragmentHeader::TrackFragmentHeader() = default;
2323 TrackFragmentHeader::~TrackFragmentHeader() = default;
2324 
2326  return FOURCC_tfhd;
2327 }
2328 
2329 bool TrackFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
2330  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&track_id));
2331 
2332  if (flags & kBaseDataOffsetPresentMask) {
2333  // MSE requires 'default-base-is-moof' to be set and
2334  // 'base-data-offset-present' not to be set. We omit these checks as some
2335  // valid files in the wild don't follow these rules, though they use moof as
2336  // base.
2337  uint64_t base_data_offset;
2338  RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
2339  DLOG(WARNING) << "base-data-offset-present is not expected. Assumes "
2340  "default-base-is-moof.";
2341  }
2342 
2343  if (flags & kSampleDescriptionIndexPresentMask) {
2344  RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
2345  } else if (buffer->Reading()) {
2346  sample_description_index = 0;
2347  }
2348 
2349  if (flags & kDefaultSampleDurationPresentMask) {
2350  RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
2351  } else if (buffer->Reading()) {
2352  default_sample_duration = 0;
2353  }
2354 
2355  if (flags & kDefaultSampleSizePresentMask) {
2356  RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
2357  } else if (buffer->Reading()) {
2358  default_sample_size = 0;
2359  }
2360 
2361  if (flags & kDefaultSampleFlagsPresentMask)
2362  RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
2363  return true;
2364 }
2365 
2366 size_t TrackFragmentHeader::ComputeSizeInternal() {
2367  size_t box_size = HeaderSize() + sizeof(track_id);
2368  if (flags & kSampleDescriptionIndexPresentMask)
2369  box_size += sizeof(sample_description_index);
2370  if (flags & kDefaultSampleDurationPresentMask)
2371  box_size += sizeof(default_sample_duration);
2372  if (flags & kDefaultSampleSizePresentMask)
2373  box_size += sizeof(default_sample_size);
2374  if (flags & kDefaultSampleFlagsPresentMask)
2375  box_size += sizeof(default_sample_flags);
2376  return box_size;
2377 }
2378 
2379 TrackFragmentRun::TrackFragmentRun() = default;
2380 TrackFragmentRun::~TrackFragmentRun() = default;
2381 
2383  return FOURCC_trun;
2384 }
2385 
2386 bool TrackFragmentRun::ReadWriteInternal(BoxBuffer* buffer) {
2387  if (!buffer->Reading()) {
2388  // Determine whether version 0 or version 1 should be used.
2389  // Use version 0 if possible, use version 1 if there is a negative
2390  // sample_offset value.
2391  version = 0;
2392  if (flags & kSampleCompTimeOffsetsPresentMask) {
2393  for (uint32_t i = 0; i < sample_count; ++i) {
2394  if (sample_composition_time_offsets[i] < 0) {
2395  version = 1;
2396  break;
2397  }
2398  }
2399  }
2400  }
2401 
2402  RCHECK(ReadWriteHeaderInternal(buffer) &&
2403  buffer->ReadWriteUInt32(&sample_count));
2404 
2405  bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
2406  bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
2407  bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
2408  bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
2409  bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
2410  bool sample_composition_time_offsets_present =
2411  (flags & kSampleCompTimeOffsetsPresentMask) != 0;
2412 
2413  if (data_offset_present) {
2414  RCHECK(buffer->ReadWriteUInt32(&data_offset));
2415  } else {
2416  // NOTE: If the data-offset is not present, then the data for this run
2417  // starts immediately after the data of the previous run, or at the
2418  // base-data-offset defined by the track fragment header if this is the
2419  // first run in a track fragment. If the data-offset is present, it is
2420  // relative to the base-data-offset established in the track fragment
2421  // header.
2422  NOTIMPLEMENTED();
2423  }
2424 
2425  uint32_t first_sample_flags(0);
2426 
2427  if (buffer->Reading()) {
2428  if (first_sample_flags_present)
2429  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2430 
2431  if (sample_duration_present)
2432  sample_durations.resize(sample_count);
2433  if (sample_size_present)
2434  sample_sizes.resize(sample_count);
2435  if (sample_flags_present)
2436  sample_flags.resize(sample_count);
2437  if (sample_composition_time_offsets_present)
2438  sample_composition_time_offsets.resize(sample_count);
2439  } else {
2440  if (first_sample_flags_present) {
2441  first_sample_flags = sample_flags[0];
2442  DCHECK(sample_flags.size() == 1);
2443  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
2444  }
2445 
2446  if (sample_duration_present)
2447  DCHECK(sample_durations.size() == sample_count);
2448  if (sample_size_present)
2449  DCHECK(sample_sizes.size() == sample_count);
2450  if (sample_flags_present)
2451  DCHECK(sample_flags.size() == sample_count);
2452  if (sample_composition_time_offsets_present)
2453  DCHECK(sample_composition_time_offsets.size() == sample_count);
2454  }
2455 
2456  for (uint32_t i = 0; i < sample_count; ++i) {
2457  if (sample_duration_present)
2458  RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
2459  if (sample_size_present)
2460  RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
2461  if (sample_flags_present)
2462  RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
2463 
2464  if (sample_composition_time_offsets_present) {
2465  if (version == 0) {
2466  uint32_t sample_offset = sample_composition_time_offsets[i];
2467  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
2468  sample_composition_time_offsets[i] = sample_offset;
2469  } else {
2470  int32_t sample_offset = sample_composition_time_offsets[i];
2471  RCHECK(buffer->ReadWriteInt32(&sample_offset));
2472  sample_composition_time_offsets[i] = sample_offset;
2473  }
2474  }
2475  }
2476 
2477  if (buffer->Reading()) {
2478  if (first_sample_flags_present) {
2479  if (sample_flags.size() == 0) {
2480  sample_flags.push_back(first_sample_flags);
2481  } else {
2482  sample_flags[0] = first_sample_flags;
2483  }
2484  }
2485  }
2486  return true;
2487 }
2488 
2489 size_t TrackFragmentRun::ComputeSizeInternal() {
2490  size_t box_size = HeaderSize() + sizeof(sample_count);
2491  if (flags & kDataOffsetPresentMask)
2492  box_size += sizeof(data_offset);
2493  if (flags & kFirstSampleFlagsPresentMask)
2494  box_size += sizeof(uint32_t);
2495  uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
2496  (flags & kSampleSizePresentMask ? 1 : 0) +
2497  (flags & kSampleFlagsPresentMask ? 1 : 0) +
2498  (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
2499  box_size += fields * sizeof(uint32_t) * sample_count;
2500  return box_size;
2501 }
2502 
2503 TrackFragment::TrackFragment() = default;
2504 TrackFragment::~TrackFragment() = default;
2505 
2506 FourCC TrackFragment::BoxType() const {
2507  return FOURCC_traf;
2508 }
2509 
2510 bool TrackFragment::ReadWriteInternal(BoxBuffer* buffer) {
2511  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2512  buffer->ReadWriteChild(&header));
2513  if (buffer->Reading()) {
2514  DCHECK(buffer->reader());
2515  decode_time_absent = !buffer->reader()->ChildExist(&decode_time);
2516  if (!decode_time_absent)
2517  RCHECK(buffer->ReadWriteChild(&decode_time));
2518  RCHECK(buffer->reader()->TryReadChildren(&runs) &&
2519  buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
2520  buffer->reader()->TryReadChildren(&sample_to_groups));
2521  } else {
2522  if (!decode_time_absent)
2523  RCHECK(buffer->ReadWriteChild(&decode_time));
2524  for (uint32_t i = 0; i < runs.size(); ++i)
2525  RCHECK(buffer->ReadWriteChild(&runs[i]));
2526  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2527  RCHECK(buffer->ReadWriteChild(&sample_to_groups[i]));
2528  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2529  RCHECK(buffer->ReadWriteChild(&sample_group_descriptions[i]));
2530  }
2531  return buffer->TryReadWriteChild(&auxiliary_size) &&
2532  buffer->TryReadWriteChild(&auxiliary_offset) &&
2533  buffer->TryReadWriteChild(&sample_encryption);
2534 }
2535 
2536 size_t TrackFragment::ComputeSizeInternal() {
2537  size_t box_size = HeaderSize() + header.ComputeSize() +
2538  decode_time.ComputeSize() + auxiliary_size.ComputeSize() +
2539  auxiliary_offset.ComputeSize() +
2540  sample_encryption.ComputeSize();
2541  for (uint32_t i = 0; i < runs.size(); ++i)
2542  box_size += runs[i].ComputeSize();
2543  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
2544  box_size += sample_group_descriptions[i].ComputeSize();
2545  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
2546  box_size += sample_to_groups[i].ComputeSize();
2547  return box_size;
2548 }
2549 
2550 MovieFragment::MovieFragment() = default;
2551 MovieFragment::~MovieFragment() = default;
2552 
2553 FourCC MovieFragment::BoxType() const {
2554  return FOURCC_moof;
2555 }
2556 
2557 bool MovieFragment::ReadWriteInternal(BoxBuffer* buffer) {
2558  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2559  buffer->ReadWriteChild(&header));
2560  if (buffer->Reading()) {
2561  BoxReader* reader = buffer->reader();
2562  DCHECK(reader);
2563  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChildren(&pssh));
2564  } else {
2565  for (uint32_t i = 0; i < tracks.size(); ++i)
2566  RCHECK(buffer->ReadWriteChild(&tracks[i]));
2567  for (uint32_t i = 0; i < pssh.size(); ++i)
2568  RCHECK(buffer->ReadWriteChild(&pssh[i]));
2569  }
2570  return true;
2571 }
2572 
2573 size_t MovieFragment::ComputeSizeInternal() {
2574  size_t box_size = HeaderSize() + header.ComputeSize();
2575  for (uint32_t i = 0; i < tracks.size(); ++i)
2576  box_size += tracks[i].ComputeSize();
2577  for (uint32_t i = 0; i < pssh.size(); ++i)
2578  box_size += pssh[i].ComputeSize();
2579  return box_size;
2580 }
2581 
2582 SegmentIndex::SegmentIndex() = default;
2583 SegmentIndex::~SegmentIndex() = default;
2584 
2585 FourCC SegmentIndex::BoxType() const {
2586  return FOURCC_sidx;
2587 }
2588 
2589 bool SegmentIndex::ReadWriteInternal(BoxBuffer* buffer) {
2590  RCHECK(ReadWriteHeaderInternal(buffer) &&
2591  buffer->ReadWriteUInt32(&reference_id) &&
2592  buffer->ReadWriteUInt32(&timescale));
2593 
2594  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
2595  RCHECK(
2596  buffer->ReadWriteUInt64NBytes(&earliest_presentation_time, num_bytes) &&
2597  buffer->ReadWriteUInt64NBytes(&first_offset, num_bytes));
2598 
2599  uint16_t reference_count = static_cast<uint16_t>(references.size());
2600  RCHECK(buffer->IgnoreBytes(2) && // reserved.
2601  buffer->ReadWriteUInt16(&reference_count));
2602  references.resize(reference_count);
2603 
2604  uint32_t reference_type_size;
2605  uint32_t sap;
2606  for (uint32_t i = 0; i < reference_count; ++i) {
2607  if (!buffer->Reading()) {
2608  reference_type_size = references[i].referenced_size;
2609  if (references[i].reference_type)
2610  reference_type_size |= (1 << 31);
2611  sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
2612  if (references[i].starts_with_sap)
2613  sap |= (1 << 31);
2614  }
2615  RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
2616  buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
2617  buffer->ReadWriteUInt32(&sap));
2618  if (buffer->Reading()) {
2619  references[i].reference_type = (reference_type_size >> 31) ? true : false;
2620  references[i].referenced_size = reference_type_size & ~(1 << 31);
2621  references[i].starts_with_sap = (sap >> 31) ? true : false;
2622  references[i].sap_type =
2623  static_cast<SegmentReference::SAPType>((sap >> 28) & 0x07);
2624  references[i].sap_delta_time = sap & ~(0xF << 28);
2625  }
2626  }
2627  return true;
2628 }
2629 
2630 size_t SegmentIndex::ComputeSizeInternal() {
2631  version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
2632  return HeaderSize() + sizeof(reference_id) + sizeof(timescale) +
2633  sizeof(uint32_t) * (1 + version) * 2 + 2 * sizeof(uint16_t) +
2634  3 * sizeof(uint32_t) * references.size();
2635 }
2636 
2637 MediaData::MediaData() = default;
2638 MediaData::~MediaData() = default;
2639 
2640 FourCC MediaData::BoxType() const {
2641  return FOURCC_mdat;
2642 }
2643 
2644 bool MediaData::ReadWriteInternal(BoxBuffer* buffer) {
2645  NOTIMPLEMENTED() << "Actual data is parsed and written separately.";
2646  return false;
2647 }
2648 
2649 size_t MediaData::ComputeSizeInternal() {
2650  return HeaderSize() + data_size;
2651 }
2652 
2653 CueSourceIDBox::CueSourceIDBox() = default;
2654 CueSourceIDBox::~CueSourceIDBox() = default;
2655 
2656 FourCC CueSourceIDBox::BoxType() const {
2657  return FOURCC_vsid;
2658 }
2659 
2660 bool CueSourceIDBox::ReadWriteInternal(BoxBuffer* buffer) {
2661  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteInt32(&source_id));
2662  return true;
2663 }
2664 
2665 size_t CueSourceIDBox::ComputeSizeInternal() {
2666  if (source_id == kCueSourceIdNotSet)
2667  return 0;
2668  return HeaderSize() + sizeof(source_id);
2669 }
2670 
2671 CueTimeBox::CueTimeBox() = default;
2672 CueTimeBox::~CueTimeBox() = default;
2673 
2674 FourCC CueTimeBox::BoxType() const {
2675  return FOURCC_ctim;
2676 }
2677 
2678 bool CueTimeBox::ReadWriteInternal(BoxBuffer* buffer) {
2679  RCHECK(ReadWriteHeaderInternal(buffer));
2680  return buffer->ReadWriteString(
2681  &cue_current_time,
2682  buffer->Reading() ? buffer->BytesLeft() : cue_current_time.size());
2683 }
2684 
2685 size_t CueTimeBox::ComputeSizeInternal() {
2686  if (cue_current_time.empty())
2687  return 0;
2688  return HeaderSize() + cue_current_time.size();
2689 }
2690 
2691 CueIDBox::CueIDBox() = default;
2692 CueIDBox::~CueIDBox() = default;
2693 
2694 FourCC CueIDBox::BoxType() const {
2695  return FOURCC_iden;
2696 }
2697 
2698 bool CueIDBox::ReadWriteInternal(BoxBuffer* buffer) {
2699  RCHECK(ReadWriteHeaderInternal(buffer));
2700  return buffer->ReadWriteString(
2701  &cue_id, buffer->Reading() ? buffer->BytesLeft() : cue_id.size());
2702 }
2703 
2704 size_t CueIDBox::ComputeSizeInternal() {
2705  if (cue_id.empty())
2706  return 0;
2707  return HeaderSize() + cue_id.size();
2708 }
2709 
2710 CueSettingsBox::CueSettingsBox() = default;
2711 CueSettingsBox::~CueSettingsBox() = default;
2712 
2713 FourCC CueSettingsBox::BoxType() const {
2714  return FOURCC_sttg;
2715 }
2716 
2717 bool CueSettingsBox::ReadWriteInternal(BoxBuffer* buffer) {
2718  RCHECK(ReadWriteHeaderInternal(buffer));
2719  return buffer->ReadWriteString(
2720  &settings, buffer->Reading() ? buffer->BytesLeft() : settings.size());
2721 }
2722 
2723 size_t CueSettingsBox::ComputeSizeInternal() {
2724  if (settings.empty())
2725  return 0;
2726  return HeaderSize() + settings.size();
2727 }
2728 
2729 CuePayloadBox::CuePayloadBox() = default;
2730 CuePayloadBox::~CuePayloadBox() = default;
2731 
2732 FourCC CuePayloadBox::BoxType() const {
2733  return FOURCC_payl;
2734 }
2735 
2736 bool CuePayloadBox::ReadWriteInternal(BoxBuffer* buffer) {
2737  RCHECK(ReadWriteHeaderInternal(buffer));
2738  return buffer->ReadWriteString(
2739  &cue_text, buffer->Reading() ? buffer->BytesLeft() : cue_text.size());
2740 }
2741 
2742 size_t CuePayloadBox::ComputeSizeInternal() {
2743  return HeaderSize() + cue_text.size();
2744 }
2745 
2746 VTTEmptyCueBox::VTTEmptyCueBox() = default;
2747 VTTEmptyCueBox::~VTTEmptyCueBox() = default;
2748 
2749 FourCC VTTEmptyCueBox::BoxType() const {
2750  return FOURCC_vtte;
2751 }
2752 
2753 bool VTTEmptyCueBox::ReadWriteInternal(BoxBuffer* buffer) {
2754  return ReadWriteHeaderInternal(buffer);
2755 }
2756 
2757 size_t VTTEmptyCueBox::ComputeSizeInternal() {
2758  return HeaderSize();
2759 }
2760 
2761 VTTAdditionalTextBox::VTTAdditionalTextBox() = default;
2762 VTTAdditionalTextBox::~VTTAdditionalTextBox() = default;
2763 
2765  return FOURCC_vtta;
2766 }
2767 
2768 bool VTTAdditionalTextBox::ReadWriteInternal(BoxBuffer* buffer) {
2769  RCHECK(ReadWriteHeaderInternal(buffer));
2770  return buffer->ReadWriteString(
2771  &cue_additional_text,
2772  buffer->Reading() ? buffer->BytesLeft() : cue_additional_text.size());
2773 }
2774 
2775 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
2776  return HeaderSize() + cue_additional_text.size();
2777 }
2778 
2779 VTTCueBox::VTTCueBox() = default;
2780 VTTCueBox::~VTTCueBox() = default;
2781 
2782 FourCC VTTCueBox::BoxType() const {
2783  return FOURCC_vttc;
2784 }
2785 
2786 bool VTTCueBox::ReadWriteInternal(BoxBuffer* buffer) {
2787  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
2788  buffer->TryReadWriteChild(&cue_source_id) &&
2789  buffer->TryReadWriteChild(&cue_id) &&
2790  buffer->TryReadWriteChild(&cue_time) &&
2791  buffer->TryReadWriteChild(&cue_settings) &&
2792  buffer->ReadWriteChild(&cue_payload));
2793  return true;
2794 }
2795 
2796 size_t VTTCueBox::ComputeSizeInternal() {
2797  return HeaderSize() + cue_source_id.ComputeSize() + cue_id.ComputeSize() +
2798  cue_time.ComputeSize() + cue_settings.ComputeSize() +
2799  cue_payload.ComputeSize();
2800 }
2801 
2802 } // namespace mp4
2803 } // namespace media
2804 } // namespace shaka
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
A class to read bit streams.
Definition: bit_reader.h:17
FourCC BoxType() const override
FourCC BoxType() const override
bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:134
bool TryReadWriteChild(Box *box)
Definition: box_buffer.h:177
FourCC BoxType() const override
bool ReadAllChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:157
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
size_t BytesLeft() const
Definition: box_buffer.h:62
FourCC BoxType() const override
FourCC BoxType() const override
virtual bool ReadWriteHeaderInternal(BoxBuffer *buffer)
Definition: box.cc:61
FourCC BoxType() const override
All the methods that are virtual are virtual for mocking.
FourCC BoxType() const override
bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
FourCC BoxType() const override
uint32_t ComputeSize()
Definition: box.cc:50
bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:128
FourCC BoxType() const override
FourCC BoxType() const override
uint32_t box_size()
Definition: box.h:55
FourCC BoxType() const override
BufferWriter * writer()
Definition: box_buffer.h:200
FourCC BoxType() const override
FourCC BoxType() const override
bool IgnoreBytes(size_t num_bytes)
Definition: box_buffer.h:189
Class for reading MP4 boxes.
Definition: box_reader.h:25
bool ReadWriteString(std::string *str, size_t size)
Definition: box_buffer.h:139
FourCC BoxType() const override
bool ReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:90
virtual uint32_t HeaderSize() const
Definition: box.cc:55
FourCC BoxType() const override
FourCC BoxType() const override
bool ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)
Definition: box_buffer.h:117
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
FourCC BoxType() const override
void Write(BufferWriter *writer)
Definition: box.cc:25
FourCC BoxType() const override
FourCC BoxType() const override
bool TryReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:106
FourCC BoxType() const override
FourCC BoxType() const override
bool ChildExist(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:102
bool ReadWriteChild(Box *box)
Definition: box_buffer.h:166