| Index: media/formats/mp4/box_definitions.cc
|
| diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
|
| index 72809cfdffdd542a7c97b2563f97bb935bc79779..df595229d1517209d740e43535fd63689aad530a 100644
|
| --- a/media/formats/mp4/box_definitions.cc
|
| +++ b/media/formats/mp4/box_definitions.cc
|
| @@ -5,6 +5,7 @@
|
| #include "media/formats/mp4/box_definitions.h"
|
|
|
| #include "base/logging.h"
|
| +#include "media/base/video_util.h"
|
| #include "media/formats/mp4/es_descriptor.h"
|
| #include "media/formats/mp4/rcheck.h"
|
|
|
| @@ -462,6 +463,109 @@ bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
|
| return true;
|
| }
|
|
|
| +#if defined(ENABLE_HEVC_DEMUXING)
|
| +HEVCDecoderConfigurationRecord::HEVCDecoderConfigurationRecord()
|
| + : configurationVersion(0),
|
| + general_profile_space(0),
|
| + general_tier_flag(0),
|
| + general_profile_idc(0),
|
| + general_profile_compatibility_flags(0),
|
| + general_constraint_indicator_flags(0),
|
| + general_level_idc(0),
|
| + min_spatial_segmentation_idc(0),
|
| + parallelismType(0),
|
| + chromaFormat(0),
|
| + bitDepthLumaMinus8(0),
|
| + bitDepthChromaMinus8(0),
|
| + avgFrameRate(0),
|
| + constantFrameRate(0),
|
| + numTemporalLayers(0),
|
| + temporalIdNested(0),
|
| + lengthSizeMinusOne(0),
|
| + numOfArrays(0) {}
|
| +
|
| +HEVCDecoderConfigurationRecord::~HEVCDecoderConfigurationRecord() {}
|
| +FourCC HEVCDecoderConfigurationRecord::BoxType() const { return FOURCC_HVCC; }
|
| +
|
| +bool HEVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
|
| + return ParseInternal(reader, reader->log_cb());
|
| +}
|
| +
|
| +bool HEVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) {
|
| + BufferReader reader(data, data_size);
|
| + return ParseInternal(&reader, LogCB());
|
| +}
|
| +
|
| +HEVCDecoderConfigurationRecord::HVCCNALArray::HVCCNALArray()
|
| + : first_byte(0) {}
|
| +
|
| +HEVCDecoderConfigurationRecord::HVCCNALArray::~HVCCNALArray() {}
|
| +
|
| +bool HEVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
|
| + const LogCB& log_cb) {
|
| + uint8 profile_indication = 0;
|
| + uint32 general_constraint_indicator_flags_hi = 0;
|
| + uint16 general_constraint_indicator_flags_lo = 0;
|
| + uint8 misc = 0;
|
| + RCHECK(reader->Read1(&configurationVersion) && configurationVersion == 1 &&
|
| + reader->Read1(&profile_indication) &&
|
| + reader->Read4(&general_profile_compatibility_flags) &&
|
| + reader->Read4(&general_constraint_indicator_flags_hi) &&
|
| + reader->Read2(&general_constraint_indicator_flags_lo) &&
|
| + reader->Read1(&general_level_idc) &&
|
| + reader->Read2(&min_spatial_segmentation_idc) &&
|
| + reader->Read1(¶llelismType) &&
|
| + reader->Read1(&chromaFormat) &&
|
| + reader->Read1(&bitDepthLumaMinus8) &&
|
| + reader->Read1(&bitDepthChromaMinus8) &&
|
| + reader->Read2(&avgFrameRate) &&
|
| + reader->Read1(&misc) &&
|
| + reader->Read1(&numOfArrays));
|
| +
|
| + general_profile_space = profile_indication >> 6;
|
| + general_tier_flag = (profile_indication >> 5) & 1;
|
| + general_profile_idc = profile_indication & 0x1f;
|
| +
|
| + general_constraint_indicator_flags = general_constraint_indicator_flags_hi;
|
| + general_constraint_indicator_flags <<= 16;
|
| + general_constraint_indicator_flags |= general_constraint_indicator_flags_lo;
|
| +
|
| + min_spatial_segmentation_idc &= 0xfff;
|
| + parallelismType &= 3;
|
| + chromaFormat &= 3;
|
| + bitDepthLumaMinus8 &= 7;
|
| + bitDepthChromaMinus8 &= 7;
|
| +
|
| + constantFrameRate = misc >> 6;
|
| + numTemporalLayers = (misc >> 3) & 7;
|
| + temporalIdNested = (misc >> 2) & 1;
|
| + lengthSizeMinusOne = misc & 3;
|
| +
|
| + DVLOG(2) << __FUNCTION__ << " numOfArrays=" << (int)numOfArrays;
|
| + arrays.resize(numOfArrays);
|
| + for (uint32 j = 0; j < numOfArrays; j++) {
|
| + RCHECK(reader->Read1(&arrays[j].first_byte));
|
| + uint16 numNalus = 0;
|
| + RCHECK(reader->Read2(&numNalus));
|
| + arrays[j].units.resize(numNalus);
|
| + for (uint32 i = 0; i < numNalus; ++i) {
|
| + uint16 naluLength = 0;
|
| + RCHECK(reader->Read2(&naluLength) &&
|
| + reader->ReadVec(&arrays[j].units[i], naluLength));
|
| + DVLOG(4) << __FUNCTION__ << " naluType="
|
| + << (int)(arrays[j].first_byte & 0x3f)
|
| + << " size=" << arrays[j].units[i].size();
|
| + }
|
| + }
|
| +
|
| + if (!log_cb.is_null()) {
|
| + MEDIA_LOG(INFO, log_cb) << "Video codec: hevc";
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +#endif
|
| +
|
| PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {}
|
| PixelAspectRatioBox::~PixelAspectRatioBox() {}
|
| FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; }
|
| @@ -506,16 +610,51 @@ bool VideoSampleEntry::Parse(BoxReader* reader) {
|
| }
|
| }
|
|
|
| - if (IsFormatValid())
|
| - RCHECK(reader->ReadChild(&avcc));
|
| + VideoCodec codec = kUnknownVideoCodec;
|
| + VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
|
| + if ((format == FOURCC_AVC1 || format == FOURCC_AVC3) ||
|
| + (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 ||
|
| + sinf.format.format == FOURCC_AVC3))) {
|
| + DVLOG(2) << __FUNCTION__
|
| + << " reading AVCDecoderConfigurationRecord (avcC)";
|
| + RCHECK(reader->ReadChild(&avcConfig));
|
| + codec = kCodecH264;
|
| + profile = H264PROFILE_MAIN;
|
| +#if defined(ENABLE_HEVC_DEMUXING)
|
| + } else if ((format == FOURCC_HEV1 || format == FOURCC_HVC1) ||
|
| + (format == FOURCC_ENCV && (sinf.format.format == FOURCC_HEV1 ||
|
| + sinf.format.format == FOURCC_HVC1))) {
|
| + DVLOG(2) << __FUNCTION__
|
| + << " parsing HEVCDecoderConfigurationRecord (hvcC)";
|
| + RCHECK(reader->ReadChild(&hevcConfig));
|
| + codec = kCodecHEVC;
|
| +#endif
|
| + } else {
|
| + // Unknown/unsupported format
|
| + MEDIA_LOG(ERROR, reader->log_cb()) << __FUNCTION__
|
| + << " unsupported video format "
|
| + << FourCCToString(format);
|
| + return false;
|
| + }
|
|
|
| + // TODO(strobe): Recover correct crop box
|
| + gfx::Size coded_size(width, height);
|
| + gfx::Rect visible_rect(coded_size);
|
| + gfx::Size natural_size = GetNaturalSize(visible_rect.size(),
|
| + pixel_aspect.h_spacing,
|
| + pixel_aspect.v_spacing);
|
| + bool is_encrypted = sinf.info.track_encryption.is_encrypted;
|
| + video_decoder_config_.Initialize(
|
| + codec, profile, VideoFrame::YV12, VideoFrame::COLOR_SPACE_UNSPECIFIED,
|
| + coded_size, visible_rect, natural_size,
|
| + // No decoder-specific buffer needed.
|
| + // Decoder parameters (SPS/PPS) are embedded in the video stream.
|
| + NULL, 0, is_encrypted, false);
|
| return true;
|
| }
|
|
|
| -bool VideoSampleEntry::IsFormatValid() const {
|
| - return format == FOURCC_AVC1 || format == FOURCC_AVC3 ||
|
| - (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 ||
|
| - sinf.format.format == FOURCC_AVC3));
|
| +VideoDecoderConfig VideoSampleEntry::GetVideoDecoderConfig() const {
|
| + return video_decoder_config_;
|
| }
|
|
|
| ElementaryStreamDescriptor::ElementaryStreamDescriptor()
|
|
|