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