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