1 // Copyright 2014 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 "media/formats/mp4/box_definitions.h" 6 7 #include "base/logging.h" 8 #include "media/formats/mp4/es_descriptor.h" 9 #include "media/formats/mp4/rcheck.h" 10 11 namespace media { 12 namespace mp4 { 13 14 FileType::FileType() {} 15 FileType::~FileType() {} 16 FourCC FileType::BoxType() const { return FOURCC_FTYP; } 17 18 bool FileType::Parse(BoxReader* reader) { 19 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); 20 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); 21 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands 22 } 23 24 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {} 25 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {} 26 FourCC ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH; } 27 28 bool ProtectionSystemSpecificHeader::Parse(BoxReader* reader) { 29 // Validate the box's contents and hang on to the system ID. 30 uint32 size; 31 RCHECK(reader->ReadFullBoxHeader() && 32 reader->ReadVec(&system_id, 16) && 33 reader->Read4(&size) && 34 reader->HasBytes(size)); 35 36 // Copy the entire box, including the header, for passing to EME as initData. 37 DCHECK(raw_box.empty()); 38 raw_box.assign(reader->data(), reader->data() + reader->size()); 39 return true; 40 } 41 42 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {} 43 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} 44 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; } 45 46 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { 47 RCHECK(reader->ReadFullBoxHeader()); 48 if (reader->flags() & 1) 49 RCHECK(reader->SkipBytes(8)); 50 51 uint32 count; 52 RCHECK(reader->Read4(&count) && 53 reader->HasBytes(count * (reader->version() == 1 ? 8 : 4))); 54 offsets.resize(count); 55 56 for (uint32 i = 0; i < count; i++) { 57 if (reader->version() == 1) { 58 RCHECK(reader->Read8(&offsets[i])); 59 } else { 60 RCHECK(reader->Read4Into8(&offsets[i])); 61 } 62 } 63 return true; 64 } 65 66 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() 67 : default_sample_info_size(0), sample_count(0) { 68 } 69 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {} 70 FourCC SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ; } 71 72 bool SampleAuxiliaryInformationSize::Parse(BoxReader* reader) { 73 RCHECK(reader->ReadFullBoxHeader()); 74 if (reader->flags() & 1) 75 RCHECK(reader->SkipBytes(8)); 76 77 RCHECK(reader->Read1(&default_sample_info_size) && 78 reader->Read4(&sample_count)); 79 if (default_sample_info_size == 0) 80 return reader->ReadVec(&sample_info_sizes, sample_count); 81 return true; 82 } 83 84 OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {} 85 OriginalFormat::~OriginalFormat() {} 86 FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; } 87 88 bool OriginalFormat::Parse(BoxReader* reader) { 89 return reader->ReadFourCC(&format); 90 } 91 92 SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {} 93 SchemeType::~SchemeType() {} 94 FourCC SchemeType::BoxType() const { return FOURCC_SCHM; } 95 96 bool SchemeType::Parse(BoxReader* reader) { 97 RCHECK(reader->ReadFullBoxHeader() && 98 reader->ReadFourCC(&type) && 99 reader->Read4(&version)); 100 return true; 101 } 102 103 TrackEncryption::TrackEncryption() 104 : is_encrypted(false), default_iv_size(0) { 105 } 106 TrackEncryption::~TrackEncryption() {} 107 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; } 108 109 bool TrackEncryption::Parse(BoxReader* reader) { 110 uint8 flag; 111 RCHECK(reader->ReadFullBoxHeader() && 112 reader->SkipBytes(2) && 113 reader->Read1(&flag) && 114 reader->Read1(&default_iv_size) && 115 reader->ReadVec(&default_kid, 16)); 116 is_encrypted = (flag != 0); 117 if (is_encrypted) { 118 RCHECK(default_iv_size == 8 || default_iv_size == 16); 119 } else { 120 RCHECK(default_iv_size == 0); 121 } 122 return true; 123 } 124 125 SchemeInfo::SchemeInfo() {} 126 SchemeInfo::~SchemeInfo() {} 127 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; } 128 129 bool SchemeInfo::Parse(BoxReader* reader) { 130 return reader->ScanChildren() && reader->ReadChild(&track_encryption); 131 } 132 133 ProtectionSchemeInfo::ProtectionSchemeInfo() {} 134 ProtectionSchemeInfo::~ProtectionSchemeInfo() {} 135 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; } 136 137 bool ProtectionSchemeInfo::Parse(BoxReader* reader) { 138 RCHECK(reader->ScanChildren() && 139 reader->ReadChild(&format) && 140 reader->ReadChild(&type)); 141 if (type.type == FOURCC_CENC) 142 RCHECK(reader->ReadChild(&info)); 143 // Other protection schemes are silently ignored. Since the protection scheme 144 // type can't be determined until this box is opened, we return 'true' for 145 // non-CENC protection scheme types. It is the parent box's responsibility to 146 // ensure that this scheme type is a supported one. 147 return true; 148 } 149 150 MovieHeader::MovieHeader() 151 : creation_time(0), 152 modification_time(0), 153 timescale(0), 154 duration(0), 155 rate(-1), 156 volume(-1), 157 next_track_id(0) {} 158 MovieHeader::~MovieHeader() {} 159 FourCC MovieHeader::BoxType() const { return FOURCC_MVHD; } 160 161 bool MovieHeader::Parse(BoxReader* reader) { 162 RCHECK(reader->ReadFullBoxHeader()); 163 164 if (reader->version() == 1) { 165 RCHECK(reader->Read8(&creation_time) && 166 reader->Read8(&modification_time) && 167 reader->Read4(×cale) && 168 reader->Read8(&duration)); 169 } else { 170 RCHECK(reader->Read4Into8(&creation_time) && 171 reader->Read4Into8(&modification_time) && 172 reader->Read4(×cale) && 173 reader->Read4Into8(&duration)); 174 } 175 176 RCHECK(reader->Read4s(&rate) && 177 reader->Read2s(&volume) && 178 reader->SkipBytes(10) && // reserved 179 reader->SkipBytes(36) && // matrix 180 reader->SkipBytes(24) && // predefined zero 181 reader->Read4(&next_track_id)); 182 return true; 183 } 184 185 TrackHeader::TrackHeader() 186 : creation_time(0), 187 modification_time(0), 188 track_id(0), 189 duration(0), 190 layer(-1), 191 alternate_group(-1), 192 volume(-1), 193 width(0), 194 height(0) {} 195 TrackHeader::~TrackHeader() {} 196 FourCC TrackHeader::BoxType() const { return FOURCC_TKHD; } 197 198 bool TrackHeader::Parse(BoxReader* reader) { 199 RCHECK(reader->ReadFullBoxHeader()); 200 if (reader->version() == 1) { 201 RCHECK(reader->Read8(&creation_time) && 202 reader->Read8(&modification_time) && 203 reader->Read4(&track_id) && 204 reader->SkipBytes(4) && // reserved 205 reader->Read8(&duration)); 206 } else { 207 RCHECK(reader->Read4Into8(&creation_time) && 208 reader->Read4Into8(&modification_time) && 209 reader->Read4(&track_id) && 210 reader->SkipBytes(4) && // reserved 211 reader->Read4Into8(&duration)); 212 } 213 214 RCHECK(reader->SkipBytes(8) && // reserved 215 reader->Read2s(&layer) && 216 reader->Read2s(&alternate_group) && 217 reader->Read2s(&volume) && 218 reader->SkipBytes(2) && // reserved 219 reader->SkipBytes(36) && // matrix 220 reader->Read4(&width) && 221 reader->Read4(&height)); 222 width >>= 16; 223 height >>= 16; 224 return true; 225 } 226 227 SampleDescription::SampleDescription() : type(kInvalid) {} 228 SampleDescription::~SampleDescription() {} 229 FourCC SampleDescription::BoxType() const { return FOURCC_STSD; } 230 231 bool SampleDescription::Parse(BoxReader* reader) { 232 uint32 count; 233 RCHECK(reader->SkipBytes(4) && 234 reader->Read4(&count)); 235 video_entries.clear(); 236 audio_entries.clear(); 237 238 // Note: this value is preset before scanning begins. See comments in the 239 // Parse(Media*) function. 240 if (type == kVideo) { 241 RCHECK(reader->ReadAllChildren(&video_entries)); 242 } else if (type == kAudio) { 243 RCHECK(reader->ReadAllChildren(&audio_entries)); 244 } 245 return true; 246 } 247 248 SyncSample::SyncSample() : is_present(false) {} 249 SyncSample::~SyncSample() {} 250 FourCC SyncSample::BoxType() const { return FOURCC_STSS; } 251 252 bool SyncSample::Parse(BoxReader* reader) { 253 uint32 entry_count; 254 RCHECK(reader->ReadFullBoxHeader() && 255 reader->Read4(&entry_count)); 256 257 is_present = true; 258 259 entries.resize(entry_count); 260 261 if (entry_count == 0) 262 return true; 263 264 for (size_t i = 0; i < entry_count; ++i) 265 RCHECK(reader->Read4(&entries[i])); 266 267 return true; 268 } 269 270 bool SyncSample::IsSyncSample(size_t k) const { 271 // ISO/IEC 14496-12 Section 8.6.2.1 : If the sync sample box is not present, 272 // every sample is a sync sample. 273 if (!is_present) 274 return true; 275 276 // ISO/IEC 14496-12 Section 8.6.2.3 : If entry_count is zero, there are no 277 // sync samples within the stream. 278 if (entries.size() == 0u) 279 return false; 280 281 for (size_t i = 0; i < entries.size(); ++i) { 282 if (entries[i] == k) 283 return true; 284 } 285 286 return false; 287 } 288 289 SampleTable::SampleTable() {} 290 SampleTable::~SampleTable() {} 291 FourCC SampleTable::BoxType() const { return FOURCC_STBL; } 292 293 bool SampleTable::Parse(BoxReader* reader) { 294 return reader->ScanChildren() && 295 reader->ReadChild(&description) && 296 reader->MaybeReadChild(&sync_sample); 297 } 298 299 EditList::EditList() {} 300 EditList::~EditList() {} 301 FourCC EditList::BoxType() const { return FOURCC_ELST; } 302 303 bool EditList::Parse(BoxReader* reader) { 304 uint32 count; 305 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); 306 307 if (reader->version() == 1) { 308 RCHECK(reader->HasBytes(count * 20)); 309 } else { 310 RCHECK(reader->HasBytes(count * 12)); 311 } 312 edits.resize(count); 313 314 for (std::vector<EditListEntry>::iterator edit = edits.begin(); 315 edit != edits.end(); ++edit) { 316 if (reader->version() == 1) { 317 RCHECK(reader->Read8(&edit->segment_duration) && 318 reader->Read8s(&edit->media_time)); 319 } else { 320 RCHECK(reader->Read4Into8(&edit->segment_duration) && 321 reader->Read4sInto8s(&edit->media_time)); 322 } 323 RCHECK(reader->Read2s(&edit->media_rate_integer) && 324 reader->Read2s(&edit->media_rate_fraction)); 325 } 326 return true; 327 } 328 329 Edit::Edit() {} 330 Edit::~Edit() {} 331 FourCC Edit::BoxType() const { return FOURCC_EDTS; } 332 333 bool Edit::Parse(BoxReader* reader) { 334 return reader->ScanChildren() && reader->ReadChild(&list); 335 } 336 337 HandlerReference::HandlerReference() : type(kInvalid) {} 338 HandlerReference::~HandlerReference() {} 339 FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; } 340 341 bool HandlerReference::Parse(BoxReader* reader) { 342 FourCC hdlr_type; 343 RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type)); 344 // Note: remaining fields in box ignored 345 if (hdlr_type == FOURCC_VIDE) { 346 type = kVideo; 347 } else if (hdlr_type == FOURCC_SOUN) { 348 type = kAudio; 349 } else { 350 type = kInvalid; 351 } 352 return true; 353 } 354 355 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() 356 : version(0), 357 profile_indication(0), 358 profile_compatibility(0), 359 avc_level(0), 360 length_size(0) {} 361 362 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {} 363 FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; } 364 365 bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) { 366 return ParseInternal(reader, reader->log_cb()); 367 } 368 369 bool AVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) { 370 BufferReader reader(data, data_size); 371 return ParseInternal(&reader, LogCB()); 372 } 373 374 bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader, 375 const LogCB& log_cb) { 376 RCHECK(reader->Read1(&version) && version == 1 && 377 reader->Read1(&profile_indication) && 378 reader->Read1(&profile_compatibility) && 379 reader->Read1(&avc_level)); 380 381 uint8 length_size_minus_one; 382 RCHECK(reader->Read1(&length_size_minus_one)); 383 length_size = (length_size_minus_one & 0x3) + 1; 384 385 RCHECK(length_size != 3); // Only values of 1, 2, and 4 are valid. 386 387 uint8 num_sps; 388 RCHECK(reader->Read1(&num_sps)); 389 num_sps &= 0x1f; 390 391 sps_list.resize(num_sps); 392 for (int i = 0; i < num_sps; i++) { 393 uint16 sps_length; 394 RCHECK(reader->Read2(&sps_length) && 395 reader->ReadVec(&sps_list[i], sps_length)); 396 RCHECK(sps_list[i].size() > 4); 397 398 if (!log_cb.is_null()) { 399 MEDIA_LOG(log_cb) << "Video codec: avc1." << std::hex 400 << static_cast<int>(sps_list[i][1]) 401 << static_cast<int>(sps_list[i][2]) 402 << static_cast<int>(sps_list[i][3]); 403 } 404 } 405 406 uint8 num_pps; 407 RCHECK(reader->Read1(&num_pps)); 408 409 pps_list.resize(num_pps); 410 for (int i = 0; i < num_pps; i++) { 411 uint16 pps_length; 412 RCHECK(reader->Read2(&pps_length) && 413 reader->ReadVec(&pps_list[i], pps_length)); 414 } 415 416 return true; 417 } 418 419 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {} 420 PixelAspectRatioBox::~PixelAspectRatioBox() {} 421 FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; } 422 423 bool PixelAspectRatioBox::Parse(BoxReader* reader) { 424 RCHECK(reader->Read4(&h_spacing) && 425 reader->Read4(&v_spacing)); 426 return true; 427 } 428 429 VideoSampleEntry::VideoSampleEntry() 430 : format(FOURCC_NULL), 431 data_reference_index(0), 432 width(0), 433 height(0) {} 434 435 VideoSampleEntry::~VideoSampleEntry() {} 436 FourCC VideoSampleEntry::BoxType() const { 437 DCHECK(false) << "VideoSampleEntry should be parsed according to the " 438 << "handler type recovered in its Media ancestor."; 439 return FOURCC_NULL; 440 } 441 442 bool VideoSampleEntry::Parse(BoxReader* reader) { 443 format = reader->type(); 444 RCHECK(reader->SkipBytes(6) && 445 reader->Read2(&data_reference_index) && 446 reader->SkipBytes(16) && 447 reader->Read2(&width) && 448 reader->Read2(&height) && 449 reader->SkipBytes(50)); 450 451 RCHECK(reader->ScanChildren() && 452 reader->MaybeReadChild(&pixel_aspect)); 453 454 if (format == FOURCC_ENCV) { 455 // Continue scanning until a recognized protection scheme is found, or until 456 // we run out of protection schemes. 457 while (sinf.type.type != FOURCC_CENC) { 458 if (!reader->ReadChild(&sinf)) 459 return false; 460 } 461 } 462 463 if (IsFormatValid()) 464 RCHECK(reader->ReadChild(&avcc)); 465 466 return true; 467 } 468 469 bool VideoSampleEntry::IsFormatValid() const { 470 return format == FOURCC_AVC1 || format == FOURCC_AVC3 || 471 (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 || 472 sinf.format.format == FOURCC_AVC3)); 473 } 474 475 ElementaryStreamDescriptor::ElementaryStreamDescriptor() 476 : object_type(kForbidden) {} 477 478 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {} 479 480 FourCC ElementaryStreamDescriptor::BoxType() const { 481 return FOURCC_ESDS; 482 } 483 484 bool ElementaryStreamDescriptor::Parse(BoxReader* reader) { 485 std::vector<uint8> data; 486 ESDescriptor es_desc; 487 488 RCHECK(reader->ReadFullBoxHeader()); 489 RCHECK(reader->ReadVec(&data, reader->size() - reader->pos())); 490 RCHECK(es_desc.Parse(data)); 491 492 object_type = es_desc.object_type(); 493 494 if (object_type != 0x40) { 495 MEDIA_LOG(reader->log_cb()) << "Audio codec: mp4a." 496 << std::hex << static_cast<int>(object_type); 497 } 498 499 if (es_desc.IsAAC(object_type)) 500 RCHECK(aac.Parse(es_desc.decoder_specific_info(), reader->log_cb())); 501 502 return true; 503 } 504 505 AudioSampleEntry::AudioSampleEntry() 506 : format(FOURCC_NULL), 507 data_reference_index(0), 508 channelcount(0), 509 samplesize(0), 510 samplerate(0) {} 511 512 AudioSampleEntry::~AudioSampleEntry() {} 513 514 FourCC AudioSampleEntry::BoxType() const { 515 DCHECK(false) << "AudioSampleEntry should be parsed according to the " 516 << "handler type recovered in its Media ancestor."; 517 return FOURCC_NULL; 518 } 519 520 bool AudioSampleEntry::Parse(BoxReader* reader) { 521 format = reader->type(); 522 RCHECK(reader->SkipBytes(6) && 523 reader->Read2(&data_reference_index) && 524 reader->SkipBytes(8) && 525 reader->Read2(&channelcount) && 526 reader->Read2(&samplesize) && 527 reader->SkipBytes(4) && 528 reader->Read4(&samplerate)); 529 // Convert from 16.16 fixed point to integer 530 samplerate >>= 16; 531 532 RCHECK(reader->ScanChildren()); 533 if (format == FOURCC_ENCA) { 534 // Continue scanning until a recognized protection scheme is found, or until 535 // we run out of protection schemes. 536 while (sinf.type.type != FOURCC_CENC) { 537 if (!reader->ReadChild(&sinf)) 538 return false; 539 } 540 } 541 542 // ESDS is not valid in case of EAC3. 543 RCHECK(reader->MaybeReadChild(&esds)); 544 return true; 545 } 546 547 MediaHeader::MediaHeader() 548 : creation_time(0), 549 modification_time(0), 550 timescale(0), 551 duration(0) {} 552 MediaHeader::~MediaHeader() {} 553 FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; } 554 555 bool MediaHeader::Parse(BoxReader* reader) { 556 RCHECK(reader->ReadFullBoxHeader()); 557 558 if (reader->version() == 1) { 559 RCHECK(reader->Read8(&creation_time) && 560 reader->Read8(&modification_time) && 561 reader->Read4(×cale) && 562 reader->Read8(&duration)); 563 } else { 564 RCHECK(reader->Read4Into8(&creation_time) && 565 reader->Read4Into8(&modification_time) && 566 reader->Read4(×cale) && 567 reader->Read4Into8(&duration)); 568 } 569 // Skip language information 570 return reader->SkipBytes(4); 571 } 572 573 MediaInformation::MediaInformation() {} 574 MediaInformation::~MediaInformation() {} 575 FourCC MediaInformation::BoxType() const { return FOURCC_MINF; } 576 577 bool MediaInformation::Parse(BoxReader* reader) { 578 return reader->ScanChildren() && 579 reader->ReadChild(&sample_table); 580 } 581 582 Media::Media() {} 583 Media::~Media() {} 584 FourCC Media::BoxType() const { return FOURCC_MDIA; } 585 586 bool Media::Parse(BoxReader* reader) { 587 RCHECK(reader->ScanChildren() && 588 reader->ReadChild(&header) && 589 reader->ReadChild(&handler)); 590 591 // Maddeningly, the HandlerReference box specifies how to parse the 592 // SampleDescription box, making the latter the only box (of those that we 593 // support) which cannot be parsed correctly on its own (or even with 594 // information from its strict ancestor tree). We thus copy the handler type 595 // to the sample description box *before* parsing it to provide this 596 // information while parsing. 597 information.sample_table.description.type = handler.type; 598 RCHECK(reader->ReadChild(&information)); 599 return true; 600 } 601 602 Track::Track() {} 603 Track::~Track() {} 604 FourCC Track::BoxType() const { return FOURCC_TRAK; } 605 606 bool Track::Parse(BoxReader* reader) { 607 RCHECK(reader->ScanChildren() && 608 reader->ReadChild(&header) && 609 reader->ReadChild(&media) && 610 reader->MaybeReadChild(&edit)); 611 return true; 612 } 613 614 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {} 615 MovieExtendsHeader::~MovieExtendsHeader() {} 616 FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; } 617 618 bool MovieExtendsHeader::Parse(BoxReader* reader) { 619 RCHECK(reader->ReadFullBoxHeader()); 620 if (reader->version() == 1) { 621 RCHECK(reader->Read8(&fragment_duration)); 622 } else { 623 RCHECK(reader->Read4Into8(&fragment_duration)); 624 } 625 return true; 626 } 627 628 TrackExtends::TrackExtends() 629 : track_id(0), 630 default_sample_description_index(0), 631 default_sample_duration(0), 632 default_sample_size(0), 633 default_sample_flags(0) {} 634 TrackExtends::~TrackExtends() {} 635 FourCC TrackExtends::BoxType() const { return FOURCC_TREX; } 636 637 bool TrackExtends::Parse(BoxReader* reader) { 638 RCHECK(reader->ReadFullBoxHeader() && 639 reader->Read4(&track_id) && 640 reader->Read4(&default_sample_description_index) && 641 reader->Read4(&default_sample_duration) && 642 reader->Read4(&default_sample_size) && 643 reader->Read4(&default_sample_flags)); 644 return true; 645 } 646 647 MovieExtends::MovieExtends() {} 648 MovieExtends::~MovieExtends() {} 649 FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; } 650 651 bool MovieExtends::Parse(BoxReader* reader) { 652 header.fragment_duration = 0; 653 return reader->ScanChildren() && 654 reader->MaybeReadChild(&header) && 655 reader->ReadChildren(&tracks); 656 } 657 658 Movie::Movie() : fragmented(false) {} 659 Movie::~Movie() {} 660 FourCC Movie::BoxType() const { return FOURCC_MOOV; } 661 662 bool Movie::Parse(BoxReader* reader) { 663 return reader->ScanChildren() && 664 reader->ReadChild(&header) && 665 reader->ReadChildren(&tracks) && 666 // Media Source specific: 'mvex' required 667 reader->ReadChild(&extends) && 668 reader->MaybeReadChildren(&pssh); 669 } 670 671 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {} 672 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {} 673 FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; } 674 675 bool TrackFragmentDecodeTime::Parse(BoxReader* reader) { 676 RCHECK(reader->ReadFullBoxHeader()); 677 if (reader->version() == 1) 678 return reader->Read8(&decode_time); 679 else 680 return reader->Read4Into8(&decode_time); 681 } 682 683 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {} 684 MovieFragmentHeader::~MovieFragmentHeader() {} 685 FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; } 686 687 bool MovieFragmentHeader::Parse(BoxReader* reader) { 688 return reader->SkipBytes(4) && reader->Read4(&sequence_number); 689 } 690 691 TrackFragmentHeader::TrackFragmentHeader() 692 : track_id(0), 693 sample_description_index(0), 694 default_sample_duration(0), 695 default_sample_size(0), 696 default_sample_flags(0), 697 has_default_sample_flags(false) {} 698 699 TrackFragmentHeader::~TrackFragmentHeader() {} 700 FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; } 701 702 bool TrackFragmentHeader::Parse(BoxReader* reader) { 703 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&track_id)); 704 705 // Media Source specific: reject tracks that set 'base-data-offset-present'. 706 // Although the Media Source requires that 'default-base-is-moof' (14496-12 707 // Amendment 2) be set, we omit this check as many otherwise-valid files in 708 // the wild don't set it. 709 // 710 // RCHECK((flags & 0x020000) && !(flags & 0x1)); 711 RCHECK(!(reader->flags() & 0x1)); 712 713 if (reader->flags() & 0x2) { 714 RCHECK(reader->Read4(&sample_description_index)); 715 } else { 716 sample_description_index = 0; 717 } 718 719 if (reader->flags() & 0x8) { 720 RCHECK(reader->Read4(&default_sample_duration)); 721 } else { 722 default_sample_duration = 0; 723 } 724 725 if (reader->flags() & 0x10) { 726 RCHECK(reader->Read4(&default_sample_size)); 727 } else { 728 default_sample_size = 0; 729 } 730 731 if (reader->flags() & 0x20) { 732 RCHECK(reader->Read4(&default_sample_flags)); 733 has_default_sample_flags = true; 734 } else { 735 has_default_sample_flags = false; 736 } 737 738 return true; 739 } 740 741 TrackFragmentRun::TrackFragmentRun() 742 : sample_count(0), data_offset(0) {} 743 TrackFragmentRun::~TrackFragmentRun() {} 744 FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; } 745 746 bool TrackFragmentRun::Parse(BoxReader* reader) { 747 RCHECK(reader->ReadFullBoxHeader() && 748 reader->Read4(&sample_count)); 749 const uint32 flags = reader->flags(); 750 751 bool data_offset_present = (flags & 0x1) != 0; 752 bool first_sample_flags_present = (flags & 0x4) != 0; 753 bool sample_duration_present = (flags & 0x100) != 0; 754 bool sample_size_present = (flags & 0x200) != 0; 755 bool sample_flags_present = (flags & 0x400) != 0; 756 bool sample_composition_time_offsets_present = (flags & 0x800) != 0; 757 758 if (data_offset_present) { 759 RCHECK(reader->Read4(&data_offset)); 760 } else { 761 data_offset = 0; 762 } 763 764 uint32 first_sample_flags; 765 if (first_sample_flags_present) 766 RCHECK(reader->Read4(&first_sample_flags)); 767 768 int fields = sample_duration_present + sample_size_present + 769 sample_flags_present + sample_composition_time_offsets_present; 770 RCHECK(reader->HasBytes(fields * sample_count)); 771 772 if (sample_duration_present) 773 sample_durations.resize(sample_count); 774 if (sample_size_present) 775 sample_sizes.resize(sample_count); 776 if (sample_flags_present) 777 sample_flags.resize(sample_count); 778 if (sample_composition_time_offsets_present) 779 sample_composition_time_offsets.resize(sample_count); 780 781 for (uint32 i = 0; i < sample_count; ++i) { 782 if (sample_duration_present) 783 RCHECK(reader->Read4(&sample_durations[i])); 784 if (sample_size_present) 785 RCHECK(reader->Read4(&sample_sizes[i])); 786 if (sample_flags_present) 787 RCHECK(reader->Read4(&sample_flags[i])); 788 if (sample_composition_time_offsets_present) 789 RCHECK(reader->Read4s(&sample_composition_time_offsets[i])); 790 } 791 792 if (first_sample_flags_present) { 793 if (sample_flags.size() == 0) { 794 sample_flags.push_back(first_sample_flags); 795 } else { 796 sample_flags[0] = first_sample_flags; 797 } 798 } 799 return true; 800 } 801 802 SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {} 803 SampleToGroup::~SampleToGroup() {} 804 FourCC SampleToGroup::BoxType() const { return FOURCC_SBGP; } 805 806 bool SampleToGroup::Parse(BoxReader* reader) { 807 RCHECK(reader->ReadFullBoxHeader() && 808 reader->Read4(&grouping_type)); 809 810 if (reader->version() == 1) 811 RCHECK(reader->Read4(&grouping_type_parameter)); 812 813 if (grouping_type != FOURCC_SEIG) { 814 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type 815 << "' is not supported."; 816 return true; 817 } 818 819 uint32 count; 820 RCHECK(reader->Read4(&count)); 821 entries.resize(count); 822 for (uint32 i = 0; i < count; ++i) { 823 RCHECK(reader->Read4(&entries[i].sample_count) && 824 reader->Read4(&entries[i].group_description_index)); 825 } 826 return true; 827 } 828 829 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() 830 : is_encrypted(false), iv_size(0) {} 831 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {} 832 833 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {} 834 SampleGroupDescription::~SampleGroupDescription() {} 835 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; } 836 837 bool SampleGroupDescription::Parse(BoxReader* reader) { 838 RCHECK(reader->ReadFullBoxHeader() && 839 reader->Read4(&grouping_type)); 840 841 if (grouping_type != FOURCC_SEIG) { 842 DLOG(WARNING) << "SampleGroupDescription box with grouping_type '" 843 << grouping_type << "' is not supported."; 844 return true; 845 } 846 847 const uint8 version = reader->version(); 848 849 const size_t kKeyIdSize = 16; 850 const size_t kEntrySize = sizeof(uint32) + kKeyIdSize; 851 uint32 default_length = 0; 852 if (version == 1) { 853 RCHECK(reader->Read4(&default_length)); 854 RCHECK(default_length == 0 || default_length >= kEntrySize); 855 } 856 857 uint32 count; 858 RCHECK(reader->Read4(&count)); 859 entries.resize(count); 860 for (uint32 i = 0; i < count; ++i) { 861 if (version == 1) { 862 if (default_length == 0) { 863 uint32 description_length = 0; 864 RCHECK(reader->Read4(&description_length)); 865 RCHECK(description_length >= kEntrySize); 866 } 867 } 868 869 uint8 flag; 870 RCHECK(reader->SkipBytes(2) && // reserved. 871 reader->Read1(&flag) && 872 reader->Read1(&entries[i].iv_size) && 873 reader->ReadVec(&entries[i].key_id, kKeyIdSize)); 874 875 entries[i].is_encrypted = (flag != 0); 876 if (entries[i].is_encrypted) { 877 RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16); 878 } else { 879 RCHECK(entries[i].iv_size == 0); 880 } 881 } 882 return true; 883 } 884 885 TrackFragment::TrackFragment() {} 886 TrackFragment::~TrackFragment() {} 887 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; } 888 889 bool TrackFragment::Parse(BoxReader* reader) { 890 RCHECK(reader->ScanChildren() && 891 reader->ReadChild(&header) && 892 // Media Source specific: 'tfdt' required 893 reader->ReadChild(&decode_time) && 894 reader->MaybeReadChildren(&runs) && 895 reader->MaybeReadChild(&auxiliary_offset) && 896 reader->MaybeReadChild(&auxiliary_size) && 897 reader->MaybeReadChild(&sdtp)); 898 899 // There could be multiple SampleGroupDescription and SampleToGroup boxes with 900 // different grouping types. For common encryption, the relevant grouping type 901 // is 'seig'. Continue reading until 'seig' is found, or until running out of 902 // child boxes. 903 while (sample_group_description.grouping_type != FOURCC_SEIG && 904 reader->HasChild(&sample_group_description)) { 905 RCHECK(reader->ReadChild(&sample_group_description)); 906 } 907 while (sample_to_group.grouping_type != FOURCC_SEIG && 908 reader->HasChild(&sample_to_group)) { 909 RCHECK(reader->ReadChild(&sample_to_group)); 910 } 911 return true; 912 } 913 914 MovieFragment::MovieFragment() {} 915 MovieFragment::~MovieFragment() {} 916 FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; } 917 918 bool MovieFragment::Parse(BoxReader* reader) { 919 RCHECK(reader->ScanChildren() && 920 reader->ReadChild(&header) && 921 reader->ReadChildren(&tracks) && 922 reader->MaybeReadChildren(&pssh)); 923 return true; 924 } 925 926 IndependentAndDisposableSamples::IndependentAndDisposableSamples() {} 927 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} 928 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } 929 930 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { 931 RCHECK(reader->ReadFullBoxHeader()); 932 RCHECK(reader->version() == 0); 933 RCHECK(reader->flags() == 0); 934 935 int sample_count = reader->size() - reader->pos(); 936 sample_depends_on_.resize(sample_count); 937 for (int i = 0; i < sample_count; ++i) { 938 uint8 sample_info; 939 RCHECK(reader->Read1(&sample_info)); 940 941 sample_depends_on_[i] = 942 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); 943 944 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); 945 } 946 947 return true; 948 } 949 950 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 951 size_t i) const { 952 if (i >= sample_depends_on_.size()) 953 return kSampleDependsOnUnknown; 954 955 return sample_depends_on_[i]; 956 } 957 958 } // namespace mp4 959 } // namespace media 960