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(USE_PROPRIETARY_CODECS) && defined(ENABLE_HEVC_DEMUXING) | |
wolenetz
2015/09/02 20:43:18
nit: why sometimes condition on both proprietary+h
servolk
2015/09/03 00:17:51
Oh, these were remains of the way we had to do thi
wolenetz
2015/09/08 19:53:10
Acknowledged.
| |
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 && | |
wolenetz
2015/09/02 20:43:18
nit: now would be a great time to MEDIA_LOG why RC
servolk
2015/09/03 00:17:51
On one hand I understand your concerns, but on the
wolenetz
2015/09/08 19:53:10
That's fine, thank you for providing more detail i
| |
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__ | |
wolenetz
2015/09/02 20:43:18
nit: We haven't been including __FUNCTION__ in mos
| |
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 |