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