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

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

Issue 1692403002: MSE - Fix crash caused by incorrect GC of GOP with next buffer position (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « media/filters/source_buffer_range.h ('k') | media/filters/source_buffer_stream.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_range.h" 5 #include "media/filters/source_buffer_range.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "media/base/timestamp_constants.h" 9 #include "media/base/timestamp_constants.h"
10 10
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 bool SourceBufferRange::TruncateAt( 224 bool SourceBufferRange::TruncateAt(
225 DecodeTimestamp timestamp, BufferQueue* removed_buffers, 225 DecodeTimestamp timestamp, BufferQueue* removed_buffers,
226 bool is_exclusive) { 226 bool is_exclusive) {
227 // Find the place in |buffers_| where we will begin deleting data. 227 // Find the place in |buffers_| where we will begin deleting data.
228 BufferQueue::iterator starting_point = 228 BufferQueue::iterator starting_point =
229 GetBufferItrAt(timestamp, is_exclusive); 229 GetBufferItrAt(timestamp, is_exclusive);
230 return TruncateAt(starting_point, removed_buffers); 230 return TruncateAt(starting_point, removed_buffers);
231 } 231 }
232 232
233 size_t SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) { 233 size_t SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
234 DCHECK(!FirstGOPContainsNextBufferPosition()); 234 CHECK(!buffers_.empty());
235 CHECK(!FirstGOPContainsNextBufferPosition());
236
235 DCHECK(deleted_buffers); 237 DCHECK(deleted_buffers);
236 238
237 int buffers_deleted = 0; 239 int buffers_deleted = 0;
238 size_t total_bytes_deleted = 0; 240 size_t total_bytes_deleted = 0;
239 241
240 KeyframeMap::iterator front = keyframe_map_.begin(); 242 KeyframeMap::iterator front = keyframe_map_.begin();
241 DCHECK(front != keyframe_map_.end()); 243 DCHECK(front != keyframe_map_.end());
242 244
243 // Delete the keyframe at the start of |keyframe_map_|. 245 // Delete the keyframe at the start of |keyframe_map_|.
244 keyframe_map_.erase(front); 246 keyframe_map_.erase(front);
(...skipping 27 matching lines...) Expand all
272 274
273 // Invalidate media segment start time if we've deleted the first buffer of 275 // Invalidate media segment start time if we've deleted the first buffer of
274 // the range. 276 // the range.
275 if (buffers_deleted > 0) 277 if (buffers_deleted > 0)
276 media_segment_start_time_ = kNoDecodeTimestamp(); 278 media_segment_start_time_ = kNoDecodeTimestamp();
277 279
278 return total_bytes_deleted; 280 return total_bytes_deleted;
279 } 281 }
280 282
281 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { 283 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
282 DCHECK(!LastGOPContainsNextBufferPosition()); 284 CHECK(!buffers_.empty());
285 CHECK(!LastGOPContainsNextBufferPosition());
286
283 DCHECK(deleted_buffers); 287 DCHECK(deleted_buffers);
284 288
285 // Remove the last GOP's keyframe from the |keyframe_map_|. 289 // Remove the last GOP's keyframe from the |keyframe_map_|.
286 KeyframeMap::iterator back = keyframe_map_.end(); 290 KeyframeMap::iterator back = keyframe_map_.end();
287 DCHECK_GT(keyframe_map_.size(), 0u); 291 DCHECK_GT(keyframe_map_.size(), 0u);
288 --back; 292 --back;
289 293
290 // The index of the first buffer in the last GOP is equal to the new size of 294 // The index of the first buffer in the last GOP is equal to the new size of
291 // |buffers_| after that GOP is deleted. 295 // |buffers_| after that GOP is deleted.
292 size_t goal_size = back->second - keyframe_map_index_base_; 296 size_t goal_size = back->second - keyframe_map_index_base_;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 if (bytes_removed > 0) { 348 if (bytes_removed > 0) {
345 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? 349 *removal_end_timestamp = gop_itr == keyframe_map_.end() ?
346 GetBufferedEndTimestamp() : gop_itr->first; 350 GetBufferedEndTimestamp() : gop_itr->first;
347 } 351 }
348 return bytes_removed; 352 return bytes_removed;
349 } 353 }
350 354
351 bool SourceBufferRange::FirstGOPEarlierThanMediaTime( 355 bool SourceBufferRange::FirstGOPEarlierThanMediaTime(
352 DecodeTimestamp media_time) const { 356 DecodeTimestamp media_time) const {
353 if (keyframe_map_.size() == 1u) 357 if (keyframe_map_.size() == 1u)
354 return (GetEndTimestamp() < media_time); 358 return (GetEndTimestamp() < media_time);
wolenetz 2016/02/13 00:51:06 Alternatively, s/GetEndTimestamp()/GetBufferedEndT
chcunningham 2016/02/16 23:36:25 Acknowledged.
355 359
356 KeyframeMap::const_iterator second_gop = keyframe_map_.begin(); 360 KeyframeMap::const_iterator second_gop = keyframe_map_.begin();
357 ++second_gop; 361 ++second_gop;
358 return second_gop->first <= media_time; 362 return second_gop->first <= media_time;
359 } 363 }
360 364
361 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { 365 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const {
362 if (!HasNextBufferPosition()) 366 if (!HasNextBufferPosition())
363 return false; 367 return false;
364 368
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 return next_buffer_index_ >= 0; 473 return next_buffer_index_ >= 0;
470 } 474 }
471 475
472 void SourceBufferRange::ResetNextBufferPosition() { 476 void SourceBufferRange::ResetNextBufferPosition() {
473 next_buffer_index_ = -1; 477 next_buffer_index_ = -1;
474 } 478 }
475 479
476 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range, 480 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
477 bool transfer_current_position) { 481 bool transfer_current_position) {
478 DCHECK(CanAppendRangeToEnd(range)); 482 DCHECK(CanAppendRangeToEnd(range));
479 DCHECK(!buffers_.empty()); 483 CHECK(!buffers_.empty());
480 484
481 if (transfer_current_position && range.next_buffer_index_ >= 0) 485 if (transfer_current_position && range.next_buffer_index_ >= 0)
482 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); 486 next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
483 487
484 AppendBuffersToEnd(range.buffers_); 488 AppendBuffersToEnd(range.buffers_);
485 } 489 }
486 490
487 bool SourceBufferRange::CanAppendRangeToEnd( 491 bool SourceBufferRange::CanAppendRangeToEnd(
488 const SourceBufferRange& range) const { 492 const SourceBufferRange& range) const {
489 return CanAppendBuffersToEnd(range.buffers_); 493 return CanAppendBuffersToEnd(range.buffers_);
490 } 494 }
491 495
492 bool SourceBufferRange::CanAppendBuffersToEnd( 496 bool SourceBufferRange::CanAppendBuffersToEnd(
493 const BufferQueue& buffers) const { 497 const BufferQueue& buffers) const {
494 DCHECK(!buffers_.empty()); 498 CHECK(!buffers_.empty());
495 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(), 499 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(),
496 buffers.front()->is_key_frame()); 500 buffers.front()->is_key_frame());
497 } 501 }
498 502
499 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const { 503 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const {
500 DCHECK(!buffers_.empty()); 504 CHECK(!buffers_.empty());
501 505
502 return (IsNextInSequence(timestamp, false) || 506 return (IsNextInSequence(timestamp, false) ||
503 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 507 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
504 } 508 }
505 509
506 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const { 510 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const {
507 DecodeTimestamp start_timestamp = 511 DecodeTimestamp start_timestamp =
508 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom()); 512 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom());
509 return !keyframe_map_.empty() && start_timestamp <= timestamp && 513 return !keyframe_map_.empty() && start_timestamp <= timestamp &&
510 timestamp < GetBufferedEndTimestamp(); 514 timestamp < GetBufferedEndTimestamp();
511 } 515 }
512 516
513 bool SourceBufferRange::CompletelyOverlaps( 517 bool SourceBufferRange::CompletelyOverlaps(
514 const SourceBufferRange& range) const { 518 const SourceBufferRange& range) const {
515 return GetStartTimestamp() <= range.GetStartTimestamp() && 519 return GetStartTimestamp() <= range.GetStartTimestamp() &&
516 GetEndTimestamp() >= range.GetEndTimestamp(); 520 GetEndTimestamp() >= range.GetEndTimestamp();
517 } 521 }
518 522
519 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { 523 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
520 return range.GetStartTimestamp() <= GetEndTimestamp() && 524 return range.GetStartTimestamp() <= GetEndTimestamp() &&
521 GetEndTimestamp() < range.GetEndTimestamp(); 525 GetEndTimestamp() < range.GetEndTimestamp();
522 } 526 }
523 527
524 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const { 528 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const {
525 DCHECK(!buffers_.empty()); 529 CHECK(!buffers_.empty());
526 DecodeTimestamp start_timestamp = media_segment_start_time_; 530 DecodeTimestamp start_timestamp = media_segment_start_time_;
527 if (start_timestamp == kNoDecodeTimestamp()) 531 if (start_timestamp == kNoDecodeTimestamp())
528 start_timestamp = buffers_.front()->GetDecodeTimestamp(); 532 start_timestamp = buffers_.front()->GetDecodeTimestamp();
529 return start_timestamp; 533 return start_timestamp;
530 } 534 }
531 535
532 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const { 536 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const {
533 DCHECK(!buffers_.empty()); 537 CHECK(!buffers_.empty());
534 return buffers_.back()->GetDecodeTimestamp(); 538 return buffers_.back()->GetDecodeTimestamp();
535 } 539 }
536 540
537 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const { 541 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const {
538 DCHECK(!buffers_.empty()); 542 CHECK(!buffers_.empty());
539 base::TimeDelta duration = buffers_.back()->duration(); 543 base::TimeDelta duration = buffers_.back()->duration();
540 if (duration == kNoTimestamp() || duration == base::TimeDelta()) 544 if (duration == kNoTimestamp() || duration == base::TimeDelta())
541 duration = GetApproximateDuration(); 545 duration = GetApproximateDuration();
542 return GetEndTimestamp() + duration; 546 return GetEndTimestamp() + duration;
543 } 547 }
544 548
545 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp( 549 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp(
546 DecodeTimestamp timestamp) { 550 DecodeTimestamp timestamp) {
547 DCHECK(!keyframe_map_.empty()); 551 DCHECK(!keyframe_map_.empty());
548 552
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 } 630 }
627 631
628 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) 632 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime())
629 continue; 633 continue;
630 buffers->push_back(buffer); 634 buffers->push_back(buffer);
631 } 635 }
632 return previous_size < buffers->size(); 636 return previous_size < buffers->size();
633 } 637 }
634 638
635 } // namespace media 639 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/source_buffer_range.h ('k') | media/filters/source_buffer_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698