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 "media/mp4/box_definitions.h" 6 7 #include "base/logging.h" 8 #include "media/mp4/es_descriptor.h" 9 #include "media/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 SampleTable::SampleTable() {} 249 SampleTable::~SampleTable() {} 250 FourCC SampleTable::BoxType() const { return FOURCC_STBL; } 251 252 bool SampleTable::Parse(BoxReader* reader) { 253 return reader->ScanChildren() && 254 reader->ReadChild(&description); 255 } 256 257 EditList::EditList() {} 258 EditList::~EditList() {} 259 FourCC EditList::BoxType() const { return FOURCC_ELST; } 260 261 bool EditList::Parse(BoxReader* reader) { 262 uint32 count; 263 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); 264 265 if (reader->version() == 1) { 266 RCHECK(reader->HasBytes(count * 20)); 267 } else { 268 RCHECK(reader->HasBytes(count * 12)); 269 } 270 edits.resize(count); 271 272 for (std::vector<EditListEntry>::iterator edit = edits.begin(); 273 edit != edits.end(); ++edit) { 274 if (reader->version() == 1) { 275 RCHECK(reader->Read8(&edit->segment_duration) && 276 reader->Read8s(&edit->media_time)); 277 } else { 278 RCHECK(reader->Read4Into8(&edit->segment_duration) && 279 reader->Read4sInto8s(&edit->media_time)); 280 } 281 RCHECK(reader->Read2s(&edit->media_rate_integer) && 282 reader->Read2s(&edit->media_rate_fraction)); 283 } 284 return true; 285 } 286 287 Edit::Edit() {} 288 Edit::~Edit() {} 289 FourCC Edit::BoxType() const { return FOURCC_EDTS; } 290 291 bool Edit::Parse(BoxReader* reader) { 292 return reader->ScanChildren() && reader->ReadChild(&list); 293 } 294 295 HandlerReference::HandlerReference() : type(kInvalid) {} 296 HandlerReference::~HandlerReference() {} 297 FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; } 298 299 bool HandlerReference::Parse(BoxReader* reader) { 300 FourCC hdlr_type; 301 RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type)); 302 // Note: remaining fields in box ignored 303 if (hdlr_type == FOURCC_VIDE) { 304 type = kVideo; 305 } else if (hdlr_type == FOURCC_SOUN) { 306 type = kAudio; 307 } else { 308 type = kInvalid; 309 } 310 return true; 311 } 312 313 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() 314 : version(0), 315 profile_indication(0), 316 profile_compatibility(0), 317 avc_level(0), 318 length_size(0) {} 319 320 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {} 321 FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; } 322 323 bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) { 324 RCHECK(reader->Read1(&version) && version == 1 && 325 reader->Read1(&profile_indication) && 326 reader->Read1(&profile_compatibility) && 327 reader->Read1(&avc_level)); 328 329 uint8 length_size_minus_one; 330 RCHECK(reader->Read1(&length_size_minus_one) && 331 (length_size_minus_one & 0xfc) == 0xfc); 332 length_size = (length_size_minus_one & 0x3) + 1; 333 334 uint8 num_sps; 335 RCHECK(reader->Read1(&num_sps) && (num_sps & 0xe0) == 0xe0); 336 num_sps &= 0x1f; 337 338 sps_list.resize(num_sps); 339 for (int i = 0; i < num_sps; i++) { 340 uint16 sps_length; 341 RCHECK(reader->Read2(&sps_length) && 342 reader->ReadVec(&sps_list[i], sps_length)); 343 } 344 345 uint8 num_pps; 346 RCHECK(reader->Read1(&num_pps)); 347 348 pps_list.resize(num_pps); 349 for (int i = 0; i < num_pps; i++) { 350 uint16 pps_length; 351 RCHECK(reader->Read2(&pps_length) && 352 reader->ReadVec(&pps_list[i], pps_length)); 353 } 354 355 return true; 356 } 357 358 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {} 359 PixelAspectRatioBox::~PixelAspectRatioBox() {} 360 FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; } 361 362 bool PixelAspectRatioBox::Parse(BoxReader* reader) { 363 RCHECK(reader->Read4(&h_spacing) && 364 reader->Read4(&v_spacing)); 365 return true; 366 } 367 368 VideoSampleEntry::VideoSampleEntry() 369 : format(FOURCC_NULL), 370 data_reference_index(0), 371 width(0), 372 height(0) {} 373 374 VideoSampleEntry::~VideoSampleEntry() {} 375 FourCC VideoSampleEntry::BoxType() const { 376 DCHECK(false) << "VideoSampleEntry should be parsed according to the " 377 << "handler type recovered in its Media ancestor."; 378 return FOURCC_NULL; 379 } 380 381 bool VideoSampleEntry::Parse(BoxReader* reader) { 382 format = reader->type(); 383 RCHECK(reader->SkipBytes(6) && 384 reader->Read2(&data_reference_index) && 385 reader->SkipBytes(16) && 386 reader->Read2(&width) && 387 reader->Read2(&height) && 388 reader->SkipBytes(50)); 389 390 RCHECK(reader->ScanChildren() && 391 reader->MaybeReadChild(&pixel_aspect)); 392 393 if (format == FOURCC_ENCV) { 394 // Continue scanning until a recognized protection scheme is found, or until 395 // we run out of protection schemes. 396 while (sinf.type.type != FOURCC_CENC) { 397 if (!reader->ReadChild(&sinf)) 398 return false; 399 } 400 } 401 402 if (IsFormatValid()) 403 RCHECK(reader->ReadChild(&avcc)); 404 405 return true; 406 } 407 408 bool VideoSampleEntry::IsFormatValid() const { 409 return format == FOURCC_AVC1 || format == FOURCC_AVC3 || 410 (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 || 411 sinf.format.format == FOURCC_AVC3)); 412 } 413 414 ElementaryStreamDescriptor::ElementaryStreamDescriptor() 415 : object_type(kForbidden) {} 416 417 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {} 418 419 FourCC ElementaryStreamDescriptor::BoxType() const { 420 return FOURCC_ESDS; 421 } 422 423 bool ElementaryStreamDescriptor::Parse(BoxReader* reader) { 424 std::vector<uint8> data; 425 ESDescriptor es_desc; 426 427 RCHECK(reader->ReadFullBoxHeader()); 428 RCHECK(reader->ReadVec(&data, reader->size() - reader->pos())); 429 RCHECK(es_desc.Parse(data)); 430 431 object_type = es_desc.object_type(); 432 433 RCHECK(aac.Parse(es_desc.decoder_specific_info())); 434 435 return true; 436 } 437 438 AudioSampleEntry::AudioSampleEntry() 439 : format(FOURCC_NULL), 440 data_reference_index(0), 441 channelcount(0), 442 samplesize(0), 443 samplerate(0) {} 444 445 AudioSampleEntry::~AudioSampleEntry() {} 446 447 FourCC AudioSampleEntry::BoxType() const { 448 DCHECK(false) << "AudioSampleEntry should be parsed according to the " 449 << "handler type recovered in its Media ancestor."; 450 return FOURCC_NULL; 451 } 452 453 bool AudioSampleEntry::Parse(BoxReader* reader) { 454 format = reader->type(); 455 RCHECK(reader->SkipBytes(6) && 456 reader->Read2(&data_reference_index) && 457 reader->SkipBytes(8) && 458 reader->Read2(&channelcount) && 459 reader->Read2(&samplesize) && 460 reader->SkipBytes(4) && 461 reader->Read4(&samplerate)); 462 // Convert from 16.16 fixed point to integer 463 samplerate >>= 16; 464 465 RCHECK(reader->ScanChildren()); 466 if (format == FOURCC_ENCA) { 467 // Continue scanning until a recognized protection scheme is found, or until 468 // we run out of protection schemes. 469 while (sinf.type.type != FOURCC_CENC) { 470 if (!reader->ReadChild(&sinf)) 471 return false; 472 } 473 } 474 475 // ESDS is not valid in case of EAC3. 476 RCHECK(reader->MaybeReadChild(&esds)); 477 return true; 478 } 479 480 MediaHeader::MediaHeader() 481 : creation_time(0), 482 modification_time(0), 483 timescale(0), 484 duration(0) {} 485 MediaHeader::~MediaHeader() {} 486 FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; } 487 488 bool MediaHeader::Parse(BoxReader* reader) { 489 RCHECK(reader->ReadFullBoxHeader()); 490 491 if (reader->version() == 1) { 492 RCHECK(reader->Read8(&creation_time) && 493 reader->Read8(&modification_time) && 494 reader->Read4(×cale) && 495 reader->Read8(&duration)); 496 } else { 497 RCHECK(reader->Read4Into8(&creation_time) && 498 reader->Read4Into8(&modification_time) && 499 reader->Read4(×cale) && 500 reader->Read4Into8(&duration)); 501 } 502 // Skip language information 503 return reader->SkipBytes(4); 504 } 505 506 MediaInformation::MediaInformation() {} 507 MediaInformation::~MediaInformation() {} 508 FourCC MediaInformation::BoxType() const { return FOURCC_MINF; } 509 510 bool MediaInformation::Parse(BoxReader* reader) { 511 return reader->ScanChildren() && 512 reader->ReadChild(&sample_table); 513 } 514 515 Media::Media() {} 516 Media::~Media() {} 517 FourCC Media::BoxType() const { return FOURCC_MDIA; } 518 519 bool Media::Parse(BoxReader* reader) { 520 RCHECK(reader->ScanChildren() && 521 reader->ReadChild(&header) && 522 reader->ReadChild(&handler)); 523 524 // Maddeningly, the HandlerReference box specifies how to parse the 525 // SampleDescription box, making the latter the only box (of those that we 526 // support) which cannot be parsed correctly on its own (or even with 527 // information from its strict ancestor tree). We thus copy the handler type 528 // to the sample description box *before* parsing it to provide this 529 // information while parsing. 530 information.sample_table.description.type = handler.type; 531 RCHECK(reader->ReadChild(&information)); 532 return true; 533 } 534 535 Track::Track() {} 536 Track::~Track() {} 537 FourCC Track::BoxType() const { return FOURCC_TRAK; } 538 539 bool Track::Parse(BoxReader* reader) { 540 RCHECK(reader->ScanChildren() && 541 reader->ReadChild(&header) && 542 reader->ReadChild(&media) && 543 reader->MaybeReadChild(&edit)); 544 return true; 545 } 546 547 MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {} 548 MovieExtendsHeader::~MovieExtendsHeader() {} 549 FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; } 550 551 bool MovieExtendsHeader::Parse(BoxReader* reader) { 552 RCHECK(reader->ReadFullBoxHeader()); 553 if (reader->version() == 1) { 554 RCHECK(reader->Read8(&fragment_duration)); 555 } else { 556 RCHECK(reader->Read4Into8(&fragment_duration)); 557 } 558 return true; 559 } 560 561 TrackExtends::TrackExtends() 562 : track_id(0), 563 default_sample_description_index(0), 564 default_sample_duration(0), 565 default_sample_size(0), 566 default_sample_flags(0) {} 567 TrackExtends::~TrackExtends() {} 568 FourCC TrackExtends::BoxType() const { return FOURCC_TREX; } 569 570 bool TrackExtends::Parse(BoxReader* reader) { 571 RCHECK(reader->ReadFullBoxHeader() && 572 reader->Read4(&track_id) && 573 reader->Read4(&default_sample_description_index) && 574 reader->Read4(&default_sample_duration) && 575 reader->Read4(&default_sample_size) && 576 reader->Read4(&default_sample_flags)); 577 return true; 578 } 579 580 MovieExtends::MovieExtends() {} 581 MovieExtends::~MovieExtends() {} 582 FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; } 583 584 bool MovieExtends::Parse(BoxReader* reader) { 585 header.fragment_duration = 0; 586 return reader->ScanChildren() && 587 reader->MaybeReadChild(&header) && 588 reader->ReadChildren(&tracks); 589 } 590 591 Movie::Movie() : fragmented(false) {} 592 Movie::~Movie() {} 593 FourCC Movie::BoxType() const { return FOURCC_MOOV; } 594 595 bool Movie::Parse(BoxReader* reader) { 596 return reader->ScanChildren() && 597 reader->ReadChild(&header) && 598 reader->ReadChildren(&tracks) && 599 // Media Source specific: 'mvex' required 600 reader->ReadChild(&extends) && 601 reader->MaybeReadChildren(&pssh); 602 } 603 604 TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {} 605 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {} 606 FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; } 607 608 bool TrackFragmentDecodeTime::Parse(BoxReader* reader) { 609 RCHECK(reader->ReadFullBoxHeader()); 610 if (reader->version() == 1) 611 return reader->Read8(&decode_time); 612 else 613 return reader->Read4Into8(&decode_time); 614 } 615 616 MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {} 617 MovieFragmentHeader::~MovieFragmentHeader() {} 618 FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; } 619 620 bool MovieFragmentHeader::Parse(BoxReader* reader) { 621 return reader->SkipBytes(4) && reader->Read4(&sequence_number); 622 } 623 624 TrackFragmentHeader::TrackFragmentHeader() 625 : track_id(0), 626 sample_description_index(0), 627 default_sample_duration(0), 628 default_sample_size(0), 629 default_sample_flags(0), 630 has_default_sample_flags(false) {} 631 632 TrackFragmentHeader::~TrackFragmentHeader() {} 633 FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; } 634 635 bool TrackFragmentHeader::Parse(BoxReader* reader) { 636 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&track_id)); 637 638 // Media Source specific: reject tracks that set 'base-data-offset-present'. 639 // Although the Media Source requires that 'default-base-is-moof' (14496-12 640 // Amendment 2) be set, we omit this check as many otherwise-valid files in 641 // the wild don't set it. 642 // 643 // RCHECK((flags & 0x020000) && !(flags & 0x1)); 644 RCHECK(!(reader->flags() & 0x1)); 645 646 if (reader->flags() & 0x2) { 647 RCHECK(reader->Read4(&sample_description_index)); 648 } else { 649 sample_description_index = 0; 650 } 651 652 if (reader->flags() & 0x8) { 653 RCHECK(reader->Read4(&default_sample_duration)); 654 } else { 655 default_sample_duration = 0; 656 } 657 658 if (reader->flags() & 0x10) { 659 RCHECK(reader->Read4(&default_sample_size)); 660 } else { 661 default_sample_size = 0; 662 } 663 664 if (reader->flags() & 0x20) { 665 RCHECK(reader->Read4(&default_sample_flags)); 666 has_default_sample_flags = true; 667 } else { 668 has_default_sample_flags = false; 669 } 670 671 return true; 672 } 673 674 TrackFragmentRun::TrackFragmentRun() 675 : sample_count(0), data_offset(0) {} 676 TrackFragmentRun::~TrackFragmentRun() {} 677 FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; } 678 679 bool TrackFragmentRun::Parse(BoxReader* reader) { 680 RCHECK(reader->ReadFullBoxHeader() && 681 reader->Read4(&sample_count)); 682 const uint32 flags = reader->flags(); 683 684 bool data_offset_present = (flags & 0x1) != 0; 685 bool first_sample_flags_present = (flags & 0x4) != 0; 686 bool sample_duration_present = (flags & 0x100) != 0; 687 bool sample_size_present = (flags & 0x200) != 0; 688 bool sample_flags_present = (flags & 0x400) != 0; 689 bool sample_composition_time_offsets_present = (flags & 0x800) != 0; 690 691 if (data_offset_present) { 692 RCHECK(reader->Read4(&data_offset)); 693 } else { 694 data_offset = 0; 695 } 696 697 uint32 first_sample_flags; 698 if (first_sample_flags_present) 699 RCHECK(reader->Read4(&first_sample_flags)); 700 701 int fields = sample_duration_present + sample_size_present + 702 sample_flags_present + sample_composition_time_offsets_present; 703 RCHECK(reader->HasBytes(fields * sample_count)); 704 705 if (sample_duration_present) 706 sample_durations.resize(sample_count); 707 if (sample_size_present) 708 sample_sizes.resize(sample_count); 709 if (sample_flags_present) 710 sample_flags.resize(sample_count); 711 if (sample_composition_time_offsets_present) 712 sample_composition_time_offsets.resize(sample_count); 713 714 for (uint32 i = 0; i < sample_count; ++i) { 715 if (sample_duration_present) 716 RCHECK(reader->Read4(&sample_durations[i])); 717 if (sample_size_present) 718 RCHECK(reader->Read4(&sample_sizes[i])); 719 if (sample_flags_present) 720 RCHECK(reader->Read4(&sample_flags[i])); 721 if (sample_composition_time_offsets_present) 722 RCHECK(reader->Read4s(&sample_composition_time_offsets[i])); 723 } 724 725 if (first_sample_flags_present) { 726 if (sample_flags.size() == 0) { 727 sample_flags.push_back(first_sample_flags); 728 } else { 729 sample_flags[0] = first_sample_flags; 730 } 731 } 732 return true; 733 } 734 735 TrackFragment::TrackFragment() {} 736 TrackFragment::~TrackFragment() {} 737 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; } 738 739 bool TrackFragment::Parse(BoxReader* reader) { 740 return reader->ScanChildren() && 741 reader->ReadChild(&header) && 742 // Media Source specific: 'tfdt' required 743 reader->ReadChild(&decode_time) && 744 reader->MaybeReadChildren(&runs) && 745 reader->MaybeReadChild(&auxiliary_offset) && 746 reader->MaybeReadChild(&auxiliary_size) && 747 reader->MaybeReadChild(&sdtp); 748 } 749 750 MovieFragment::MovieFragment() {} 751 MovieFragment::~MovieFragment() {} 752 FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; } 753 754 bool MovieFragment::Parse(BoxReader* reader) { 755 RCHECK(reader->ScanChildren() && 756 reader->ReadChild(&header) && 757 reader->ReadChildren(&tracks) && 758 reader->MaybeReadChildren(&pssh)); 759 return true; 760 } 761 762 IndependentAndDisposableSamples::IndependentAndDisposableSamples() {} 763 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} 764 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } 765 766 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { 767 RCHECK(reader->ReadFullBoxHeader()); 768 RCHECK(reader->version() == 0); 769 RCHECK(reader->flags() == 0); 770 771 int sample_count = reader->size() - reader->pos(); 772 sample_depends_on_.resize(sample_count); 773 for (int i = 0; i < sample_count; ++i) { 774 uint8 sample_info; 775 RCHECK(reader->Read1(&sample_info)); 776 RCHECK((sample_info >> 6) == 0); // reserved. 777 778 sample_depends_on_[i] = 779 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); 780 781 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); 782 } 783 784 return true; 785 } 786 787 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 788 size_t i) const { 789 if (i >= sample_depends_on_.size()) 790 return kSampleDependsOnUnknown; 791 792 return sample_depends_on_[i]; 793 } 794 795 } // namespace mp4 796 } // namespace media 797