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/source_buffer_stream.cc

Issue 1281113002: MSE: Warn when keyframe after track_buffer is significantly in future (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed DCHECK, added tests, need to fix log resulting from one of new tests Created 5 years, 4 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/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 12 matching lines...) Expand all
23 // An arbitrarily-chosen number to estimate the duration of a buffer if none 23 // An arbitrarily-chosen number to estimate the duration of a buffer if none
24 // is set and there's not enough information to get a better estimate. 24 // is set and there's not enough information to get a better estimate.
25 kDefaultBufferDurationInMs = 125, 25 kDefaultBufferDurationInMs = 125,
26 26
27 // Limit the number of MEDIA_LOG() logs for splice buffer generation warnings 27 // Limit the number of MEDIA_LOG() logs for splice buffer generation warnings
28 // and successes. Though these values are high enough to possibly exhaust the 28 // and successes. Though these values are high enough to possibly exhaust the
29 // media internals event cache (along with other events), these logs are 29 // media internals event cache (along with other events), these logs are
30 // important for debugging splice generation. 30 // important for debugging splice generation.
31 kMaxSpliceGenerationWarningLogs = 50, 31 kMaxSpliceGenerationWarningLogs = 50,
32 kMaxSpliceGenerationSuccessLogs = 20, 32 kMaxSpliceGenerationSuccessLogs = 20,
33
34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps.
35 kMaxTrackBufferGapWarningLogs = 20,
33 }; 36 };
xhwang 2015/08/10 23:51:08 nit: As discussed before, these could just be "con
wolenetz 2015/08/11 02:53:31 Oops! Done :)
34 37
35 // Helper method that returns true if |ranges| is sorted in increasing order, 38 // Helper method that returns true if |ranges| is sorted in increasing order,
36 // false otherwise. 39 // false otherwise.
37 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { 40 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) {
38 DecodeTimestamp prev = kNoDecodeTimestamp(); 41 DecodeTimestamp prev = kNoDecodeTimestamp();
39 for (std::list<SourceBufferRange*>::const_iterator itr = 42 for (std::list<SourceBufferRange*>::const_iterator itr =
40 ranges.begin(); itr != ranges.end(); ++itr) { 43 ranges.begin(); itr != ranges.end(); ++itr) {
41 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) 44 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
42 return false; 45 return false;
43 prev = (*itr)->GetEndTimestamp(); 46 prev = (*itr)->GetEndTimestamp();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 130 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
128 const scoped_refptr<MediaLog>& media_log, 131 const scoped_refptr<MediaLog>& media_log,
129 bool splice_frames_enabled) 132 bool splice_frames_enabled)
130 : media_log_(media_log), 133 : media_log_(media_log),
131 current_config_index_(0), 134 current_config_index_(0),
132 append_config_index_(0), 135 append_config_index_(0),
133 seek_pending_(false), 136 seek_pending_(false),
134 end_of_stream_(false), 137 end_of_stream_(false),
135 seek_buffer_timestamp_(kNoTimestamp()), 138 seek_buffer_timestamp_(kNoTimestamp()),
136 selected_range_(NULL), 139 selected_range_(NULL),
140 just_exhausted_track_buffer_(false),
137 media_segment_start_time_(kNoDecodeTimestamp()), 141 media_segment_start_time_(kNoDecodeTimestamp()),
138 range_for_next_append_(ranges_.end()), 142 range_for_next_append_(ranges_.end()),
139 new_media_segment_(false), 143 new_media_segment_(false),
140 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 144 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
141 last_appended_buffer_is_keyframe_(false), 145 last_appended_buffer_is_keyframe_(false),
142 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 146 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
143 max_interbuffer_distance_(kNoTimestamp()), 147 max_interbuffer_distance_(kNoTimestamp()),
144 memory_limit_(kSourceBufferAudioMemoryLimit), 148 memory_limit_(kSourceBufferAudioMemoryLimit),
145 config_change_pending_(false), 149 config_change_pending_(false),
146 splice_buffers_index_(0), 150 splice_buffers_index_(0),
147 pending_buffers_complete_(false), 151 pending_buffers_complete_(false),
148 splice_frames_enabled_(splice_frames_enabled), 152 splice_frames_enabled_(splice_frames_enabled),
149 num_splice_generation_warning_logs_(0), 153 num_splice_generation_warning_logs_(0),
150 num_splice_generation_success_logs_(0) { 154 num_splice_generation_success_logs_(0),
155 num_track_buffer_gap_warning_logs_(0) {
151 DCHECK(audio_config.IsValidConfig()); 156 DCHECK(audio_config.IsValidConfig());
152 audio_configs_.push_back(audio_config); 157 audio_configs_.push_back(audio_config);
153 } 158 }
154 159
155 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 160 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
156 const scoped_refptr<MediaLog>& media_log, 161 const scoped_refptr<MediaLog>& media_log,
157 bool splice_frames_enabled) 162 bool splice_frames_enabled)
158 : media_log_(media_log), 163 : media_log_(media_log),
159 current_config_index_(0), 164 current_config_index_(0),
160 append_config_index_(0), 165 append_config_index_(0),
161 seek_pending_(false), 166 seek_pending_(false),
162 end_of_stream_(false), 167 end_of_stream_(false),
163 seek_buffer_timestamp_(kNoTimestamp()), 168 seek_buffer_timestamp_(kNoTimestamp()),
164 selected_range_(NULL), 169 selected_range_(NULL),
170 just_exhausted_track_buffer_(false),
165 media_segment_start_time_(kNoDecodeTimestamp()), 171 media_segment_start_time_(kNoDecodeTimestamp()),
166 range_for_next_append_(ranges_.end()), 172 range_for_next_append_(ranges_.end()),
167 new_media_segment_(false), 173 new_media_segment_(false),
168 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 174 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
169 last_appended_buffer_is_keyframe_(false), 175 last_appended_buffer_is_keyframe_(false),
170 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 176 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
171 max_interbuffer_distance_(kNoTimestamp()), 177 max_interbuffer_distance_(kNoTimestamp()),
172 memory_limit_(kSourceBufferVideoMemoryLimit), 178 memory_limit_(kSourceBufferVideoMemoryLimit),
173 config_change_pending_(false), 179 config_change_pending_(false),
174 splice_buffers_index_(0), 180 splice_buffers_index_(0),
175 pending_buffers_complete_(false), 181 pending_buffers_complete_(false),
176 splice_frames_enabled_(splice_frames_enabled), 182 splice_frames_enabled_(splice_frames_enabled),
177 num_splice_generation_warning_logs_(0), 183 num_splice_generation_warning_logs_(0),
178 num_splice_generation_success_logs_(0) { 184 num_splice_generation_success_logs_(0),
185 num_track_buffer_gap_warning_logs_(0) {
179 DCHECK(video_config.IsValidConfig()); 186 DCHECK(video_config.IsValidConfig());
180 video_configs_.push_back(video_config); 187 video_configs_.push_back(video_config);
181 } 188 }
182 189
183 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 190 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
184 const scoped_refptr<MediaLog>& media_log, 191 const scoped_refptr<MediaLog>& media_log,
185 bool splice_frames_enabled) 192 bool splice_frames_enabled)
186 : media_log_(media_log), 193 : media_log_(media_log),
187 current_config_index_(0), 194 current_config_index_(0),
188 append_config_index_(0), 195 append_config_index_(0),
189 text_track_config_(text_config), 196 text_track_config_(text_config),
190 seek_pending_(false), 197 seek_pending_(false),
191 end_of_stream_(false), 198 end_of_stream_(false),
192 seek_buffer_timestamp_(kNoTimestamp()), 199 seek_buffer_timestamp_(kNoTimestamp()),
193 selected_range_(NULL), 200 selected_range_(NULL),
201 just_exhausted_track_buffer_(false),
194 media_segment_start_time_(kNoDecodeTimestamp()), 202 media_segment_start_time_(kNoDecodeTimestamp()),
195 range_for_next_append_(ranges_.end()), 203 range_for_next_append_(ranges_.end()),
196 new_media_segment_(false), 204 new_media_segment_(false),
197 last_appended_buffer_timestamp_(kNoDecodeTimestamp()), 205 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
198 last_appended_buffer_is_keyframe_(false), 206 last_appended_buffer_is_keyframe_(false),
199 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 207 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
200 max_interbuffer_distance_(kNoTimestamp()), 208 max_interbuffer_distance_(kNoTimestamp()),
201 memory_limit_(kSourceBufferAudioMemoryLimit), 209 memory_limit_(kSourceBufferAudioMemoryLimit),
202 config_change_pending_(false), 210 config_change_pending_(false),
203 splice_buffers_index_(0), 211 splice_buffers_index_(0),
204 pending_buffers_complete_(false), 212 pending_buffers_complete_(false),
205 splice_frames_enabled_(splice_frames_enabled), 213 splice_frames_enabled_(splice_frames_enabled),
206 num_splice_generation_warning_logs_(0), 214 num_splice_generation_warning_logs_(0),
207 num_splice_generation_success_logs_(0) {} 215 num_splice_generation_success_logs_(0),
216 num_track_buffer_gap_warning_logs_(0) {}
208 217
209 SourceBufferStream::~SourceBufferStream() { 218 SourceBufferStream::~SourceBufferStream() {
210 while (!ranges_.empty()) { 219 while (!ranges_.empty()) {
211 delete ranges_.front(); 220 delete ranges_.front();
212 ranges_.pop_front(); 221 ranges_.pop_front();
213 } 222 }
214 } 223 }
215 224
216 void SourceBufferStream::OnNewMediaSegment( 225 void SourceBufferStream::OnNewMediaSegment(
217 DecodeTimestamp media_segment_start_time) { 226 DecodeTimestamp media_segment_start_time) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 535
527 DCHECK(IsRangeListSorted(ranges_)); 536 DCHECK(IsRangeListSorted(ranges_));
528 DCHECK(OnlySelectedRangeIsSeeked()); 537 DCHECK(OnlySelectedRangeIsSeeked());
529 } 538 }
530 539
531 void SourceBufferStream::ResetSeekState() { 540 void SourceBufferStream::ResetSeekState() {
532 SetSelectedRange(NULL); 541 SetSelectedRange(NULL);
533 track_buffer_.clear(); 542 track_buffer_.clear();
534 config_change_pending_ = false; 543 config_change_pending_ = false;
535 last_output_buffer_timestamp_ = kNoDecodeTimestamp(); 544 last_output_buffer_timestamp_ = kNoDecodeTimestamp();
545 just_exhausted_track_buffer_ = false;
536 splice_buffers_index_ = 0; 546 splice_buffers_index_ = 0;
537 pending_buffer_ = NULL; 547 pending_buffer_ = NULL;
538 pending_buffers_complete_ = false; 548 pending_buffers_complete_ = false;
539 } 549 }
540 550
541 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 551 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
542 base::TimeDelta seek_timestamp) const { 552 base::TimeDelta seek_timestamp) const {
543 if (ranges_.empty()) 553 if (ranges_.empty())
544 return false; 554 return false;
545 base::TimeDelta beginning_of_buffered = 555 base::TimeDelta beginning_of_buffered =
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 return kConfigChange; 1143 return kConfigChange;
1134 } 1144 }
1135 1145
1136 DVLOG(3) << __FUNCTION__ << " Next buffer coming from track_buffer_"; 1146 DVLOG(3) << __FUNCTION__ << " Next buffer coming from track_buffer_";
1137 *out_buffer = next_buffer; 1147 *out_buffer = next_buffer;
1138 track_buffer_.pop_front(); 1148 track_buffer_.pop_front();
1139 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1149 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
1140 1150
1141 // If the track buffer becomes empty, then try to set the selected range 1151 // If the track buffer becomes empty, then try to set the selected range
1142 // based on the timestamp of this buffer being returned. 1152 // based on the timestamp of this buffer being returned.
1143 if (track_buffer_.empty()) 1153 if (track_buffer_.empty()) {
1154 just_exhausted_track_buffer_ = true;
1144 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_); 1155 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_);
1156 }
1145 1157
1146 return kSuccess; 1158 return kSuccess;
1147 } 1159 }
1148 1160
1149 DCHECK(track_buffer_.empty()); 1161 DCHECK(track_buffer_.empty());
1150 if (!selected_range_ || !selected_range_->HasNextBuffer()) { 1162 if (!selected_range_ || !selected_range_->HasNextBuffer()) {
1151 if (IsEndOfStreamReached()) { 1163 if (IsEndOfStreamReached()) {
1152 return kEndOfStream; 1164 return kEndOfStream;
1153 } 1165 }
1154 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName() 1166 DVLOG(3) << __FUNCTION__ << " " << GetStreamTypeName()
1155 << ": returning kNeedBuffer " 1167 << ": returning kNeedBuffer "
1156 << (selected_range_ ? "(selected range has no next buffer)" 1168 << (selected_range_ ? "(selected range has no next buffer)"
1157 : "(no selected range)"); 1169 : "(no selected range)");
1158 return kNeedBuffer; 1170 return kNeedBuffer;
1159 } 1171 }
1160 1172
1161 if (selected_range_->GetNextConfigId() != current_config_index_) { 1173 if (selected_range_->GetNextConfigId() != current_config_index_) {
1162 config_change_pending_ = true; 1174 config_change_pending_ = true;
1163 DVLOG(1) << "Config change (selected range config ID does not match)."; 1175 DVLOG(1) << "Config change (selected range config ID does not match).";
1164 return kConfigChange; 1176 return kConfigChange;
1165 } 1177 }
1166 1178
1167 CHECK(selected_range_->GetNextBuffer(out_buffer)); 1179 CHECK(selected_range_->GetNextBuffer(out_buffer));
1180
1181 DecodeTimestamp next_output_buffer_timestamp =
1182 (*out_buffer)->GetDecodeTimestamp();
1183 if (just_exhausted_track_buffer_) {
1184 DCHECK((*out_buffer)->is_key_frame());
1185 just_exhausted_track_buffer_ = false;
1186 base::TimeDelta delta =
1187 next_output_buffer_timestamp - last_output_buffer_timestamp_;
1188 DCHECK_GE(delta, base::TimeDelta());
1189 if (delta > GetMaxInterbufferDistance()) {
1190 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_track_buffer_gap_warning_logs_,
1191 kMaxTrackBufferGapWarningLogs)
1192 << "Media append that overlapped current playback position caused "
1193 "time gap in playing "
1194 << GetStreamTypeName() << " stream because the next keyframe is "
1195 << delta.InMilliseconds() << "ms beyond last overlapped frame. Media "
1196 "may appear temporarily frozen.";
1197 }
1198 }
1199
1168 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp(); 1200 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
1169 return kSuccess; 1201 return kSuccess;
1170 } 1202 }
1171 1203
1172 DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() { 1204 DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() {
1173 if (!track_buffer_.empty()) 1205 if (!track_buffer_.empty())
1174 return track_buffer_.front()->GetDecodeTimestamp(); 1206 return track_buffer_.front()->GetDecodeTimestamp();
1175 1207
1176 if (!selected_range_) 1208 if (!selected_range_)
1177 return kNoDecodeTimestamp(); 1209 return kNoDecodeTimestamp();
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 return false; 1699 return false;
1668 1700
1669 DCHECK_NE(have_splice_buffers, have_preroll_buffer); 1701 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1670 splice_buffers_index_ = 0; 1702 splice_buffers_index_ = 0;
1671 pending_buffer_.swap(*out_buffer); 1703 pending_buffer_.swap(*out_buffer);
1672 pending_buffers_complete_ = false; 1704 pending_buffers_complete_ = false;
1673 return true; 1705 return true;
1674 } 1706 }
1675 1707
1676 } // namespace media 1708 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698