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