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

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

Issue 10952034: Remove lingering frames of old data when appending a new segment (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: response to CR Created 8 years, 3 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 | Annotate | Revision Log
« 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 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // |timestamp|. 56 // |timestamp|.
57 void SeekAheadTo(base::TimeDelta timestamp); 57 void SeekAheadTo(base::TimeDelta timestamp);
58 58
59 // Updates |next_buffer_index_| to point to next keyframe strictly after 59 // Updates |next_buffer_index_| to point to next keyframe strictly after
60 // |timestamp|. 60 // |timestamp|.
61 void SeekAheadPast(base::TimeDelta timestamp); 61 void SeekAheadPast(base::TimeDelta timestamp);
62 62
63 // Seeks to the beginning of the range. 63 // Seeks to the beginning of the range.
64 void SeekToStart(); 64 void SeekToStart();
65 65
66 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and 66 // Finds the next keyframe from |buffers_| after |timestamp| (or at
67 // returns a new SourceBufferRange with the buffers from that keyframe onward. 67 // |timestamp| if |is_exclusive| is false) and creates and returns a new
68 // SourceBufferRange with the buffers from that keyframe onward.
68 // The buffers in the new SourceBufferRange are moved out of this range. If 69 // The buffers in the new SourceBufferRange are moved out of this range. If
69 // there is no keyframe after |timestamp|, SplitRange() returns null and this 70 // there is no keyframe after |timestamp|, SplitRange() returns null and this
70 // range is unmodified. 71 // range is unmodified.
71 SourceBufferRange* SplitRange(base::TimeDelta timestamp); 72 SourceBufferRange* SplitRange(base::TimeDelta timestamp, bool is_exclusive);
72 73
73 // Deletes the buffers from this range whose timestamps are greater than or 74 // Deletes the buffers from this range starting at |timestamp|, exclusive if
74 // equal to |buffer|'s timestamp. 75 // |is_exclusive| is true, inclusive otherwise.
75 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was 76 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
76 // deleted, and deletes the |keyframe_map_| entries for the buffers that 77 // deleted, and deletes the |keyframe_map_| entries for the buffers that
77 // were removed. 78 // were removed.
78 // |deleted_buffers| contains the buffers that were deleted from this range, 79 // |deleted_buffers| contains the buffers that were deleted from this range,
79 // starting at the buffer that had been at |next_buffer_index_|. 80 // starting at the buffer that had been at |next_buffer_index_|.
80 // Returns true if the |next_buffer_index_| is reset. Note that this method 81 // Returns true if the |next_buffer_index_| is reset. Note that this method
81 // may return true even if it does not add any buffers to |deleted_buffers|. 82 // may return true even if it does not add any buffers to |deleted_buffers|.
82 // This indicates that the range had not buffered |next_buffer_index_|, but 83 // This indicates that the range had not buffered |next_buffer_index_|, but
83 // a buffer at that position would have been deleted. 84 // a buffer at that position would have been deleted.
84 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer, 85 bool TruncateAt(base::TimeDelta timestamp,
85 BufferQueue* deleted_buffers); 86 BufferQueue* deleted_buffers, bool is_exclusive);
86 bool TruncateAt(base::TimeDelta timestamp);
87 // Deletes all buffers in range. 87 // Deletes all buffers in range.
88 bool DeleteAll(BufferQueue* deleted_buffers); 88 bool DeleteAll(BufferQueue* deleted_buffers);
89 89
90 // Attempts to free |bytes| data from the range, preferring to delete at the 90 // Attempts to free |bytes| data from the range, preferring to delete at the
91 // beginning of the range. Deletes data in GOPS at a time so that the range 91 // beginning of the range. Deletes data in GOPS at a time so that the range
92 // always begins with a keyframe. Returns the number of bytes freed. 92 // always begins with a keyframe. Returns the number of bytes freed.
93 int FreeFromStart(int bytes); 93 int FreeFromStart(int bytes);
94 94
95 // Attempts to free |bytes| data from the range, preferring to delete at the 95 // Attempts to free |bytes| data from the range, preferring to delete at the
96 // end of the range. Returns the number of bytes freed. 96 // end of the range. Returns the number of bytes freed.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 int size_in_bytes() const { return size_in_bytes_; } 157 int size_in_bytes() const { return size_in_bytes_; }
158 158
159 private: 159 private:
160 typedef std::map<base::TimeDelta, size_t> KeyframeMap; 160 typedef std::map<base::TimeDelta, size_t> KeyframeMap;
161 161
162 // Seeks the range to the next keyframe after |timestamp|. If 162 // Seeks the range to the next keyframe after |timestamp|. If
163 // |skip_given_timestamp| is true, the seek will go to a keyframe with a 163 // |skip_given_timestamp| is true, the seek will go to a keyframe with a
164 // timestamp strictly greater than |timestamp|. 164 // timestamp strictly greater than |timestamp|.
165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); 165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp);
166 166
167 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|.
168 // If |skip_given_timestamp| is true, this returns the first buffer with
169 // timestamp greater than |timestamp|.
170 BufferQueue::iterator GetBufferItrAt(
171 base::TimeDelta timestamp, bool skip_given_timestamp);
172
167 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after 173 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
168 // |timestamp|. If |skip_given_timestamp| is true, this returns the first 174 // |timestamp|. If |skip_given_timestamp| is true, this returns the first
169 // keyframe with a timestamp strictly greater than |timestamp|. 175 // keyframe with a timestamp strictly greater than |timestamp|.
170 KeyframeMap::iterator GetFirstKeyframeAt( 176 KeyframeMap::iterator GetFirstKeyframeAt(
171 base::TimeDelta timestamp, bool skip_given_timestamp); 177 base::TimeDelta timestamp, bool skip_given_timestamp);
172 178
173 // Returns an iterator in |keyframe_map_| pointing to the first keyframe 179 // Returns an iterator in |keyframe_map_| pointing to the first keyframe
174 // before or at |timestamp|. 180 // before or at |timestamp|.
175 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); 181 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp);
176 182
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 return true; 250 return true;
245 } 251 }
246 252
247 // Comparison function for two Buffers based on timestamp. 253 // Comparison function for two Buffers based on timestamp.
248 static bool BufferComparator( 254 static bool BufferComparator(
249 const scoped_refptr<media::StreamParserBuffer>& first, 255 const scoped_refptr<media::StreamParserBuffer>& first,
250 const scoped_refptr<media::StreamParserBuffer>& second) { 256 const scoped_refptr<media::StreamParserBuffer>& second) {
251 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); 257 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp();
252 } 258 }
253 259
260 // Returns an estimate of how far from the beginning or end of a range a buffer
261 // can be to still be considered in the range, given the |approximate_duration|
262 // of a buffer in the stream.
263 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
264 // Because we do not know exactly when is the next timestamp, any buffer
265 // that starts within 2x the approximate duration of a buffer is considered
266 // within this range.
267 return 2 * approximate_duration;
268 }
269
254 // An arbitrarily-chosen number to estimate the duration of a buffer if none 270 // An arbitrarily-chosen number to estimate the duration of a buffer if none
255 // is set and there's not enough information to get a better estimate. 271 // is set and there's not enough information to get a better estimate.
256 static int kDefaultBufferDurationInMs = 125; 272 static int kDefaultBufferDurationInMs = 125;
257 273
258 // The amount of time the beginning of the buffered data can differ from the 274 // The amount of time the beginning of the buffered data can differ from the
259 // start time in order to still be considered the start of stream. 275 // start time in order to still be considered the start of stream.
260 static base::TimeDelta kSeekToStartFudgeRoom() { 276 static base::TimeDelta kSeekToStartFudgeRoom() {
261 return base::TimeDelta::FromMilliseconds(1000); 277 return base::TimeDelta::FromMilliseconds(1000);
262 } 278 }
263 // The maximum amount of data in bytes the stream will keep in memory. 279 // The maximum amount of data in bytes the stream will keep in memory.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 ranges_.pop_front(); 326 ranges_.pop_front();
311 } 327 }
312 328
313 STLDeleteElements(&audio_configs_); 329 STLDeleteElements(&audio_configs_);
314 STLDeleteElements(&video_configs_); 330 STLDeleteElements(&video_configs_);
315 } 331 }
316 332
317 void SourceBufferStream::OnNewMediaSegment( 333 void SourceBufferStream::OnNewMediaSegment(
318 base::TimeDelta media_segment_start_time) { 334 base::TimeDelta media_segment_start_time) {
319 media_segment_start_time_ = media_segment_start_time; 335 media_segment_start_time_ = media_segment_start_time;
336 new_media_segment_ = true;
320 337
321 // Find the range that will house the buffers appended through the next 338 RangeList::iterator last_range = range_for_next_append_;
322 // Append() call.
323 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); 339 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
324 new_media_segment_ = true; 340
325 last_buffer_timestamp_ = kNoTimestamp(); 341 // Only reset |last_buffer_timestamp_| if this new media segment is not
342 // adjacent to the previous media segment appended to the stream.
343 if (range_for_next_append_ == ranges_.end() ||
344 !AreAdjacentInSequence(
345 last_buffer_timestamp_, media_segment_start_time)) {
346 last_buffer_timestamp_ = kNoTimestamp();
347 } else {
348 DCHECK(last_range == range_for_next_append_);
349 }
326 } 350 }
327 351
328 bool SourceBufferStream::Append( 352 bool SourceBufferStream::Append(
329 const SourceBufferStream::BufferQueue& buffers) { 353 const SourceBufferStream::BufferQueue& buffers) {
330 DCHECK(!buffers.empty()); 354 DCHECK(!buffers.empty());
331 DCHECK(media_segment_start_time_ != kNoTimestamp()); 355 DCHECK(media_segment_start_time_ != kNoTimestamp());
332 356
333 // New media segments must begin with a keyframe. 357 // New media segments must begin with a keyframe.
334 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { 358 if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
335 DVLOG(1) << "Media segment did not begin with keyframe."; 359 DVLOG(1) << "Media segment did not begin with keyframe.";
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 556
533 void SourceBufferStream::InsertIntoExistingRange( 557 void SourceBufferStream::InsertIntoExistingRange(
534 const RangeList::iterator& range_for_new_buffers_itr, 558 const RangeList::iterator& range_for_new_buffers_itr,
535 const BufferQueue& new_buffers, 559 const BufferQueue& new_buffers,
536 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { 560 bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
537 DCHECK(deleted_next_buffer); 561 DCHECK(deleted_next_buffer);
538 DCHECK(deleted_buffers); 562 DCHECK(deleted_buffers);
539 563
540 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; 564 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr;
541 565
542 // If this is a simple case where we can just append to the end of the range, 566 if (last_buffer_timestamp_ != kNoTimestamp()) {
543 // do so and return. 567 // Clean up the old buffers between the last appended buffer and the
544 if (range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { 568 // beginning of |new_buffers|.
545 range_for_new_buffers->AppendBuffersToEnd(new_buffers); 569 *deleted_next_buffer =
546 return; 570 DeleteBetween(
571 range_for_new_buffers, last_buffer_timestamp_,
572 new_buffers.front()->GetDecodeTimestamp(), true,
573 deleted_buffers);
547 } 574 }
548 575
549 // Otherwise, this is either a start overlap or an middle overlap. 576 // If we cannot append the |new_buffers| to the end of the existing range,
577 // this is either a start overlap or an middle overlap. Delete the buffers
578 // that |new_buffers| overlaps.
579 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) {
580 *deleted_next_buffer |=
581 DeleteBetween(
582 range_for_new_buffers, new_buffers.front()->GetDecodeTimestamp(),
583 new_buffers.back()->GetDecodeTimestamp(), false,
584 deleted_buffers);
585 }
550 586
551 // In case this is a middle overlap, save the buffers that come after the end 587 range_for_new_buffers->AppendBuffersToEnd(new_buffers);
552 // of |new_buffers|, and add them into a new range. 588 }
589
590 bool SourceBufferStream::DeleteBetween(
591 SourceBufferRange* range, base::TimeDelta start_timestamp,
592 base::TimeDelta end_timestamp, bool is_range_exclusive,
593 BufferQueue* deleted_buffers) {
553 SourceBufferRange* new_next_range = 594 SourceBufferRange* new_next_range =
554 range_for_new_buffers->SplitRange( 595 range->SplitRange(end_timestamp, is_range_exclusive);
555 new_buffers.back()->GetDecodeTimestamp());
556 596
557 if (new_next_range) 597 if (new_next_range)
558 AddToRanges(new_next_range); 598 AddToRanges(new_next_range);
559 599
560 // Delete the buffers that are overlapped by |new_buffers|, then append
561 // |new_buffers| to the end of the range.
562 BufferQueue saved_buffers; 600 BufferQueue saved_buffers;
563 bool deleted_next_buffer_from_range = 601 bool deleted_next_buffer =
564 range_for_new_buffers->TruncateAt(new_buffers.front(), &saved_buffers); 602 range->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive);
565 range_for_new_buffers->AppendBuffersToEnd(new_buffers);
566 603
567 if (selected_range_ != range_for_new_buffers) 604 if (selected_range_ != range)
568 return; 605 return deleted_next_buffer;
569 606
570 DCHECK(!*deleted_next_buffer); 607 DCHECK(deleted_buffers->empty());
571 *deleted_buffers = saved_buffers; 608 *deleted_buffers = saved_buffers;
572 *deleted_next_buffer = deleted_next_buffer_from_range;
573 609
574 // If this was a middle overlap resulting in a new range, and the next buffer 610 // If the next buffer position has transferred to the split range, set the
575 // position has been transferred to the newly created range, update the 611 // selected range accordingly.
576 // |selected_range_| accordingly.
577 if (new_next_range && new_next_range->HasNextBufferPosition()) { 612 if (new_next_range && new_next_range->HasNextBufferPosition()) {
578 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); 613 DCHECK(!range->HasNextBufferPosition());
579 DCHECK(!*deleted_next_buffer); 614 DCHECK(!deleted_next_buffer);
580 SetSelectedRange(new_next_range); 615 SetSelectedRange(new_next_range);
581 } 616 }
617 return deleted_next_buffer;
618 }
619
620 bool SourceBufferStream::AreAdjacentInSequence(
621 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const {
622 return first_timestamp < second_timestamp &&
623 second_timestamp <=
624 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
582 } 625 }
583 626
584 void SourceBufferStream::ResolveCompleteOverlaps( 627 void SourceBufferStream::ResolveCompleteOverlaps(
585 const RangeList::iterator& range_with_new_buffers_itr, 628 const RangeList::iterator& range_with_new_buffers_itr,
586 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { 629 bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
587 DCHECK(deleted_next_buffer); 630 DCHECK(deleted_next_buffer);
588 DCHECK(deleted_buffers); 631 DCHECK(deleted_buffers);
589 632
590 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 633 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
591 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 634 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
(...skipping 28 matching lines...) Expand all
620 } 663 }
621 664
622 // Split the overlapped range after |range_with_new_buffers|'s last buffer 665 // Split the overlapped range after |range_with_new_buffers|'s last buffer
623 // overlaps. Now |overlapped_range| contains only the buffers that do not 666 // overlaps. Now |overlapped_range| contains only the buffers that do not
624 // belong in |ranges_| anymore, and |new_next_range| contains buffers that 667 // belong in |ranges_| anymore, and |new_next_range| contains buffers that
625 // go after |range_with_new_buffers| (without overlap). 668 // go after |range_with_new_buffers| (without overlap).
626 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); 669 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr);
627 next_range_itr = ranges_.erase(next_range_itr); 670 next_range_itr = ranges_.erase(next_range_itr);
628 671
629 SourceBufferRange* new_next_range = 672 SourceBufferRange* new_next_range =
630 overlapped_range->SplitRange(range_with_new_buffers->GetEndTimestamp()); 673 overlapped_range->SplitRange(
674 range_with_new_buffers->GetEndTimestamp(), true);
631 675
632 // If there were non-overlapped buffers, add the new range to |ranges_|. 676 // If there were non-overlapped buffers, add the new range to |ranges_|.
633 if (new_next_range) 677 if (new_next_range)
634 AddToRanges(new_next_range); 678 AddToRanges(new_next_range);
635 679
636 // If we didn't overlap a selected range, return. 680 // If we didn't overlap a selected range, return.
637 if (selected_range_ != overlapped_range.get()) 681 if (selected_range_ != overlapped_range.get())
638 return; 682 return;
639 683
640 // If the |overlapped_range| transfers its next buffer position to 684 // If the |overlapped_range| transfers its next buffer position to
641 // |new_next_range|, make |new_next_range| the |selected_range_|. 685 // |new_next_range|, make |new_next_range| the |selected_range_|.
642 if (new_next_range && new_next_range->HasNextBufferPosition()) { 686 if (new_next_range && new_next_range->HasNextBufferPosition()) {
643 DCHECK(!overlapped_range->HasNextBufferPosition()); 687 DCHECK(!overlapped_range->HasNextBufferPosition());
644 SetSelectedRange(new_next_range); 688 SetSelectedRange(new_next_range);
645 return; 689 return;
646 } 690 }
647 691
648 // Save the buffers in |overlapped_range|. 692 // Save the buffers in |overlapped_range|.
649 DCHECK(!*deleted_next_buffer); 693 DCHECK(!*deleted_next_buffer);
650 DCHECK_EQ(overlapped_range.get(), selected_range_); 694 DCHECK_EQ(overlapped_range.get(), selected_range_);
651 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); 695 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers);
652 DCHECK(*deleted_next_buffer); 696 DCHECK(*deleted_next_buffer);
653 697
654 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. 698 // |overlapped_range| will be deleted, so set |selected_range_| to NULL.
655 SetSelectedRange(NULL); 699 SetSelectedRange(NULL);
656 } 700 }
657 701
658 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { 702 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) {
659 DCHECK(!deleted_buffers.empty()); 703 DCHECK(!deleted_buffers.empty());
660 if (!track_buffer_.empty())
661 return;
662
663 DCHECK(selected_range_); 704 DCHECK(selected_range_);
664 DCHECK(selected_range_->HasNextBufferPosition()); 705 DCHECK(selected_range_->HasNextBufferPosition());
665 706
666 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); 707 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp();
667 708
668 // If there is no gap between what was deleted and what was added, nothing 709 // If there is no gap between what was deleted and what was added, nothing
669 // should be added to the track buffer. 710 // should be added to the track buffer.
670 if (selected_range_->HasNextBuffer() && 711 if (selected_range_->HasNextBuffer() &&
671 (next_keyframe_timestamp == 712 (next_keyframe_timestamp ==
672 deleted_buffers.front()->GetDecodeTimestamp())) { 713 deleted_buffers.front()->GetDecodeTimestamp())) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 RangeList::iterator itr = ranges_.end(); 803 RangeList::iterator itr = ranges_.end();
763 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 804 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
764 if ((*itr)->GetEndTimestamp() > duration) 805 if ((*itr)->GetEndTimestamp() > duration)
765 break; 806 break;
766 } 807 }
767 if (itr == ranges_.end()) 808 if (itr == ranges_.end())
768 return; 809 return;
769 810
770 // Need to partially truncate this range. 811 // Need to partially truncate this range.
771 if ((*itr)->GetStartTimestamp() < duration) { 812 if ((*itr)->GetStartTimestamp() < duration) {
772 bool deleted_seek_point = (*itr)->TruncateAt(duration); 813 bool deleted_seek_point = (*itr)->TruncateAt(duration, NULL, false);
773 if (deleted_seek_point) 814 if (deleted_seek_point)
774 ResetSeekState(); 815 ResetSeekState();
775 ++itr; 816 ++itr;
776 } 817 }
777 818
778 // Delete all ranges that begin after |duration|. 819 // Delete all ranges that begin after |duration|.
779 while (itr != ranges_.end()) { 820 while (itr != ranges_.end()) {
780 // If we're about to delete the selected range, also reset the seek state. 821 // If we're about to delete the selected range, also reset the seek state.
781 DCHECK((*itr)->GetStartTimestamp() >= duration); 822 DCHECK((*itr)->GetStartTimestamp() >= duration);
782 if (*itr== selected_range_) 823 if (*itr== selected_range_)
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 } 1092 }
1052 next_buffer_index_ = result->second; 1093 next_buffer_index_ = result->second;
1053 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 1094 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1054 } 1095 }
1055 1096
1056 void SourceBufferRange::SeekToStart() { 1097 void SourceBufferRange::SeekToStart() {
1057 DCHECK(!buffers_.empty()); 1098 DCHECK(!buffers_.empty());
1058 next_buffer_index_ = 0; 1099 next_buffer_index_ = 0;
1059 } 1100 }
1060 1101
1061 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { 1102 SourceBufferRange* SourceBufferRange::SplitRange(
1062 // Find the first keyframe after |timestamp|, not including |timestamp|. 1103 base::TimeDelta timestamp, bool is_exclusive) {
1104 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not
1105 // include keyframes at |timestamp|.
1063 KeyframeMap::iterator new_beginning_keyframe = 1106 KeyframeMap::iterator new_beginning_keyframe =
1064 GetFirstKeyframeAt(timestamp, true); 1107 GetFirstKeyframeAt(timestamp, is_exclusive);
1065 1108
1066 // If there is no keyframe after |timestamp|, we can't split the range. 1109 // If there is no keyframe after |timestamp|, we can't split the range.
1067 if (new_beginning_keyframe == keyframe_map_.end()) 1110 if (new_beginning_keyframe == keyframe_map_.end())
1068 return NULL; 1111 return NULL;
1069 1112
1070 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 1113 // Remove the data beginning at |keyframe_index| from |buffers_| and save it
1071 // into |removed_buffers|. 1114 // into |removed_buffers|.
1072 int keyframe_index = new_beginning_keyframe->second; 1115 int keyframe_index = new_beginning_keyframe->second;
1073 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 1116 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
1074 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 1117 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
(...skipping 14 matching lines...) Expand all
1089 ResetNextBufferPosition(); 1132 ResetNextBufferPosition();
1090 } else if (waiting_for_keyframe_) { 1133 } else if (waiting_for_keyframe_) {
1091 split_range->waiting_for_keyframe_ = true; 1134 split_range->waiting_for_keyframe_ = true;
1092 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; 1135 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_;
1093 ResetNextBufferPosition(); 1136 ResetNextBufferPosition();
1094 } 1137 }
1095 1138
1096 return split_range; 1139 return split_range;
1097 } 1140 }
1098 1141
1142 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
1143 base::TimeDelta timestamp, bool skip_given_timestamp) {
1144 // Need to make a dummy buffer with timestamp |timestamp| in order to search
1145 // the |buffers_| container.
1146 scoped_refptr<StreamParserBuffer> dummy_buffer =
1147 StreamParserBuffer::CopyFrom(NULL, 0, false);
1148 dummy_buffer->SetDecodeTimestamp(timestamp);
1149
1150 if (skip_given_timestamp) {
1151 return std::upper_bound(
1152 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1153 }
1154 return std::lower_bound(
1155 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1156 }
1157
1099 SourceBufferRange::KeyframeMap::iterator 1158 SourceBufferRange::KeyframeMap::iterator
1100 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, 1159 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp,
1101 bool skip_given_timestamp) { 1160 bool skip_given_timestamp) {
1102 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 1161 return skip_given_timestamp ?
1103 // lower_bound() returns the first element >= |timestamp|, so if we don't want 1162 keyframe_map_.upper_bound(timestamp) :
1104 // to include keyframes == |timestamp|, we have to increment the iterator 1163 keyframe_map_.lower_bound(timestamp);
1105 // accordingly.
1106 if (skip_given_timestamp &&
1107 result != keyframe_map_.end() && result->first == timestamp) {
1108 ++result;
1109 }
1110 return result;
1111 } 1164 }
1112 1165
1113 SourceBufferRange::KeyframeMap::iterator 1166 SourceBufferRange::KeyframeMap::iterator
1114 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { 1167 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) {
1115 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 1168 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
1116 // lower_bound() returns the first element >= |timestamp|, so we want the 1169 // lower_bound() returns the first element >= |timestamp|, so we want the
1117 // previous element if it did not return the element exactly equal to 1170 // previous element if it did not return the element exactly equal to
1118 // |timestamp|. 1171 // |timestamp|.
1119 if (result != keyframe_map_.begin() && 1172 if (result != keyframe_map_.begin() &&
1120 (result == keyframe_map_.end() || result->first != timestamp)) { 1173 (result == keyframe_map_.end() || result->first != timestamp)) {
1121 --result; 1174 --result;
1122 } 1175 }
1123 return result; 1176 return result;
1124 } 1177 }
1125 1178
1126 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 1179 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
1127 return TruncateAt(buffers_.begin(), removed_buffers); 1180 return TruncateAt(buffers_.begin(), removed_buffers);
1128 } 1181 }
1129 1182
1130 bool SourceBufferRange::TruncateAt(base::TimeDelta timestamp) {
1131 // Need to make a dummy buffer with timestamp |timestamp| in order to search
1132 // the |buffers_| container.
1133 scoped_refptr<StreamParserBuffer> dummy_buffer =
1134 StreamParserBuffer::CopyFrom(NULL, 0, false);
1135 dummy_buffer->SetDecodeTimestamp(timestamp);
1136 return TruncateAt(dummy_buffer, NULL);
1137 }
1138
1139 bool SourceBufferRange::TruncateAt( 1183 bool SourceBufferRange::TruncateAt(
1140 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { 1184 base::TimeDelta timestamp, BufferQueue* removed_buffers,
1185 bool is_exclusive) {
1141 // Find the place in |buffers_| where we will begin deleting data. 1186 // Find the place in |buffers_| where we will begin deleting data.
1142 BufferQueue::iterator starting_point = 1187 BufferQueue::iterator starting_point =
1143 std::lower_bound(buffers_.begin(), buffers_.end(), 1188 GetBufferItrAt(timestamp, is_exclusive);
1144 buffer,
1145 BufferComparator);
1146 return TruncateAt(starting_point, removed_buffers); 1189 return TruncateAt(starting_point, removed_buffers);
1147 } 1190 }
1148 1191
1149 int SourceBufferRange::FreeFromStart(int bytes) { 1192 int SourceBufferRange::FreeFromStart(int bytes) {
1150 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); 1193 KeyframeMap::iterator deletion_limit = keyframe_map_.end();
1151 if (HasNextBufferPosition()) { 1194 if (HasNextBufferPosition()) {
1152 base::TimeDelta next_timestamp = GetNextTimestamp(); 1195 base::TimeDelta next_timestamp = GetNextTimestamp();
1153 if (next_timestamp != kNoTimestamp()) { 1196 if (next_timestamp != kNoTimestamp()) {
1154 deletion_limit = GetFirstKeyframeBefore(next_timestamp); 1197 deletion_limit = GetFirstKeyframeBefore(next_timestamp);
1155 } else { 1198 } else {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 } 1450 }
1408 1451
1409 bool SourceBufferRange::IsNextInSequence( 1452 bool SourceBufferRange::IsNextInSequence(
1410 const scoped_refptr<media::StreamParserBuffer>& buffer, 1453 const scoped_refptr<media::StreamParserBuffer>& buffer,
1411 base::TimeDelta timestamp) const { 1454 base::TimeDelta timestamp) const {
1412 return buffer->GetDecodeTimestamp() < timestamp && 1455 return buffer->GetDecodeTimestamp() < timestamp &&
1413 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); 1456 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom();
1414 } 1457 }
1415 1458
1416 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 1459 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
1417 // Because we do not know exactly when is the next timestamp, any buffer 1460 return ComputeFudgeRoom(GetApproximateDuration());
1418 // that starts within 2x the approximate duration of a buffer is considered
1419 // within this range.
1420 return 2 * GetApproximateDuration();
1421 } 1461 }
1422 1462
1423 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 1463 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
1424 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 1464 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
1425 DCHECK(max_interbuffer_distance != kNoTimestamp()); 1465 DCHECK(max_interbuffer_distance != kNoTimestamp());
1426 return max_interbuffer_distance; 1466 return max_interbuffer_distance;
1427 } 1467 }
1428 1468
1429 } // namespace media 1469 } // 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