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

Unified Diff: media/formats/mp4/mp4_stream_parser.cc

Issue 816353010: Implemented HEVC video demuxing and parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added hevc handling in media/base/android/media_codec_bridge.cc Created 5 years, 9 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/mp4_stream_parser.cc
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc
index e6ad09d9171cabcd5fc23b19468ebbb25b7b54e7..319ef2d7bd7a20662a80bb7c07104574ae673996 100644
--- a/media/formats/mp4/mp4_stream_parser.cc
+++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -12,13 +12,16 @@
#include "media/base/stream_parser_buffer.h"
#include "media/base/text_track_config.h"
#include "media/base/video_decoder_config.h"
-#include "media/base/video_util.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/formats/mp4/box_reader.h"
#include "media/formats/mp4/es_descriptor.h"
#include "media/formats/mp4/rcheck.h"
#include "media/formats/mpeg/adts_constants.h"
+#if defined(USE_PROPRIETARY_CODECS) && defined(ENABLE_HEVC_DEMUXING)
+#include "media/formats/mp4/hevc.h"
+#endif
+
namespace media {
namespace mp4 {
@@ -278,25 +281,15 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) {
desc_idx = 0;
const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx];
- if (!entry.IsFormatValid()) {
+ video_config = entry.GetVideoDecoderConfig();
+ if (!video_config.IsValidConfig()) {
MEDIA_LOG(log_cb_) << "Unsupported video format 0x"
<< std::hex << entry.format << " in stsd box.";
return false;
}
- // TODO(strobe): Recover correct crop box
- gfx::Size coded_size(entry.width, entry.height);
- gfx::Rect visible_rect(coded_size);
- gfx::Size natural_size = GetNaturalSize(visible_rect.size(),
- entry.pixel_aspect.h_spacing,
- entry.pixel_aspect.v_spacing);
is_video_track_encrypted_ = entry.sinf.info.track_encryption.is_encrypted;
DVLOG(1) << "is_video_track_encrypted_: " << is_video_track_encrypted_;
- video_config.Initialize(kCodecH264, H264PROFILE_MAIN, VideoFrame::YV12,
- coded_size, visible_rect, natural_size,
- // No decoder-specific buffer needed for AVC;
- // SPS/PPS are embedded in the video stream
- NULL, 0, is_video_track_encrypted_, false);
has_video_ = true;
video_track_id_ = track->header.track_id;
}
@@ -389,6 +382,35 @@ bool MP4StreamParser::PrepareAVCBuffer(
return true;
}
+#if defined(USE_PROPRIETARY_CODECS) && defined(ENABLE_HEVC_DEMUXING)
+bool MP4StreamParser::PrepareHEVCBuffer(
+ const HEVCDecoderConfigurationRecord& hevc_config,
+ std::vector<uint8>* frame_buf,
+ std::vector<SubsampleEntry>* subsamples) const {
+ DVLOG(2) << __FUNCTION__ << " size=" << frame_buf->size();
+ RCHECK(AVC::ConvertFrameToAnnexB(hevc_config.lengthSizeMinusOne + 1,
+ frame_buf));
+ if (!subsamples->empty()) {
+ const int nalu_size_diff = 4 - (hevc_config.lengthSizeMinusOne + 1);
+ size_t expected_size = runs_->sample_size() +
+ subsamples->size() * nalu_size_diff;
+ RCHECK(frame_buf->size() == expected_size);
+ for (size_t i = 0; i < subsamples->size(); i++)
+ (*subsamples)[i].clear_bytes += nalu_size_diff;
+ }
+
+ if (runs_->is_keyframe()) {
+ // If this is a keyframe, we (re-)inject HEVC params headers at the start of
+ // a frame. If subsample info is present, we also update the clear byte
+ // count for that first subsample.
+ RCHECK(HEVC::InsertParamSetsAnnexB(hevc_config, frame_buf, subsamples));
+ }
+
+ DCHECK(HEVC::IsValidAnnexB(*frame_buf, *subsamples));
+ return true;
+}
+#endif
+
bool MP4StreamParser::PrepareAACBuffer(
const AAC& aac_config, std::vector<uint8>* frame_buf,
std::vector<SubsampleEntry>* subsamples) const {
@@ -479,12 +501,24 @@ bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers,
std::vector<uint8> frame_buf(buf, buf + runs_->sample_size());
if (video) {
- if (!PrepareAVCBuffer(runs_->video_description().avcc,
+ VideoCodec codec =
+ runs_->video_description().GetVideoDecoderConfig().codec();
+ if (codec == kCodecH264 &&
+ !PrepareAVCBuffer(runs_->video_description().avcConfig,
&frame_buf, &subsamples)) {
MEDIA_LOG(log_cb_) << "Failed to prepare AVC sample for decode";
*err = true;
return false;
}
+#if defined(USE_PROPRIETARY_CODECS) && defined(ENABLE_HEVC_DEMUXING)
+ if (codec == kCodecHEVC &&
+ !PrepareHEVCBuffer(runs_->video_description().hevcConfig,
+ &frame_buf, &subsamples)) {
+ MEDIA_LOG(log_cb_) << "Failed to prepare HEVC sample for decode";
+ *err = true;
+ return false;
+ }
+#endif
}
if (audio) {

Powered by Google App Engine
This is Rietveld 408576698