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

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

Issue 1843823003: MSE: Protect better against out-of-sequence parser callbacks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix_597447_1
Patch Set: Removed patchset dependency - this can land by itself Created 4 years, 8 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
« no previous file with comments | « media/filters/media_source_state.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/base/media_track.h" 9 #include "media/base/media_track.h"
10 #include "media/base/media_tracks.h" 10 #include "media/base/media_tracks.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 : create_demuxer_stream_cb_(create_demuxer_stream_cb), 93 : create_demuxer_stream_cb_(create_demuxer_stream_cb),
94 timestamp_offset_during_append_(NULL), 94 timestamp_offset_during_append_(NULL),
95 parsing_media_segment_(false), 95 parsing_media_segment_(false),
96 media_segment_contained_audio_frame_(false), 96 media_segment_contained_audio_frame_(false),
97 media_segment_contained_video_frame_(false), 97 media_segment_contained_video_frame_(false),
98 stream_parser_(stream_parser.release()), 98 stream_parser_(stream_parser.release()),
99 audio_(NULL), 99 audio_(NULL),
100 video_(NULL), 100 video_(NULL),
101 frame_processor_(frame_processor.release()), 101 frame_processor_(frame_processor.release()),
102 media_log_(media_log), 102 media_log_(media_log),
103 state_(UNINITIALIZED),
103 auto_update_timestamp_offset_(false) { 104 auto_update_timestamp_offset_(false) {
104 DCHECK(!create_demuxer_stream_cb_.is_null()); 105 DCHECK(!create_demuxer_stream_cb_.is_null());
105 DCHECK(frame_processor_); 106 DCHECK(frame_processor_);
106 } 107 }
107 108
108 MediaSourceState::~MediaSourceState() { 109 MediaSourceState::~MediaSourceState() {
109 Shutdown(); 110 Shutdown();
110 111
111 STLDeleteValues(&text_stream_map_); 112 STLDeleteValues(&text_stream_map_);
112 } 113 }
113 114
114 void MediaSourceState::Init( 115 void MediaSourceState::Init(
115 const StreamParser::InitCB& init_cb, 116 const StreamParser::InitCB& init_cb,
116 bool allow_audio, 117 bool allow_audio,
117 bool allow_video, 118 bool allow_video,
118 const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 119 const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
119 const NewTextTrackCB& new_text_track_cb) { 120 const NewTextTrackCB& new_text_track_cb) {
121 DCHECK_EQ(state_, UNINITIALIZED);
120 new_text_track_cb_ = new_text_track_cb; 122 new_text_track_cb_ = new_text_track_cb;
121 init_cb_ = init_cb; 123 init_cb_ = init_cb;
122 124
125 state_ = PENDING_PARSER_CONFIG;
123 stream_parser_->Init( 126 stream_parser_->Init(
124 base::Bind(&MediaSourceState::OnSourceInitDone, base::Unretained(this)), 127 base::Bind(&MediaSourceState::OnSourceInitDone, base::Unretained(this)),
125 base::Bind(&MediaSourceState::OnNewConfigs, base::Unretained(this), 128 base::Bind(&MediaSourceState::OnNewConfigs, base::Unretained(this),
126 allow_audio, allow_video), 129 allow_audio, allow_video),
127 base::Bind(&MediaSourceState::OnNewBuffers, base::Unretained(this)), 130 base::Bind(&MediaSourceState::OnNewBuffers, base::Unretained(this)),
128 new_text_track_cb_.is_null(), encrypted_media_init_data_cb, 131 new_text_track_cb_.is_null(), encrypted_media_init_data_cb,
129 base::Bind(&MediaSourceState::OnNewMediaSegment, base::Unretained(this)), 132 base::Bind(&MediaSourceState::OnNewMediaSegment, base::Unretained(this)),
130 base::Bind(&MediaSourceState::OnEndOfMediaSegment, 133 base::Bind(&MediaSourceState::OnEndOfMediaSegment,
131 base::Unretained(this)), 134 base::Unretained(this)),
132 media_log_); 135 media_log_);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 // in response to ChunkDemuxerStream::Read() calls. 471 // in response to ChunkDemuxerStream::Read() calls.
469 472
470 return false; 473 return false;
471 } 474 }
472 475
473 bool MediaSourceState::OnNewConfigs( 476 bool MediaSourceState::OnNewConfigs(
474 bool allow_audio, 477 bool allow_audio,
475 bool allow_video, 478 bool allow_video,
476 scoped_ptr<MediaTracks> tracks, 479 scoped_ptr<MediaTracks> tracks,
477 const StreamParser::TextTrackConfigMap& text_configs) { 480 const StreamParser::TextTrackConfigMap& text_configs) {
481 DCHECK_GE(state_, PENDING_PARSER_CONFIG);
478 DCHECK(tracks.get()); 482 DCHECK(tracks.get());
479 media_tracks_ = std::move(tracks); 483 media_tracks_ = std::move(tracks);
480 const AudioDecoderConfig& audio_config = media_tracks_->getFirstAudioConfig(); 484 const AudioDecoderConfig& audio_config = media_tracks_->getFirstAudioConfig();
481 const VideoDecoderConfig& video_config = media_tracks_->getFirstVideoConfig(); 485 const VideoDecoderConfig& video_config = media_tracks_->getFirstVideoConfig();
482 486
483 DVLOG(1) << "OnNewConfigs(" << allow_audio << ", " << allow_video << ", " 487 DVLOG(1) << "OnNewConfigs(" << allow_audio << ", " << allow_video << ", "
484 << audio_config.IsValidConfig() << ", " 488 << audio_config.IsValidConfig() << ", "
485 << video_config.IsValidConfig() << ")"; 489 << video_config.IsValidConfig() << ")";
486 // MSE spec allows new configs to be emitted only during Append, but not 490 // MSE spec allows new configs to be emitted only during Append, but not
487 // during Flush or parser reset operations. 491 // during Flush or parser reset operations.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 break; 646 break;
643 } 647 }
644 } 648 }
645 } 649 }
646 } 650 }
647 651
648 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); 652 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint();
649 653
650 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); 654 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed");
651 if (success) { 655 if (success) {
656 if (state_ == PENDING_PARSER_CONFIG)
657 state_ = PENDING_PARSER_INIT;
652 DCHECK(!init_segment_received_cb_.is_null()); 658 DCHECK(!init_segment_received_cb_.is_null());
653 init_segment_received_cb_.Run(std::move(media_tracks_)); 659 init_segment_received_cb_.Run(std::move(media_tracks_));
654 } 660 }
655 661
656 return success; 662 return success;
657 } 663 }
658 664
659 void MediaSourceState::OnNewMediaSegment() { 665 void MediaSourceState::OnNewMediaSegment() {
660 DVLOG(2) << "OnNewMediaSegment()"; 666 DVLOG(2) << "OnNewMediaSegment()";
667 DCHECK_EQ(state_, PARSER_INITIALIZED);
661 parsing_media_segment_ = true; 668 parsing_media_segment_ = true;
662 media_segment_contained_audio_frame_ = false; 669 media_segment_contained_audio_frame_ = false;
663 media_segment_contained_video_frame_ = false; 670 media_segment_contained_video_frame_ = false;
664 } 671 }
665 672
666 void MediaSourceState::OnEndOfMediaSegment() { 673 void MediaSourceState::OnEndOfMediaSegment() {
667 DVLOG(2) << "OnEndOfMediaSegment()"; 674 DVLOG(2) << "OnEndOfMediaSegment()";
675 DCHECK_EQ(state_, PARSER_INITIALIZED);
668 parsing_media_segment_ = false; 676 parsing_media_segment_ = false;
669 677
670 const bool missing_audio = audio_ && !media_segment_contained_audio_frame_; 678 const bool missing_audio = audio_ && !media_segment_contained_audio_frame_;
671 const bool missing_video = video_ && !media_segment_contained_video_frame_; 679 const bool missing_video = video_ && !media_segment_contained_video_frame_;
672 if (!missing_audio && !missing_video) 680 if (!missing_audio && !missing_video)
673 return; 681 return;
674 682
675 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_missing_track_logs_, 683 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_missing_track_logs_,
676 kMaxMissingTrackInSegmentLogs) 684 kMaxMissingTrackInSegmentLogs)
677 << "Media segment did not contain any " 685 << "Media segment did not contain any "
678 << (missing_audio && missing_video ? "audio or video" 686 << (missing_audio && missing_video ? "audio or video"
679 : missing_audio ? "audio" : "video") 687 : missing_audio ? "audio" : "video")
680 << " coded frames, mismatching initialization segment. Therefore, MSE " 688 << " coded frames, mismatching initialization segment. Therefore, MSE "
681 "coded frame processing may not interoperably detect discontinuities " 689 "coded frame processing may not interoperably detect discontinuities "
682 "in appended media."; 690 "in appended media.";
683 } 691 }
684 692
685 bool MediaSourceState::OnNewBuffers( 693 bool MediaSourceState::OnNewBuffers(
686 const StreamParser::BufferQueue& audio_buffers, 694 const StreamParser::BufferQueue& audio_buffers,
687 const StreamParser::BufferQueue& video_buffers, 695 const StreamParser::BufferQueue& video_buffers,
688 const StreamParser::TextBufferQueueMap& text_map) { 696 const StreamParser::TextBufferQueueMap& text_map) {
689 DVLOG(2) << "OnNewBuffers()"; 697 DVLOG(2) << "OnNewBuffers()";
698 DCHECK_EQ(state_, PARSER_INITIALIZED);
690 DCHECK(timestamp_offset_during_append_); 699 DCHECK(timestamp_offset_during_append_);
691 DCHECK(parsing_media_segment_); 700 DCHECK(parsing_media_segment_);
692 701
693 media_segment_contained_audio_frame_ |= !audio_buffers.empty(); 702 media_segment_contained_audio_frame_ |= !audio_buffers.empty();
694 media_segment_contained_video_frame_ |= !video_buffers.empty(); 703 media_segment_contained_video_frame_ |= !video_buffers.empty();
695 704
696 const TimeDelta timestamp_offset_before_processing = 705 const TimeDelta timestamp_offset_before_processing =
697 *timestamp_offset_during_append_; 706 *timestamp_offset_during_append_;
698 707
699 // Calculate the new timestamp offset for audio/video tracks if the stream 708 // Calculate the new timestamp offset for audio/video tracks if the stream
(...skipping 23 matching lines...) Expand all
723 if (auto_update_timestamp_offset_ && 732 if (auto_update_timestamp_offset_ &&
724 timestamp_offset_before_processing == *timestamp_offset_during_append_) { 733 timestamp_offset_before_processing == *timestamp_offset_during_append_) {
725 *timestamp_offset_during_append_ = new_timestamp_offset; 734 *timestamp_offset_during_append_ = new_timestamp_offset;
726 } 735 }
727 736
728 return true; 737 return true;
729 } 738 }
730 739
731 void MediaSourceState::OnSourceInitDone( 740 void MediaSourceState::OnSourceInitDone(
732 const StreamParser::InitParameters& params) { 741 const StreamParser::InitParameters& params) {
742 DCHECK_EQ(state_, PENDING_PARSER_INIT);
743 state_ = PARSER_INITIALIZED;
733 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; 744 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset;
734 base::ResetAndReturn(&init_cb_).Run(params); 745 base::ResetAndReturn(&init_cb_).Run(params);
735 } 746 }
736 747
737 } // namespace media 748 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/media_source_state.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698