| 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 5c2fcb9e30dfe8a944edaf3850460a811c787e8a..06a52103b2d335477bc03ad6371448dde751239c 100644
|
| --- a/media/formats/mp4/mp4_stream_parser.cc
|
| +++ b/media/formats/mp4/mp4_stream_parser.cc
|
| @@ -11,13 +11,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 {
|
|
|
| @@ -276,25 +279,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(ERROR, 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;
|
| }
|
| @@ -387,6 +380,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 {
|
| @@ -477,12 +499,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(ERROR, 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(ERROR, log_cb_) << "Failed to prepare HEVC sample for decode";
|
| + *err = true;
|
| + return false;
|
| + }
|
| +#endif
|
| }
|
|
|
| if (audio) {
|
|
|