Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: media/formats/mp4/box_definitions.cc

Issue 816353010: Implemented HEVC video demuxing and parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to ToT Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(&parallelismType) &&
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698