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

Unified 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, 7 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 side-by-side diff with in-line comments
Download patch
Index: media/formats/mp4/box_definitions.cc
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
index 5a15240ebbc0f8b860fa55dba16daaa63d9fe68d..b96415819f74d03444d031fa7655d9b42366bfa3 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"
@@ -413,6 +414,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(&parallelismType) &&
+ 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; }
@@ -457,16 +561,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,
+ 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()

Powered by Google App Engine
This is Rietveld 408576698