OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mp4/box_definitions.h" | 5 #include "media/formats/mp4/box_definitions.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/base/video_types.h" |
| 9 #include "media/base/video_util.h" |
| 10 #include "media/formats/mp4/avc.h" |
8 #include "media/formats/mp4/es_descriptor.h" | 11 #include "media/formats/mp4/es_descriptor.h" |
9 #include "media/formats/mp4/rcheck.h" | 12 #include "media/formats/mp4/rcheck.h" |
10 | 13 |
| 14 #if defined(ENABLE_HEVC_DEMUXING) |
| 15 #include "media/formats/mp4/hevc.h" |
| 16 #endif |
| 17 |
11 namespace media { | 18 namespace media { |
12 namespace mp4 { | 19 namespace mp4 { |
13 | 20 |
14 FileType::FileType() {} | 21 FileType::FileType() {} |
15 FileType::~FileType() {} | 22 FileType::~FileType() {} |
16 FourCC FileType::BoxType() const { return FOURCC_FTYP; } | 23 FourCC FileType::BoxType() const { return FOURCC_FTYP; } |
17 | 24 |
18 bool FileType::Parse(BoxReader* reader) { | 25 bool FileType::Parse(BoxReader* reader) { |
19 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); | 26 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); |
20 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); | 27 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 pps_list.resize(num_pps); | 441 pps_list.resize(num_pps); |
435 for (int i = 0; i < num_pps; i++) { | 442 for (int i = 0; i < num_pps; i++) { |
436 uint16 pps_length; | 443 uint16 pps_length; |
437 RCHECK(reader->Read2(&pps_length) && | 444 RCHECK(reader->Read2(&pps_length) && |
438 reader->ReadVec(&pps_list[i], pps_length)); | 445 reader->ReadVec(&pps_list[i], pps_length)); |
439 } | 446 } |
440 | 447 |
441 return true; | 448 return true; |
442 } | 449 } |
443 | 450 |
| 451 #if defined(ENABLE_HEVC_DEMUXING) |
| 452 HEVCDecoderConfigurationRecord::HEVCDecoderConfigurationRecord() |
| 453 : configurationVersion(0), |
| 454 general_profile_space(0), |
| 455 general_tier_flag(0), |
| 456 general_profile_idc(0), |
| 457 general_profile_compatibility_flags(0), |
| 458 general_constraint_indicator_flags(0), |
| 459 general_level_idc(0), |
| 460 min_spatial_segmentation_idc(0), |
| 461 parallelismType(0), |
| 462 chromaFormat(0), |
| 463 bitDepthLumaMinus8(0), |
| 464 bitDepthChromaMinus8(0), |
| 465 avgFrameRate(0), |
| 466 constantFrameRate(0), |
| 467 numTemporalLayers(0), |
| 468 temporalIdNested(0), |
| 469 lengthSizeMinusOne(0), |
| 470 numOfArrays(0) {} |
| 471 |
| 472 HEVCDecoderConfigurationRecord::~HEVCDecoderConfigurationRecord() {} |
| 473 FourCC HEVCDecoderConfigurationRecord::BoxType() const { return FOURCC_HVCC; } |
| 474 |
| 475 bool HEVCDecoderConfigurationRecord::Parse(BoxReader* reader) { |
| 476 return ParseInternal(reader, reader->media_log()); |
| 477 } |
| 478 |
| 479 bool HEVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) { |
| 480 BufferReader reader(data, data_size); |
| 481 return ParseInternal(&reader, new MediaLog()); |
| 482 } |
| 483 |
| 484 HEVCDecoderConfigurationRecord::HVCCNALArray::HVCCNALArray() |
| 485 : first_byte(0) {} |
| 486 |
| 487 HEVCDecoderConfigurationRecord::HVCCNALArray::~HVCCNALArray() {} |
| 488 |
| 489 bool HEVCDecoderConfigurationRecord::ParseInternal( |
| 490 BufferReader* reader, |
| 491 const scoped_refptr<MediaLog>& media_log) { |
| 492 uint8 profile_indication = 0; |
| 493 uint32 general_constraint_indicator_flags_hi = 0; |
| 494 uint16 general_constraint_indicator_flags_lo = 0; |
| 495 uint8 misc = 0; |
| 496 RCHECK(reader->Read1(&configurationVersion) && configurationVersion == 1 && |
| 497 reader->Read1(&profile_indication) && |
| 498 reader->Read4(&general_profile_compatibility_flags) && |
| 499 reader->Read4(&general_constraint_indicator_flags_hi) && |
| 500 reader->Read2(&general_constraint_indicator_flags_lo) && |
| 501 reader->Read1(&general_level_idc) && |
| 502 reader->Read2(&min_spatial_segmentation_idc) && |
| 503 reader->Read1(¶llelismType) && |
| 504 reader->Read1(&chromaFormat) && |
| 505 reader->Read1(&bitDepthLumaMinus8) && |
| 506 reader->Read1(&bitDepthChromaMinus8) && |
| 507 reader->Read2(&avgFrameRate) && |
| 508 reader->Read1(&misc) && |
| 509 reader->Read1(&numOfArrays)); |
| 510 |
| 511 general_profile_space = profile_indication >> 6; |
| 512 general_tier_flag = (profile_indication >> 5) & 1; |
| 513 general_profile_idc = profile_indication & 0x1f; |
| 514 |
| 515 general_constraint_indicator_flags = general_constraint_indicator_flags_hi; |
| 516 general_constraint_indicator_flags <<= 16; |
| 517 general_constraint_indicator_flags |= general_constraint_indicator_flags_lo; |
| 518 |
| 519 min_spatial_segmentation_idc &= 0xfff; |
| 520 parallelismType &= 3; |
| 521 chromaFormat &= 3; |
| 522 bitDepthLumaMinus8 &= 7; |
| 523 bitDepthChromaMinus8 &= 7; |
| 524 |
| 525 constantFrameRate = misc >> 6; |
| 526 numTemporalLayers = (misc >> 3) & 7; |
| 527 temporalIdNested = (misc >> 2) & 1; |
| 528 lengthSizeMinusOne = misc & 3; |
| 529 |
| 530 DVLOG(2) << __FUNCTION__ << " numOfArrays=" << (int)numOfArrays; |
| 531 arrays.resize(numOfArrays); |
| 532 for (uint32 j = 0; j < numOfArrays; j++) { |
| 533 RCHECK(reader->Read1(&arrays[j].first_byte)); |
| 534 uint16 numNalus = 0; |
| 535 RCHECK(reader->Read2(&numNalus)); |
| 536 arrays[j].units.resize(numNalus); |
| 537 for (uint32 i = 0; i < numNalus; ++i) { |
| 538 uint16 naluLength = 0; |
| 539 RCHECK(reader->Read2(&naluLength) && |
| 540 reader->ReadVec(&arrays[j].units[i], naluLength)); |
| 541 DVLOG(4) << __FUNCTION__ << " naluType=" |
| 542 << (int)(arrays[j].first_byte & 0x3f) |
| 543 << " size=" << arrays[j].units[i].size(); |
| 544 } |
| 545 } |
| 546 |
| 547 if (media_log.get()) { |
| 548 MEDIA_LOG(INFO, media_log) << "Video codec: hevc"; |
| 549 } |
| 550 |
| 551 return true; |
| 552 } |
| 553 #endif |
| 554 |
444 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {} | 555 PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {} |
445 PixelAspectRatioBox::~PixelAspectRatioBox() {} | 556 PixelAspectRatioBox::~PixelAspectRatioBox() {} |
446 FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; } | 557 FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; } |
447 | 558 |
448 bool PixelAspectRatioBox::Parse(BoxReader* reader) { | 559 bool PixelAspectRatioBox::Parse(BoxReader* reader) { |
449 RCHECK(reader->Read4(&h_spacing) && | 560 RCHECK(reader->Read4(&h_spacing) && |
450 reader->Read4(&v_spacing)); | 561 reader->Read4(&v_spacing)); |
451 return true; | 562 return true; |
452 } | 563 } |
453 | 564 |
454 VideoSampleEntry::VideoSampleEntry() | 565 VideoSampleEntry::VideoSampleEntry() |
455 : format(FOURCC_NULL), | 566 : format(FOURCC_NULL), |
456 data_reference_index(0), | 567 data_reference_index(0), |
457 width(0), | 568 width(0), |
458 height(0) {} | 569 height(0), |
| 570 video_codec(kUnknownVideoCodec), |
| 571 video_codec_profile(VIDEO_CODEC_PROFILE_UNKNOWN) {} |
459 | 572 |
460 VideoSampleEntry::~VideoSampleEntry() {} | 573 VideoSampleEntry::~VideoSampleEntry() {} |
461 FourCC VideoSampleEntry::BoxType() const { | 574 FourCC VideoSampleEntry::BoxType() const { |
462 DCHECK(false) << "VideoSampleEntry should be parsed according to the " | 575 DCHECK(false) << "VideoSampleEntry should be parsed according to the " |
463 << "handler type recovered in its Media ancestor."; | 576 << "handler type recovered in its Media ancestor."; |
464 return FOURCC_NULL; | 577 return FOURCC_NULL; |
465 } | 578 } |
466 | 579 |
| 580 namespace { |
| 581 |
| 582 bool IsFormatValidH264(const FourCC& format, |
| 583 const ProtectionSchemeInfo& sinf) { |
| 584 return format == FOURCC_AVC1 || format == FOURCC_AVC3 || |
| 585 (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 || |
| 586 sinf.format.format == FOURCC_AVC3)); |
| 587 } |
| 588 |
| 589 #if defined(ENABLE_HEVC_DEMUXING) |
| 590 bool IsFormatValidHEVC(const FourCC& format, |
| 591 const ProtectionSchemeInfo& sinf) { |
| 592 return format == FOURCC_HEV1 || format == FOURCC_HVC1 || |
| 593 (format == FOURCC_ENCV && (sinf.format.format == FOURCC_HEV1 || |
| 594 sinf.format.format == FOURCC_HVC1)); |
| 595 } |
| 596 #endif |
| 597 |
| 598 } |
| 599 |
467 bool VideoSampleEntry::Parse(BoxReader* reader) { | 600 bool VideoSampleEntry::Parse(BoxReader* reader) { |
468 format = reader->type(); | 601 format = reader->type(); |
469 RCHECK(reader->SkipBytes(6) && | 602 RCHECK(reader->SkipBytes(6) && |
470 reader->Read2(&data_reference_index) && | 603 reader->Read2(&data_reference_index) && |
471 reader->SkipBytes(16) && | 604 reader->SkipBytes(16) && |
472 reader->Read2(&width) && | 605 reader->Read2(&width) && |
473 reader->Read2(&height) && | 606 reader->Read2(&height) && |
474 reader->SkipBytes(50)); | 607 reader->SkipBytes(50)); |
475 | 608 |
476 RCHECK(reader->ScanChildren() && | 609 RCHECK(reader->ScanChildren() && |
477 reader->MaybeReadChild(&pixel_aspect)); | 610 reader->MaybeReadChild(&pixel_aspect)); |
478 | 611 |
479 if (format == FOURCC_ENCV) { | 612 if (format == FOURCC_ENCV) { |
480 // Continue scanning until a recognized protection scheme is found, or until | 613 // Continue scanning until a recognized protection scheme is found, or until |
481 // we run out of protection schemes. | 614 // we run out of protection schemes. |
482 while (sinf.type.type != FOURCC_CENC) { | 615 while (sinf.type.type != FOURCC_CENC) { |
483 if (!reader->ReadChild(&sinf)) | 616 if (!reader->ReadChild(&sinf)) |
484 return false; | 617 return false; |
485 } | 618 } |
486 } | 619 } |
487 | 620 |
488 if (IsFormatValid()) { | 621 if (IsFormatValidH264(format, sinf)) { |
| 622 DVLOG(2) << __FUNCTION__ |
| 623 << " reading AVCDecoderConfigurationRecord (avcC)"; |
489 scoped_ptr<AVCDecoderConfigurationRecord> avcConfig( | 624 scoped_ptr<AVCDecoderConfigurationRecord> avcConfig( |
490 new AVCDecoderConfigurationRecord()); | 625 new AVCDecoderConfigurationRecord()); |
491 RCHECK(reader->ReadChild(avcConfig.get())); | 626 RCHECK(reader->ReadChild(avcConfig.get())); |
492 frame_bitstream_converter = make_scoped_refptr( | 627 frame_bitstream_converter = make_scoped_refptr( |
493 new AVCBitstreamConverter(avcConfig.Pass())); | 628 new AVCBitstreamConverter(avcConfig.Pass())); |
| 629 video_codec = kCodecH264; |
| 630 video_codec_profile = H264PROFILE_MAIN; |
| 631 #if defined(ENABLE_HEVC_DEMUXING) |
| 632 } else if (IsFormatValidHEVC(format, sinf)) { |
| 633 DVLOG(2) << __FUNCTION__ |
| 634 << " parsing HEVCDecoderConfigurationRecord (hvcC)"; |
| 635 scoped_ptr<HEVCDecoderConfigurationRecord> hevcConfig( |
| 636 new HEVCDecoderConfigurationRecord()); |
| 637 RCHECK(reader->ReadChild(hevcConfig.get())); |
| 638 frame_bitstream_converter = make_scoped_refptr( |
| 639 new HEVCBitstreamConverter(hevcConfig.Pass())); |
| 640 video_codec = kCodecHEVC; |
| 641 #endif |
| 642 } else { |
| 643 // Unknown/unsupported format |
| 644 MEDIA_LOG(ERROR, reader->media_log()) << __FUNCTION__ |
| 645 << " unsupported video format " |
| 646 << FourCCToString(format); |
| 647 return false; |
494 } | 648 } |
495 | 649 |
496 return true; | 650 return true; |
497 } | 651 } |
498 | 652 |
499 bool VideoSampleEntry::IsFormatValid() const { | 653 bool VideoSampleEntry::IsFormatValid() const { |
500 return format == FOURCC_AVC1 || format == FOURCC_AVC3 || | 654 #if defined(ENABLE_HEVC_DEMUXING) |
501 (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 || | 655 if (IsFormatValidHEVC(format, sinf)) |
502 sinf.format.format == FOURCC_AVC3)); | 656 return true; |
| 657 #endif |
| 658 return IsFormatValidH264(format, sinf); |
503 } | 659 } |
504 | 660 |
505 ElementaryStreamDescriptor::ElementaryStreamDescriptor() | 661 ElementaryStreamDescriptor::ElementaryStreamDescriptor() |
506 : object_type(kForbidden) {} | 662 : object_type(kForbidden) {} |
507 | 663 |
508 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {} | 664 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {} |
509 | 665 |
510 FourCC ElementaryStreamDescriptor::BoxType() const { | 666 FourCC ElementaryStreamDescriptor::BoxType() const { |
511 return FOURCC_ESDS; | 667 return FOURCC_ESDS; |
512 } | 668 } |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( | 1143 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( |
988 size_t i) const { | 1144 size_t i) const { |
989 if (i >= sample_depends_on_.size()) | 1145 if (i >= sample_depends_on_.size()) |
990 return kSampleDependsOnUnknown; | 1146 return kSampleDependsOnUnknown; |
991 | 1147 |
992 return sample_depends_on_[i]; | 1148 return sample_depends_on_[i]; |
993 } | 1149 } |
994 | 1150 |
995 } // namespace mp4 | 1151 } // namespace mp4 |
996 } // namespace media | 1152 } // namespace media |
OLD | NEW |