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

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

Issue 1670033002: Reland: MSE: Relax the 'media segment must begin with keyframe' requirement (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes and tests for bugs 581125 and 581458, which caused previous attempt to be reverted Created 4 years, 10 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) 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 19 matching lines...) Expand all
30 // important for debugging splice generation. 30 // important for debugging splice generation.
31 const int kMaxSpliceGenerationWarningLogs = 50; 31 const int kMaxSpliceGenerationWarningLogs = 50;
32 const int kMaxSpliceGenerationSuccessLogs = 20; 32 const int kMaxSpliceGenerationSuccessLogs = 20;
33 33
34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps. 34 // Limit the number of MEDIA_LOG() logs for track buffer time gaps.
35 const int kMaxTrackBufferGapWarningLogs = 20; 35 const int kMaxTrackBufferGapWarningLogs = 20;
36 36
37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings. 37 // Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20; 38 const int kMaxGarbageCollectAlgorithmWarningLogs = 20;
39 39
40 // Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed
41 // by keyframe. Prior to relaxing the "media segments must begin with a
42 // keyframe" requirement, we issued decode error for this situation. That was
43 // likely too strict, and now that the keyframe requirement is relaxed, we have
44 // no knowledge of media segment boundaries here. Now, we log but don't trigger
45 // decode error, since we allow these sequences which may cause extra decoder
46 // work or other side-effects.
47 const int kMaxStrangeSameTimestampsLogs = 20;
48
40 // Helper method that returns true if |ranges| is sorted in increasing order, 49 // Helper method that returns true if |ranges| is sorted in increasing order,
41 // false otherwise. 50 // false otherwise.
42 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) { 51 bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) {
43 DecodeTimestamp prev = kNoDecodeTimestamp(); 52 DecodeTimestamp prev = kNoDecodeTimestamp();
44 for (std::list<SourceBufferRange*>::const_iterator itr = 53 for (std::list<SourceBufferRange*>::const_iterator itr =
45 ranges.begin(); itr != ranges.end(); ++itr) { 54 ranges.begin(); itr != ranges.end(); ++itr) {
46 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp()) 55 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
47 return false; 56 return false;
48 prev = (*itr)->GetEndTimestamp(); 57 prev = (*itr)->GetEndTimestamp();
49 } 58 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 return SourceBufferRange::NO_GAPS_ALLOWED; 139 return SourceBufferRange::NO_GAPS_ALLOWED;
131 } 140 }
132 141
133 } // namespace 142 } // namespace
134 143
135 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config, 144 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
136 const scoped_refptr<MediaLog>& media_log, 145 const scoped_refptr<MediaLog>& media_log,
137 bool splice_frames_enabled) 146 bool splice_frames_enabled)
138 : media_log_(media_log), 147 : media_log_(media_log),
139 seek_buffer_timestamp_(kNoTimestamp()), 148 seek_buffer_timestamp_(kNoTimestamp()),
140 media_segment_start_time_(kNoDecodeTimestamp()), 149 coded_frame_group_start_time_(kNoDecodeTimestamp()),
141 range_for_next_append_(ranges_.end()), 150 range_for_next_append_(ranges_.end()),
142 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 151 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
143 max_interbuffer_distance_(kNoTimestamp()), 152 max_interbuffer_distance_(kNoTimestamp()),
144 memory_limit_(kSourceBufferAudioMemoryLimit), 153 memory_limit_(kSourceBufferAudioMemoryLimit),
145 splice_frames_enabled_(splice_frames_enabled) { 154 splice_frames_enabled_(splice_frames_enabled) {
146 DCHECK(audio_config.IsValidConfig()); 155 DCHECK(audio_config.IsValidConfig());
147 audio_configs_.push_back(audio_config); 156 audio_configs_.push_back(audio_config);
148 } 157 }
149 158
150 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, 159 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
151 const scoped_refptr<MediaLog>& media_log, 160 const scoped_refptr<MediaLog>& media_log,
152 bool splice_frames_enabled) 161 bool splice_frames_enabled)
153 : media_log_(media_log), 162 : media_log_(media_log),
154 seek_buffer_timestamp_(kNoTimestamp()), 163 seek_buffer_timestamp_(kNoTimestamp()),
155 media_segment_start_time_(kNoDecodeTimestamp()), 164 coded_frame_group_start_time_(kNoDecodeTimestamp()),
156 range_for_next_append_(ranges_.end()), 165 range_for_next_append_(ranges_.end()),
157 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 166 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
158 max_interbuffer_distance_(kNoTimestamp()), 167 max_interbuffer_distance_(kNoTimestamp()),
159 memory_limit_(kSourceBufferVideoMemoryLimit), 168 memory_limit_(kSourceBufferVideoMemoryLimit),
160 splice_frames_enabled_(splice_frames_enabled) { 169 splice_frames_enabled_(splice_frames_enabled) {
161 DCHECK(video_config.IsValidConfig()); 170 DCHECK(video_config.IsValidConfig());
162 video_configs_.push_back(video_config); 171 video_configs_.push_back(video_config);
163 } 172 }
164 173
165 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config, 174 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
166 const scoped_refptr<MediaLog>& media_log, 175 const scoped_refptr<MediaLog>& media_log,
167 bool splice_frames_enabled) 176 bool splice_frames_enabled)
168 : media_log_(media_log), 177 : media_log_(media_log),
169 text_track_config_(text_config), 178 text_track_config_(text_config),
170 seek_buffer_timestamp_(kNoTimestamp()), 179 seek_buffer_timestamp_(kNoTimestamp()),
171 media_segment_start_time_(kNoDecodeTimestamp()), 180 coded_frame_group_start_time_(kNoDecodeTimestamp()),
172 range_for_next_append_(ranges_.end()), 181 range_for_next_append_(ranges_.end()),
173 last_output_buffer_timestamp_(kNoDecodeTimestamp()), 182 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
174 max_interbuffer_distance_(kNoTimestamp()), 183 max_interbuffer_distance_(kNoTimestamp()),
175 memory_limit_(kSourceBufferAudioMemoryLimit), 184 memory_limit_(kSourceBufferAudioMemoryLimit),
176 splice_frames_enabled_(splice_frames_enabled) {} 185 splice_frames_enabled_(splice_frames_enabled) {}
177 186
178 SourceBufferStream::~SourceBufferStream() { 187 SourceBufferStream::~SourceBufferStream() {
179 while (!ranges_.empty()) { 188 while (!ranges_.empty()) {
180 delete ranges_.front(); 189 delete ranges_.front();
181 ranges_.pop_front(); 190 ranges_.pop_front();
182 } 191 }
183 } 192 }
184 193
185 void SourceBufferStream::OnNewMediaSegment( 194 void SourceBufferStream::OnStartOfCodedFrameGroup(
186 DecodeTimestamp media_segment_start_time) { 195 DecodeTimestamp coded_frame_group_start_time) {
187 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() 196 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << " ("
188 << " (" << media_segment_start_time.InSecondsF() << ")"; 197 << coded_frame_group_start_time.InSecondsF() << ")";
189 DCHECK(!end_of_stream_); 198 DCHECK(!end_of_stream_);
190 media_segment_start_time_ = media_segment_start_time; 199 coded_frame_group_start_time_ = coded_frame_group_start_time;
191 new_media_segment_ = true; 200 new_coded_frame_group_ = true;
192 201
193 RangeList::iterator last_range = range_for_next_append_; 202 RangeList::iterator last_range = range_for_next_append_;
194 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); 203 range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time);
195 204
196 // Only reset |last_appended_buffer_timestamp_| if this new media segment is 205 // Only reset |last_appended_buffer_timestamp_| if this new coded frame group
197 // not adjacent to the previous media segment appended to the stream. 206 // is not adjacent to the previous coded frame group appended to the stream.
198 if (range_for_next_append_ == ranges_.end() || 207 if (range_for_next_append_ == ranges_.end() ||
199 !AreAdjacentInSequence(last_appended_buffer_timestamp_, 208 !AreAdjacentInSequence(last_appended_buffer_timestamp_,
200 media_segment_start_time)) { 209 coded_frame_group_start_time)) {
201 last_appended_buffer_timestamp_ = kNoDecodeTimestamp(); 210 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
202 last_appended_buffer_duration_ = kNoTimestamp(); 211 last_appended_buffer_duration_ = kNoTimestamp();
203 last_appended_buffer_is_keyframe_ = false; 212 last_appended_buffer_is_keyframe_ = false;
204 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range"; 213 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range";
205 } else if (last_range != ranges_.end()) { 214 } else if (last_range != ranges_.end()) {
206 DCHECK(last_range == range_for_next_append_); 215 DCHECK(last_range == range_for_next_append_);
207 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range " 216 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range "
208 << "unless intervening remove makes discontinuity"; 217 << "unless intervening remove makes discontinuity";
209 } 218 }
210 } 219 }
211 220
212 bool SourceBufferStream::Append(const BufferQueue& buffers) { 221 bool SourceBufferStream::Append(const BufferQueue& buffers) {
213 TRACE_EVENT2("media", "SourceBufferStream::Append", 222 TRACE_EVENT2("media", "SourceBufferStream::Append",
214 "stream type", GetStreamTypeName(), 223 "stream type", GetStreamTypeName(),
215 "buffers to append", buffers.size()); 224 "buffers to append", buffers.size());
216 225
217 DCHECK(!buffers.empty()); 226 DCHECK(!buffers.empty());
218 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); 227 DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
219 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); 228 DCHECK(coded_frame_group_start_time_ <=
229 buffers.front()->GetDecodeTimestamp());
220 DCHECK(!end_of_stream_); 230 DCHECK(!end_of_stream_);
221 231
222 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() 232 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName()
223 << ": buffers " << BufferQueueToLogString(buffers); 233 << ": buffers " << BufferQueueToLogString(buffers);
224 234
225 // New media segments must begin with a keyframe. 235 // New coded frame groups emitted by the coded frame processor must begin with
226 // TODO(wolenetz): Relax this requirement. See http://crbug.com/229412. 236 // a keyframe. TODO(wolenetz): Change this to [DCHECK + MEDIA_LOG(ERROR...) +
227 if (new_media_segment_ && !buffers.front()->is_key_frame()) { 237 // return false] once the CHECK has baked in a stable release. See
228 MEDIA_LOG(ERROR, media_log_) << "Media segment did not begin with key " 238 // https://crbug.com/580621.
229 "frame. Support for such segments will be " 239 CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame());
230 "available in a future version. Please see " 240
231 "https://crbug.com/229412."; 241 // Buffers within a coded frame group should be monotonically increasing.
wolenetz 2016/02/05 23:27:24 Note that IsMonotonicallyIncreasing() does the sam
chcunningham 2016/02/09 00:21:08 Acknowledged.
242 if (!IsMonotonicallyIncreasing(buffers)) {
232 return false; 243 return false;
233 } 244 }
234 245
235 // Buffers within a media segment should be monotonically increasing. 246 if (coded_frame_group_start_time_ < DecodeTimestamp() ||
236 if (!IsMonotonicallyIncreasing(buffers))
237 return false;
238
239 if (media_segment_start_time_ < DecodeTimestamp() ||
240 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { 247 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) {
241 MEDIA_LOG(ERROR, media_log_) 248 MEDIA_LOG(ERROR, media_log_)
242 << "Cannot append a media segment with negative timestamps."; 249 << "Cannot append a coded frame group with negative timestamps.";
243 return false; 250 return false;
244 } 251 }
245 252
246 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(),
247 buffers.front()->is_key_frame())) {
248 const DecodeTimestamp& dts = buffers.front()->GetDecodeTimestamp();
249 MEDIA_LOG(ERROR, media_log_)
250 << "Invalid same timestamp construct detected at"
251 << " time " << dts.InSecondsF();
252
253 return false;
254 }
255
256 UpdateMaxInterbufferDistance(buffers); 253 UpdateMaxInterbufferDistance(buffers);
257 SetConfigIds(buffers); 254 SetConfigIds(buffers);
258 255
259 // Save a snapshot of stream state before range modifications are made. 256 // Save a snapshot of stream state before range modifications are made.
260 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); 257 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
261 BufferQueue deleted_buffers; 258 BufferQueue deleted_buffers;
262 259
263 PrepareRangesForNextAppend(buffers, &deleted_buffers); 260 PrepareRangesForNextAppend(buffers, &deleted_buffers);
264 261
265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 262 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
266 // create a new range with |buffers|. 263 // create a new range with |buffers|.
267 if (range_for_next_append_ != ranges_.end()) { 264 if (range_for_next_append_ != ranges_.end()) {
268 (*range_for_next_append_)->AppendBuffersToEnd(buffers); 265 (*range_for_next_append_)->AppendBuffersToEnd(buffers);
269 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 266 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
270 last_appended_buffer_duration_ = buffers.back()->duration(); 267 last_appended_buffer_duration_ = buffers.back()->duration();
271 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); 268 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
272 } else { 269 } else {
273 DecodeTimestamp new_range_start_time = std::min( 270 DecodeTimestamp new_range_start_time = std::min(
274 media_segment_start_time_, buffers.front()->GetDecodeTimestamp()); 271 coded_frame_group_start_time_, buffers.front()->GetDecodeTimestamp());
275 const BufferQueue* buffers_for_new_range = &buffers; 272 const BufferQueue* buffers_for_new_range = &buffers;
276 BufferQueue trimmed_buffers; 273 BufferQueue trimmed_buffers;
277 274
278 // If the new range is not being created because of a new media 275 // If the new range is not being created because of a new coded frame group,
279 // segment, then we must make sure that we start with a key frame. 276 // then we must make sure that we start with a key frame. This can happen
280 // This can happen if the GOP in the previous append gets destroyed 277 // if the GOP in the previous append gets destroyed by a Remove() call.
281 // by a Remove() call. 278 if (!new_coded_frame_group_) {
282 if (!new_media_segment_) {
283 BufferQueue::const_iterator itr = buffers.begin(); 279 BufferQueue::const_iterator itr = buffers.begin();
284 280
285 // Scan past all the non-key-frames. 281 // Scan past all the non-key-frames.
286 while (itr != buffers.end() && !(*itr)->is_key_frame()) { 282 while (itr != buffers.end() && !(*itr)->is_key_frame()) {
287 ++itr; 283 ++itr;
288 } 284 }
289 285
290 // If we didn't find a key frame, then update the last appended 286 // If we didn't find a key frame, then update the last appended
291 // buffer state and return. 287 // buffer state and return.
292 if (itr == buffers.end()) { 288 if (itr == buffers.end()) {
293 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); 289 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
294 last_appended_buffer_duration_ = buffers.back()->duration(); 290 last_appended_buffer_duration_ = buffers.back()->duration();
295 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); 291 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
296 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() 292 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName()
297 << ": new buffers in the middle of media segment depend on" 293 << ": new buffers in the middle of coded frame group depend on"
298 "keyframe that has been removed, and contain no keyframes." 294 "keyframe that has been removed, and contain no keyframes."
299 "Skipping further processing."; 295 "Skipping further processing.";
300 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() 296 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName()
301 << ": done. ranges_=" << RangesToString(ranges_); 297 << ": done. ranges_=" << RangesToString(ranges_);
302 return true; 298 return true;
303 } else if (itr != buffers.begin()) { 299 } else if (itr != buffers.begin()) {
304 // Copy the first key frame and everything after it into 300 // Copy the first key frame and everything after it into
305 // |trimmed_buffers|. 301 // |trimmed_buffers|.
306 trimmed_buffers.assign(itr, buffers.end()); 302 trimmed_buffers.assign(itr, buffers.end());
307 buffers_for_new_range = &trimmed_buffers; 303 buffers_for_new_range = &trimmed_buffers;
308 } 304 }
309 305
310 new_range_start_time = 306 new_range_start_time =
311 buffers_for_new_range->front()->GetDecodeTimestamp(); 307 buffers_for_new_range->front()->GetDecodeTimestamp();
312 } 308 }
313 309
314 range_for_next_append_ = 310 range_for_next_append_ =
315 AddToRanges(new SourceBufferRange( 311 AddToRanges(new SourceBufferRange(
316 TypeToGapPolicy(GetType()), 312 TypeToGapPolicy(GetType()),
317 *buffers_for_new_range, new_range_start_time, 313 *buffers_for_new_range, new_range_start_time,
318 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, 314 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
319 base::Unretained(this)))); 315 base::Unretained(this))));
320 last_appended_buffer_timestamp_ = 316 last_appended_buffer_timestamp_ =
321 buffers_for_new_range->back()->GetDecodeTimestamp(); 317 buffers_for_new_range->back()->GetDecodeTimestamp();
322 last_appended_buffer_duration_ = buffers_for_new_range->back()->duration(); 318 last_appended_buffer_duration_ = buffers_for_new_range->back()->duration();
323 last_appended_buffer_is_keyframe_ = 319 last_appended_buffer_is_keyframe_ =
324 buffers_for_new_range->back()->is_key_frame(); 320 buffers_for_new_range->back()->is_key_frame();
325 } 321 }
326 322
327 new_media_segment_ = false; 323 new_coded_frame_group_ = false;
328 324
329 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); 325 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
330 326
331 // Seek to try to fulfill a previous call to Seek(). 327 // Seek to try to fulfill a previous call to Seek().
332 if (seek_pending_) { 328 if (seek_pending_) {
333 DCHECK(!selected_range_); 329 DCHECK(!selected_range_);
334 DCHECK(deleted_buffers.empty()); 330 DCHECK(deleted_buffers.empty());
335 Seek(seek_buffer_timestamp_); 331 Seek(seek_buffer_timestamp_);
336 } 332 }
337 333
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 while (itr != ranges_.end()) { 429 while (itr != ranges_.end()) {
434 SourceBufferRange* range = *itr; 430 SourceBufferRange* range = *itr;
435 if (range->GetStartTimestamp() >= end) 431 if (range->GetStartTimestamp() >= end)
436 break; 432 break;
437 433
438 // Split off any remaining GOPs starting at or after |end| and add it to 434 // Split off any remaining GOPs starting at or after |end| and add it to
439 // |ranges_|. 435 // |ranges_|.
440 SourceBufferRange* new_range = range->SplitRange(end); 436 SourceBufferRange* new_range = range->SplitRange(end);
441 if (new_range) { 437 if (new_range) {
442 itr = ranges_.insert(++itr, new_range); 438 itr = ranges_.insert(++itr, new_range);
439
440 // Update |range_for_next_append_| if it was previously |range| and should
wolenetz 2016/02/05 23:27:24 Note: this is the core of the fix for crbug 581458
chcunningham 2016/02/09 00:21:08 Acknowledged.
441 // be |new_range| now.
442 if (range_for_next_append_ != ranges_.end() &&
443 *range_for_next_append_ == range &&
444 last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
chcunningham 2016/02/09 00:21:08 I'm wondering about the case where we've just gott
wolenetz 2016/02/09 00:47:19 I'll need to grok this a little more. I'll get an
wolenetz 2016/02/09 01:36:41 Great comment, Chris! We've never tested any case
wolenetz 2016/02/12 01:23:47 Done. (as of patch set #5)
445 DecodeTimestamp potential_next_append_timestamp =
446 last_appended_buffer_timestamp_ +
447 base::TimeDelta::FromInternalValue(1);
448 if (new_range->BelongsToRange(potential_next_append_timestamp))
449 range_for_next_append_ = itr;
450 }
451
443 --itr; 452 --itr;
444 453
445 // Update the selected range if the next buffer position was transferred 454 // Update the selected range if the next buffer position was transferred
446 // to |new_range|. 455 // to |new_range|.
447 if (new_range->HasNextBufferPosition()) 456 if (new_range->HasNextBufferPosition())
448 SetSelectedRange(new_range); 457 SetSelectedRange(new_range);
449 } 458 }
450 459
451 // Truncate the current range so that it only contains data before 460 // Truncate the current range so that it only contains data before
452 // the removal range. 461 // the removal range.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 524 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
516 base::TimeDelta seek_timestamp) const { 525 base::TimeDelta seek_timestamp) const {
517 if (ranges_.empty()) 526 if (ranges_.empty())
518 return false; 527 return false;
519 base::TimeDelta beginning_of_buffered = 528 base::TimeDelta beginning_of_buffered =
520 ranges_.front()->GetStartTimestamp().ToPresentationTime(); 529 ranges_.front()->GetStartTimestamp().ToPresentationTime();
521 return (seek_timestamp <= beginning_of_buffered && 530 return (seek_timestamp <= beginning_of_buffered &&
522 beginning_of_buffered < kSeekToStartFudgeRoom()); 531 beginning_of_buffered < kSeekToStartFudgeRoom());
523 } 532 }
524 533
525 bool SourceBufferStream::IsMonotonicallyIncreasing( 534 bool SourceBufferStream::IsMonotonicallyIncreasing(const BufferQueue& buffers) {
526 const BufferQueue& buffers) const {
527 DCHECK(!buffers.empty()); 535 DCHECK(!buffers.empty());
528 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 536 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
529 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; 537 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
530 for (BufferQueue::const_iterator itr = buffers.begin(); 538 for (BufferQueue::const_iterator itr = buffers.begin();
531 itr != buffers.end(); ++itr) { 539 itr != buffers.end(); ++itr) {
532 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); 540 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
533 bool current_is_keyframe = (*itr)->is_key_frame(); 541 bool current_is_keyframe = (*itr)->is_key_frame();
534 DCHECK(current_timestamp != kNoDecodeTimestamp()); 542 DCHECK(current_timestamp != kNoDecodeTimestamp());
535 DCHECK((*itr)->duration() >= base::TimeDelta()) 543 DCHECK((*itr)->duration() >= base::TimeDelta())
536 << "Packet with invalid duration." 544 << "Packet with invalid duration."
537 << " pts " << (*itr)->timestamp().InSecondsF() 545 << " pts " << (*itr)->timestamp().InSecondsF()
538 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() 546 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF()
539 << " dur " << (*itr)->duration().InSecondsF(); 547 << " dur " << (*itr)->duration().InSecondsF();
540 548
541 if (prev_timestamp != kNoDecodeTimestamp()) { 549 if (prev_timestamp != kNoDecodeTimestamp()) {
542 if (current_timestamp < prev_timestamp) { 550 if (current_timestamp < prev_timestamp) {
543 MEDIA_LOG(ERROR, media_log_) 551 MEDIA_LOG(ERROR, media_log_)
544 << "Buffers did not monotonically increase."; 552 << "Buffers did not monotonically increase.";
545 return false; 553 return false;
546 } 554 }
547 555
548 if (current_timestamp == prev_timestamp && 556 if (current_timestamp == prev_timestamp &&
549 !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, 557 SourceBufferRange::IsUncommonSameTimestampSequence(
wolenetz 2016/02/05 23:27:24 Note, this is the core of the fix for crbug 581125
chcunningham 2016/02/09 00:21:08 Acknowledged.
550 current_is_keyframe)) { 558 prev_is_keyframe, current_is_keyframe)) {
551 MEDIA_LOG(ERROR, media_log_) << "Unexpected combination of buffers with" 559 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_strange_same_timestamps_logs_,
552 << " the same timestamp detected at " 560 kMaxStrangeSameTimestampsLogs)
553 << current_timestamp.InSecondsF(); 561 << "Detected an append sequence with keyframe following a "
554 return false; 562 "non-keyframe, both with the same decode timestamp of "
563 << current_timestamp.InSecondsF();
555 } 564 }
556 } 565 }
557 566
558 prev_timestamp = current_timestamp; 567 prev_timestamp = current_timestamp;
559 prev_is_keyframe = current_is_keyframe; 568 prev_is_keyframe = current_is_keyframe;
560 } 569 }
561 return true; 570 return true;
562 } 571 }
563 572
564 bool SourceBufferStream::IsNextTimestampValid(
565 DecodeTimestamp next_timestamp, bool next_is_keyframe) const {
566 return (last_appended_buffer_timestamp_ != next_timestamp) ||
567 new_media_segment_ ||
568 SourceBufferRange::AllowSameTimestamp(last_appended_buffer_is_keyframe_,
569 next_is_keyframe);
570 }
571
572
573 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { 573 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
574 for (RangeList::const_iterator itr = ranges_.begin(); 574 for (RangeList::const_iterator itr = ranges_.begin();
575 itr != ranges_.end(); ++itr) { 575 itr != ranges_.end(); ++itr) {
576 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) 576 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
577 return false; 577 return false;
578 } 578 }
579 return !selected_range_ || selected_range_->HasNextBufferPosition(); 579 return !selected_range_ || selected_range_->HasNextBufferPosition();
580 } 580 }
581 581
582 void SourceBufferStream::UpdateMaxInterbufferDistance( 582 void SourceBufferStream::UpdateMaxInterbufferDistance(
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { 920 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
921 DCHECK(deleted_buffers); 921 DCHECK(deleted_buffers);
922 922
923 // Handle splices between the existing buffers and the new buffers. If a 923 // Handle splices between the existing buffers and the new buffers. If a
924 // splice is generated the timestamp and duration of the first buffer in 924 // splice is generated the timestamp and duration of the first buffer in
925 // |new_buffers| will be modified. 925 // |new_buffers| will be modified.
926 if (splice_frames_enabled_) 926 if (splice_frames_enabled_)
927 GenerateSpliceFrame(new_buffers); 927 GenerateSpliceFrame(new_buffers);
928 928
929 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; 929 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
930 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
931 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); 930 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
932 bool next_is_keyframe = new_buffers.front()->is_key_frame();
933 931
934 if (prev_timestamp != kNoDecodeTimestamp() && 932 if (prev_timestamp != kNoDecodeTimestamp() &&
935 prev_timestamp != next_timestamp) { 933 prev_timestamp != next_timestamp) {
936 // Clean up the old buffers between the last appended buffer and the 934 // Clean up the old buffers between the last appended buffer and the
937 // beginning of |new_buffers|. 935 // beginning of |new_buffers|.
938 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); 936 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
939 } 937 }
940 938
941 // Make the delete range exclusive if we are dealing with an allowed same 939 // Always make the start of the delete range exclusive for same timestamp
942 // timestamp situation. This prevents the first buffer in the current append 940 // across the last buffer in the previous append and the first buffer in the
943 // from deleting the last buffer in the previous append if both buffers 941 // current append. Never be exclusive if a splice frame was generated because
chcunningham 2016/02/09 00:21:08 Does the splice buffers check really make sense he
wolenetz 2016/02/09 00:47:19 Hmm. PrepareRangesForNextAppend() actually calls G
wolenetz 2016/02/12 01:23:47 From chat, this is fodder for a low pri later CL.
944 // have the same timestamp. 942 // we don't generate splice frames for same timestamp situations.
945 //
946 // The delete range should never be exclusive if a splice frame was generated
947 // because we don't generate splice frames for same timestamp situations.
948 DCHECK(new_buffers.front()->splice_timestamp() != 943 DCHECK(new_buffers.front()->splice_timestamp() !=
949 new_buffers.front()->timestamp()); 944 new_buffers.front()->timestamp());
950 const bool exclude_start = 945 const bool exclude_start = new_buffers.front()->splice_buffers().empty() &&
951 new_buffers.front()->splice_buffers().empty() && 946 prev_timestamp == next_timestamp;
952 prev_timestamp == next_timestamp &&
953 SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, next_is_keyframe);
954 947
955 // Delete the buffers that |new_buffers| overlaps. 948 // Delete the buffers that |new_buffers| overlaps.
956 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp(); 949 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
957 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp(); 950 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
958 base::TimeDelta duration = new_buffers.back()->duration(); 951 base::TimeDelta duration = new_buffers.back()->duration();
959 952
960 // Set end time for remove to include the duration of last buffer. If the 953 // Set end time for remove to include the duration of last buffer. If the
961 // duration is estimated, use 1 microsecond instead to ensure frames are not 954 // duration is estimated, use 1 microsecond instead to ensure frames are not
962 // accidentally removed due to over-estimation. 955 // accidentally removed due to over-estimation.
963 if (duration != kNoTimestamp() && duration > base::TimeDelta() && 956 if (duration != kNoTimestamp() && duration > base::TimeDelta() &&
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 return false; 1775 return false;
1783 1776
1784 DCHECK_NE(have_splice_buffers, have_preroll_buffer); 1777 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
1785 splice_buffers_index_ = 0; 1778 splice_buffers_index_ = 0;
1786 pending_buffer_.swap(*out_buffer); 1779 pending_buffer_.swap(*out_buffer);
1787 pending_buffers_complete_ = false; 1780 pending_buffers_complete_ = false;
1788 return true; 1781 return true;
1789 } 1782 }
1790 1783
1791 } // namespace media 1784 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698