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