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