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