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

Side by Side Diff: media/filters/media_source_state.cc

Issue 1564983003: MSE: Log a warning if muxed AV media segment has no A or has no V block (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed previous CR comments Created 4 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/media_source_state.h" 5 #include "media/filters/media_source_state.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "media/filters/chunk_demuxer.h" 9 #include "media/filters/chunk_demuxer.h"
10 #include "media/filters/frame_processor.h" 10 #include "media/filters/frame_processor.h"
11 #include "media/filters/source_buffer_stream.h" 11 #include "media/filters/source_buffer_stream.h"
12 12
13 namespace media { 13 namespace media {
14 14
15 enum {
16 // Limits the number of MEDIA_LOG() calls warning the user that a muxed stream
17 // media segment is missing a block from at least one of the audio or video
18 // tracks.
19 kMaxMissingTrackInSegmentLogs = 10,
20 };
21
15 static TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) { 22 static TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) {
16 return queue.back()->timestamp() + queue.back()->duration(); 23 return queue.back()->timestamp() + queue.back()->duration();
17 } 24 }
18 25
19 // List of time ranges for each SourceBuffer. 26 // List of time ranges for each SourceBuffer.
20 // static 27 // static
21 Ranges<TimeDelta> MediaSourceState::ComputeRangesIntersection( 28 Ranges<TimeDelta> MediaSourceState::ComputeRangesIntersection(
22 const RangesList& activeRanges, 29 const RangesList& activeRanges,
23 bool ended) { 30 bool ended) {
24 // TODO(servolk): Perhaps this can be removed in favor of blink implementation 31 // TODO(servolk): Perhaps this can be removed in favor of blink implementation
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 85
79 MediaSourceState::MediaSourceState( 86 MediaSourceState::MediaSourceState(
80 scoped_ptr<StreamParser> stream_parser, 87 scoped_ptr<StreamParser> stream_parser,
81 scoped_ptr<FrameProcessor> frame_processor, 88 scoped_ptr<FrameProcessor> frame_processor,
82 const CreateDemuxerStreamCB& create_demuxer_stream_cb, 89 const CreateDemuxerStreamCB& create_demuxer_stream_cb,
83 const scoped_refptr<MediaLog>& media_log) 90 const scoped_refptr<MediaLog>& media_log)
84 : create_demuxer_stream_cb_(create_demuxer_stream_cb), 91 : create_demuxer_stream_cb_(create_demuxer_stream_cb),
85 timestamp_offset_during_append_(NULL), 92 timestamp_offset_during_append_(NULL),
86 new_media_segment_(false), 93 new_media_segment_(false),
87 parsing_media_segment_(false), 94 parsing_media_segment_(false),
95 media_segment_contained_audio_frame_(false),
96 media_segment_contained_video_frame_(false),
88 stream_parser_(stream_parser.release()), 97 stream_parser_(stream_parser.release()),
89 audio_(NULL), 98 audio_(NULL),
90 video_(NULL), 99 video_(NULL),
91 frame_processor_(frame_processor.release()), 100 frame_processor_(frame_processor.release()),
92 media_log_(media_log), 101 media_log_(media_log),
93 auto_update_timestamp_offset_(false) { 102 auto_update_timestamp_offset_(false) {
94 DCHECK(!create_demuxer_stream_cb_.is_null()); 103 DCHECK(!create_demuxer_stream_cb_.is_null());
95 DCHECK(frame_processor_); 104 DCHECK(frame_processor_);
96 } 105 }
97 106
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 DCHECK(!timestamp_offset_during_append_); 182 DCHECK(!timestamp_offset_during_append_);
174 timestamp_offset_during_append_ = timestamp_offset; 183 timestamp_offset_during_append_ = timestamp_offset;
175 append_window_start_during_append_ = append_window_start; 184 append_window_start_during_append_ = append_window_start;
176 append_window_end_during_append_ = append_window_end; 185 append_window_end_during_append_ = append_window_end;
177 186
178 stream_parser_->Flush(); 187 stream_parser_->Flush();
179 timestamp_offset_during_append_ = NULL; 188 timestamp_offset_during_append_ = NULL;
180 189
181 frame_processor_->Reset(); 190 frame_processor_->Reset();
182 parsing_media_segment_ = false; 191 parsing_media_segment_ = false;
192 media_segment_contained_audio_frame_ = false;
193 media_segment_contained_video_frame_ = false;
183 } 194 }
184 195
185 void MediaSourceState::Remove(TimeDelta start, 196 void MediaSourceState::Remove(TimeDelta start,
186 TimeDelta end, 197 TimeDelta end,
187 TimeDelta duration) { 198 TimeDelta duration) {
188 if (audio_) 199 if (audio_)
189 audio_->Remove(start, end, duration); 200 audio_->Remove(start, end, duration);
190 201
191 if (video_) 202 if (video_)
192 video_->Remove(start, end, duration); 203 video_->Remove(start, end, duration);
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 if (success) 641 if (success)
631 init_segment_received_cb_.Run(); 642 init_segment_received_cb_.Run();
632 643
633 return success; 644 return success;
634 } 645 }
635 646
636 void MediaSourceState::OnNewMediaSegment() { 647 void MediaSourceState::OnNewMediaSegment() {
637 DVLOG(2) << "OnNewMediaSegment()"; 648 DVLOG(2) << "OnNewMediaSegment()";
638 parsing_media_segment_ = true; 649 parsing_media_segment_ = true;
639 new_media_segment_ = true; 650 new_media_segment_ = true;
651 media_segment_contained_audio_frame_ = false;
652 media_segment_contained_video_frame_ = false;
640 } 653 }
641 654
642 void MediaSourceState::OnEndOfMediaSegment() { 655 void MediaSourceState::OnEndOfMediaSegment() {
643 DVLOG(2) << "OnEndOfMediaSegment()"; 656 DVLOG(2) << "OnEndOfMediaSegment()";
644 parsing_media_segment_ = false; 657 parsing_media_segment_ = false;
645 new_media_segment_ = false; 658 new_media_segment_ = false;
659
660 const bool missing_audio = audio_ && !media_segment_contained_audio_frame_;
661 const bool missing_video = video_ && !media_segment_contained_video_frame_;
662 if (!missing_audio && !missing_video)
663 return;
664
665 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_missing_track_logs_,
666 kMaxMissingTrackInSegmentLogs)
667 << "Media segment did not contain any "
668 << (missing_audio && missing_video ? "audio or video"
669 : missing_audio ? "audio" : "video")
670 << " coded frames, mismatching initialization segment. Therefore, MSE "
671 "coded frame processing may not interoperably detect discontinuities "
672 "in appended media.";
646 } 673 }
647 674
648 bool MediaSourceState::OnNewBuffers( 675 bool MediaSourceState::OnNewBuffers(
649 const StreamParser::BufferQueue& audio_buffers, 676 const StreamParser::BufferQueue& audio_buffers,
650 const StreamParser::BufferQueue& video_buffers, 677 const StreamParser::BufferQueue& video_buffers,
651 const StreamParser::TextBufferQueueMap& text_map) { 678 const StreamParser::TextBufferQueueMap& text_map) {
652 DVLOG(2) << "OnNewBuffers()"; 679 DVLOG(2) << "OnNewBuffers()";
653 DCHECK(timestamp_offset_during_append_); 680 DCHECK(timestamp_offset_during_append_);
654 DCHECK(parsing_media_segment_); 681 DCHECK(parsing_media_segment_);
655 682
683 media_segment_contained_audio_frame_ |= !audio_buffers.empty();
684 media_segment_contained_video_frame_ |= !video_buffers.empty();
685
656 const TimeDelta timestamp_offset_before_processing = 686 const TimeDelta timestamp_offset_before_processing =
657 *timestamp_offset_during_append_; 687 *timestamp_offset_during_append_;
658 688
659 // Calculate the new timestamp offset for audio/video tracks if the stream 689 // Calculate the new timestamp offset for audio/video tracks if the stream
660 // parser has requested automatic updates. 690 // parser has requested automatic updates.
661 TimeDelta new_timestamp_offset = timestamp_offset_before_processing; 691 TimeDelta new_timestamp_offset = timestamp_offset_before_processing;
662 if (auto_update_timestamp_offset_) { 692 if (auto_update_timestamp_offset_) {
663 const bool have_audio_buffers = !audio_buffers.empty(); 693 const bool have_audio_buffers = !audio_buffers.empty();
664 const bool have_video_buffers = !video_buffers.empty(); 694 const bool have_video_buffers = !video_buffers.empty();
665 if (have_audio_buffers && have_video_buffers) { 695 if (have_audio_buffers && have_video_buffers) {
(...skipping 22 matching lines...) Expand all
688 return true; 718 return true;
689 } 719 }
690 720
691 void MediaSourceState::OnSourceInitDone( 721 void MediaSourceState::OnSourceInitDone(
692 const StreamParser::InitParameters& params) { 722 const StreamParser::InitParameters& params) {
693 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; 723 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset;
694 base::ResetAndReturn(&init_cb_).Run(params); 724 base::ResetAndReturn(&init_cb_).Run(params);
695 } 725 }
696 726
697 } // namespace media 727 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698