| Index: media/filters/chunk_demuxer.cc
|
| diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
|
| index 224abc430b697570bc8d05545417da950c9d1b71..c03de799e4e310994b4186ca801e9d65cd6e8cbd 100644
|
| --- a/media/filters/chunk_demuxer.cc
|
| +++ b/media/filters/chunk_demuxer.cc
|
| @@ -192,7 +192,7 @@ class SourceState {
|
| void OnNewMediaSegment();
|
|
|
| // Called by the |stream_parser_| at the end of a media segment.
|
| - void OnEndOfMediaSegment();
|
| + bool OnEndOfMediaSegment();
|
|
|
| // Called by the |stream_parser_| when new buffers have been parsed.
|
| // It processes the new buffers using |frame_processor_|, which includes
|
| @@ -240,6 +240,12 @@ class SourceState {
|
| // Keeps track of whether a media segment is being parsed.
|
| bool parsing_media_segment_;
|
|
|
| + // Valid only while |parsing_media_segment_| is true. These flags are to
|
| + // enforce adherence to MSE spec's requirement of at least one frame for each
|
| + // A/V track in each media segment.
|
| + bool media_segment_contained_audio_frame_;
|
| + bool media_segment_contained_video_frame_;
|
| +
|
| // The object used to parse appended data.
|
| scoped_ptr<StreamParser> stream_parser_;
|
|
|
| @@ -277,6 +283,8 @@ SourceState::SourceState(scoped_ptr<StreamParser> stream_parser,
|
| timestamp_offset_during_append_(NULL),
|
| new_media_segment_(false),
|
| parsing_media_segment_(false),
|
| + media_segment_contained_audio_frame_(false),
|
| + media_segment_contained_video_frame_(false),
|
| stream_parser_(stream_parser.release()),
|
| audio_(NULL),
|
| video_(NULL),
|
| @@ -825,12 +833,27 @@ void SourceState::OnNewMediaSegment() {
|
| DVLOG(2) << "OnNewMediaSegment()";
|
| parsing_media_segment_ = true;
|
| new_media_segment_ = true;
|
| + media_segment_contained_audio_frame_ = false;
|
| + media_segment_contained_video_frame_ = false;
|
| }
|
|
|
| -void SourceState::OnEndOfMediaSegment() {
|
| +bool SourceState::OnEndOfMediaSegment() {
|
| DVLOG(2) << "OnEndOfMediaSegment()";
|
| parsing_media_segment_ = false;
|
| new_media_segment_ = false;
|
| +
|
| + const bool missing_audio = audio_ && !media_segment_contained_audio_frame_;
|
| + const bool missing_video = video_ && !media_segment_contained_video_frame_;
|
| + if (missing_audio || missing_video) {
|
| + MEDIA_LOG(ERROR, media_log_)
|
| + << "Media segment did not contain any "
|
| + << (missing_audio && missing_video ? "audio or video"
|
| + : missing_audio ? "audio" : "video")
|
| + << " coded frames, mismatching initialization segment";
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| bool SourceState::OnNewBuffers(
|
| @@ -841,6 +864,9 @@ bool SourceState::OnNewBuffers(
|
| DCHECK(timestamp_offset_during_append_);
|
| DCHECK(parsing_media_segment_);
|
|
|
| + media_segment_contained_audio_frame_ |= !audio_buffers.empty();
|
| + media_segment_contained_video_frame_ |= !video_buffers.empty();
|
| +
|
| const TimeDelta timestamp_offset_before_processing =
|
| *timestamp_offset_during_append_;
|
|
|
|
|