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