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

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: fix lingering frames bug 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
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // Returns true if the end of this range contains buffers that overlaps with 147 // Returns true if the end of this range contains buffers that overlaps with
148 // the beginning of |range|. 148 // the beginning of |range|.
149 bool EndOverlaps(const SourceBufferRange& range) const; 149 bool EndOverlaps(const SourceBufferRange& range) const;
150 150
151 // Returns true if |timestamp| is the timestamp of the next buffer in 151 // Returns true if |timestamp| is the timestamp of the next buffer in
152 // sequence after |buffer|, false otherwise. 152 // sequence after |buffer|, false otherwise.
153 bool IsNextInSequence( 153 bool IsNextInSequence(
154 const scoped_refptr<media::StreamParserBuffer>& buffer, 154 const scoped_refptr<media::StreamParserBuffer>& buffer,
155 base::TimeDelta timestamp) const; 155 base::TimeDelta timestamp) const;
156 156
157 // Returns true if |second_timestamp| is the timestamp of the next buffer in
158 // sequence after |first_timestamp|, false otherwise.
159 bool AreAdjacentInSequence(
160 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const;
161
157 int size_in_bytes() const { return size_in_bytes_; } 162 int size_in_bytes() const { return size_in_bytes_; }
158 163
159 private: 164 private:
160 typedef std::map<base::TimeDelta, size_t> KeyframeMap; 165 typedef std::map<base::TimeDelta, size_t> KeyframeMap;
161 166
162 // Seeks the range to the next keyframe after |timestamp|. If 167 // 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 168 // |skip_given_timestamp| is true, the seek will go to a keyframe with a
164 // timestamp strictly greater than |timestamp|. 169 // timestamp strictly greater than |timestamp|.
165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); 170 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp);
166 171
172 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|.
173 // If |skip_given_timestamp| is true, this returns the first buffer with
174 // timestamp greater than |timestamp|.
175 BufferQueue::iterator GetBufferItrAt(
176 base::TimeDelta timestamp, bool skip_given_timestamp);
177
167 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after 178 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
168 // |timestamp|. If |skip_given_timestamp| is true, this returns the first 179 // |timestamp|. If |skip_given_timestamp| is true, this returns the first
169 // keyframe with a timestamp strictly greater than |timestamp|. 180 // keyframe with a timestamp strictly greater than |timestamp|.
170 KeyframeMap::iterator GetFirstKeyframeAt( 181 KeyframeMap::iterator GetFirstKeyframeAt(
171 base::TimeDelta timestamp, bool skip_given_timestamp); 182 base::TimeDelta timestamp, bool skip_given_timestamp);
172 183
173 // Returns an iterator in |keyframe_map_| pointing to the first keyframe 184 // Returns an iterator in |keyframe_map_| pointing to the first keyframe
174 // before or at |timestamp|. 185 // before or at |timestamp|.
175 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); 186 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp);
176 187
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 ranges_.pop_front(); 321 ranges_.pop_front();
311 } 322 }
312 323
313 STLDeleteElements(&audio_configs_); 324 STLDeleteElements(&audio_configs_);
314 STLDeleteElements(&video_configs_); 325 STLDeleteElements(&video_configs_);
315 } 326 }
316 327
317 void SourceBufferStream::OnNewMediaSegment( 328 void SourceBufferStream::OnNewMediaSegment(
318 base::TimeDelta media_segment_start_time) { 329 base::TimeDelta media_segment_start_time) {
319 media_segment_start_time_ = media_segment_start_time; 330 media_segment_start_time_ = media_segment_start_time;
331 new_media_segment_ = true;
320 332
321 // Find the range that will house the buffers appended through the next 333 RangeList::iterator last_range = range_for_next_append_;
322 // Append() call.
323 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); 334 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
324 new_media_segment_ = true; 335
325 last_buffer_timestamp_ = kNoTimestamp(); 336 // Only reset |last_buffer_timestamp_| if this new media segment is not
337 // adjacent to the previous media segment appended to the stream.
338 if (range_for_next_append_ == ranges_.end() ||
339 !(*range_for_next_append_)->AreAdjacentInSequence(
340 last_buffer_timestamp_, media_segment_start_time)) {
341 last_buffer_timestamp_ = kNoTimestamp();
342 } else {
343 DCHECK(last_range == range_for_next_append_);
344 }
326 } 345 }
327 346
328 bool SourceBufferStream::Append( 347 bool SourceBufferStream::Append(
329 const SourceBufferStream::BufferQueue& buffers) { 348 const SourceBufferStream::BufferQueue& buffers) {
330 DCHECK(!buffers.empty()); 349 DCHECK(!buffers.empty());
331 DCHECK(media_segment_start_time_ != kNoTimestamp()); 350 DCHECK(media_segment_start_time_ != kNoTimestamp());
332 351
333 // New media segments must begin with a keyframe. 352 // New media segments must begin with a keyframe.
334 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { 353 if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
335 DVLOG(1) << "Media segment did not begin with keyframe."; 354 DVLOG(1) << "Media segment did not begin with keyframe.";
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 551
533 void SourceBufferStream::InsertIntoExistingRange( 552 void SourceBufferStream::InsertIntoExistingRange(
534 const RangeList::iterator& range_for_new_buffers_itr, 553 const RangeList::iterator& range_for_new_buffers_itr,
535 const BufferQueue& new_buffers, 554 const BufferQueue& new_buffers,
536 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { 555 bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
537 DCHECK(deleted_next_buffer); 556 DCHECK(deleted_next_buffer);
538 DCHECK(deleted_buffers); 557 DCHECK(deleted_buffers);
539 558
540 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; 559 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr;
541 560
542 // If this is a simple case where we can just append to the end of the range, 561 if (last_buffer_timestamp_ != kNoTimestamp()) {
543 // do so and return. 562 // Clean up the old buffers between the last appended buffer and the
544 if (range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { 563 // beginning of |new_buffers|.
545 range_for_new_buffers->AppendBuffersToEnd(new_buffers); 564 *deleted_next_buffer =
546 return; 565 DeleteBetween(
566 range_for_new_buffers, last_buffer_timestamp_,
567 new_buffers.front()->GetDecodeTimestamp(), true,
568 deleted_buffers);
547 } 569 }
548 570
549 // Otherwise, this is either a start overlap or an middle overlap. 571 // If we cannot append the |new_buffers| to the end of the existing range,
572 // this is either a start overlap or an middle overlap. Delete the buffers
573 // that |new_buffers| overlaps.
574 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) {
575 *deleted_next_buffer |=
576 DeleteBetween(
577 range_for_new_buffers, new_buffers.front()->GetDecodeTimestamp(),
578 new_buffers.back()->GetDecodeTimestamp(), false,
579 deleted_buffers);
580 }
550 581
551 // In case this is a middle overlap, save the buffers that come after the end 582 range_for_new_buffers->AppendBuffersToEnd(new_buffers);
552 // of |new_buffers|, and add them into a new range. 583 }
584
585 bool SourceBufferStream::DeleteBetween(
586 SourceBufferRange* range, base::TimeDelta start_timestamp,
587 base::TimeDelta end_timestamp, bool is_range_exclusive,
588 BufferQueue* deleted_buffers) {
553 SourceBufferRange* new_next_range = 589 SourceBufferRange* new_next_range =
554 range_for_new_buffers->SplitRange( 590 range->SplitRange(end_timestamp, is_range_exclusive);
555 new_buffers.back()->GetDecodeTimestamp());
556 591
557 if (new_next_range) 592 if (new_next_range)
558 AddToRanges(new_next_range); 593 AddToRanges(new_next_range);
559 594
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; 595 BufferQueue saved_buffers;
563 bool deleted_next_buffer_from_range = 596 bool deleted_next_buffer =
564 range_for_new_buffers->TruncateAt(new_buffers.front(), &saved_buffers); 597 range->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive);
565 range_for_new_buffers->AppendBuffersToEnd(new_buffers);
566 598
567 if (selected_range_ != range_for_new_buffers) 599 if (selected_range_ != range)
568 return; 600 return deleted_next_buffer;
569 601
570 DCHECK(!*deleted_next_buffer);
571 *deleted_buffers = saved_buffers; 602 *deleted_buffers = saved_buffers;
acolwell GONE FROM CHROMIUM 2012/09/19 23:15:51 DCHECK(deleted_buffers->empty()) right before this
vrk (LEFT CHROMIUM) 2012/09/20 00:00:59 Good idea, done.
572 *deleted_next_buffer = deleted_next_buffer_from_range;
573 603
574 // If this was a middle overlap resulting in a new range, and the next buffer 604 // 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 605 // selected range accordingly.
576 // |selected_range_| accordingly.
577 if (new_next_range && new_next_range->HasNextBufferPosition()) { 606 if (new_next_range && new_next_range->HasNextBufferPosition()) {
578 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); 607 DCHECK(!range->HasNextBufferPosition());
579 DCHECK(!*deleted_next_buffer); 608 DCHECK(!deleted_next_buffer);
580 SetSelectedRange(new_next_range); 609 SetSelectedRange(new_next_range);
581 } 610 }
611 return deleted_next_buffer;
582 } 612 }
583 613
584 void SourceBufferStream::ResolveCompleteOverlaps( 614 void SourceBufferStream::ResolveCompleteOverlaps(
585 const RangeList::iterator& range_with_new_buffers_itr, 615 const RangeList::iterator& range_with_new_buffers_itr,
586 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { 616 bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
587 DCHECK(deleted_next_buffer); 617 DCHECK(deleted_next_buffer);
588 DCHECK(deleted_buffers); 618 DCHECK(deleted_buffers);
589 619
590 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 620 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
591 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 621 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
(...skipping 28 matching lines...) Expand all
620 } 650 }
621 651
622 // Split the overlapped range after |range_with_new_buffers|'s last buffer 652 // Split the overlapped range after |range_with_new_buffers|'s last buffer
623 // overlaps. Now |overlapped_range| contains only the buffers that do not 653 // overlaps. Now |overlapped_range| contains only the buffers that do not
624 // belong in |ranges_| anymore, and |new_next_range| contains buffers that 654 // belong in |ranges_| anymore, and |new_next_range| contains buffers that
625 // go after |range_with_new_buffers| (without overlap). 655 // go after |range_with_new_buffers| (without overlap).
626 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); 656 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr);
627 next_range_itr = ranges_.erase(next_range_itr); 657 next_range_itr = ranges_.erase(next_range_itr);
628 658
629 SourceBufferRange* new_next_range = 659 SourceBufferRange* new_next_range =
630 overlapped_range->SplitRange(range_with_new_buffers->GetEndTimestamp()); 660 overlapped_range->SplitRange(
661 range_with_new_buffers->GetEndTimestamp(), true);
631 662
632 // If there were non-overlapped buffers, add the new range to |ranges_|. 663 // If there were non-overlapped buffers, add the new range to |ranges_|.
633 if (new_next_range) 664 if (new_next_range)
634 AddToRanges(new_next_range); 665 AddToRanges(new_next_range);
635 666
636 // If we didn't overlap a selected range, return. 667 // If we didn't overlap a selected range, return.
637 if (selected_range_ != overlapped_range.get()) 668 if (selected_range_ != overlapped_range.get())
638 return; 669 return;
639 670
640 // If the |overlapped_range| transfers its next buffer position to 671 // If the |overlapped_range| transfers its next buffer position to
641 // |new_next_range|, make |new_next_range| the |selected_range_|. 672 // |new_next_range|, make |new_next_range| the |selected_range_|.
642 if (new_next_range && new_next_range->HasNextBufferPosition()) { 673 if (new_next_range && new_next_range->HasNextBufferPosition()) {
643 DCHECK(!overlapped_range->HasNextBufferPosition()); 674 DCHECK(!overlapped_range->HasNextBufferPosition());
644 SetSelectedRange(new_next_range); 675 SetSelectedRange(new_next_range);
645 return; 676 return;
646 } 677 }
647 678
648 // Save the buffers in |overlapped_range|. 679 // Save the buffers in |overlapped_range|.
649 DCHECK(!*deleted_next_buffer); 680 DCHECK(!*deleted_next_buffer);
650 DCHECK_EQ(overlapped_range.get(), selected_range_); 681 DCHECK_EQ(overlapped_range.get(), selected_range_);
651 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); 682 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers);
652 DCHECK(*deleted_next_buffer); 683 DCHECK(*deleted_next_buffer);
653 684
654 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. 685 // |overlapped_range| will be deleted, so set |selected_range_| to NULL.
655 SetSelectedRange(NULL); 686 SetSelectedRange(NULL);
656 } 687 }
657 688
658 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { 689 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) {
659 DCHECK(!deleted_buffers.empty()); 690 DCHECK(!deleted_buffers.empty());
660 if (!track_buffer_.empty())
661 return;
662
663 DCHECK(selected_range_); 691 DCHECK(selected_range_);
664 DCHECK(selected_range_->HasNextBufferPosition()); 692 DCHECK(selected_range_->HasNextBufferPosition());
665 693
666 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); 694 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp();
667 695
668 // If there is no gap between what was deleted and what was added, nothing 696 // If there is no gap between what was deleted and what was added, nothing
669 // should be added to the track buffer. 697 // should be added to the track buffer.
670 if (selected_range_->HasNextBuffer() && 698 if (selected_range_->HasNextBuffer() &&
671 (next_keyframe_timestamp == 699 (next_keyframe_timestamp ==
672 deleted_buffers.front()->GetDecodeTimestamp())) { 700 deleted_buffers.front()->GetDecodeTimestamp())) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 RangeList::iterator itr = ranges_.end(); 790 RangeList::iterator itr = ranges_.end();
763 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 791 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
764 if ((*itr)->GetEndTimestamp() > duration) 792 if ((*itr)->GetEndTimestamp() > duration)
765 break; 793 break;
766 } 794 }
767 if (itr == ranges_.end()) 795 if (itr == ranges_.end())
768 return; 796 return;
769 797
770 // Need to partially truncate this range. 798 // Need to partially truncate this range.
771 if ((*itr)->GetStartTimestamp() < duration) { 799 if ((*itr)->GetStartTimestamp() < duration) {
772 bool deleted_seek_point = (*itr)->TruncateAt(duration); 800 bool deleted_seek_point = (*itr)->TruncateAt(duration, NULL, false);
773 if (deleted_seek_point) 801 if (deleted_seek_point)
774 ResetSeekState(); 802 ResetSeekState();
775 ++itr; 803 ++itr;
776 } 804 }
777 805
778 // Delete all ranges that begin after |duration|. 806 // Delete all ranges that begin after |duration|.
779 while (itr != ranges_.end()) { 807 while (itr != ranges_.end()) {
780 // If we're about to delete the selected range, also reset the seek state. 808 // If we're about to delete the selected range, also reset the seek state.
781 DCHECK((*itr)->GetStartTimestamp() >= duration); 809 DCHECK((*itr)->GetStartTimestamp() >= duration);
782 if (*itr== selected_range_) 810 if (*itr== selected_range_)
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 } 1079 }
1052 next_buffer_index_ = result->second; 1080 next_buffer_index_ = result->second;
1053 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 1081 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1054 } 1082 }
1055 1083
1056 void SourceBufferRange::SeekToStart() { 1084 void SourceBufferRange::SeekToStart() {
1057 DCHECK(!buffers_.empty()); 1085 DCHECK(!buffers_.empty());
1058 next_buffer_index_ = 0; 1086 next_buffer_index_ = 0;
1059 } 1087 }
1060 1088
1061 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { 1089 SourceBufferRange* SourceBufferRange::SplitRange(
1062 // Find the first keyframe after |timestamp|, not including |timestamp|. 1090 base::TimeDelta timestamp, bool is_exclusive) {
1091 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not
1092 // include keyframes at |timestamp|.
1063 KeyframeMap::iterator new_beginning_keyframe = 1093 KeyframeMap::iterator new_beginning_keyframe =
1064 GetFirstKeyframeAt(timestamp, true); 1094 GetFirstKeyframeAt(timestamp, is_exclusive);
1065 1095
1066 // If there is no keyframe after |timestamp|, we can't split the range. 1096 // If there is no keyframe after |timestamp|, we can't split the range.
1067 if (new_beginning_keyframe == keyframe_map_.end()) 1097 if (new_beginning_keyframe == keyframe_map_.end())
1068 return NULL; 1098 return NULL;
1069 1099
1070 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 1100 // Remove the data beginning at |keyframe_index| from |buffers_| and save it
1071 // into |removed_buffers|. 1101 // into |removed_buffers|.
1072 int keyframe_index = new_beginning_keyframe->second; 1102 int keyframe_index = new_beginning_keyframe->second;
1073 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 1103 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
1074 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 1104 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
(...skipping 14 matching lines...) Expand all
1089 ResetNextBufferPosition(); 1119 ResetNextBufferPosition();
1090 } else if (waiting_for_keyframe_) { 1120 } else if (waiting_for_keyframe_) {
1091 split_range->waiting_for_keyframe_ = true; 1121 split_range->waiting_for_keyframe_ = true;
1092 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; 1122 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_;
1093 ResetNextBufferPosition(); 1123 ResetNextBufferPosition();
1094 } 1124 }
1095 1125
1096 return split_range; 1126 return split_range;
1097 } 1127 }
1098 1128
1129 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
1130 base::TimeDelta timestamp, bool skip_given_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
1137 if (skip_given_timestamp) {
1138 return std::upper_bound(
1139 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1140 } else {
acolwell GONE FROM CHROMIUM 2012/09/19 23:15:51 nit: drop else and deindent
vrk (LEFT CHROMIUM) 2012/09/20 00:00:59 Done.
1141 return std::lower_bound(
1142 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1143 }
1144 }
1145
1099 SourceBufferRange::KeyframeMap::iterator 1146 SourceBufferRange::KeyframeMap::iterator
1100 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, 1147 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp,
1101 bool skip_given_timestamp) { 1148 bool skip_given_timestamp) {
1102 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 1149 return skip_given_timestamp ?
1103 // lower_bound() returns the first element >= |timestamp|, so if we don't want 1150 keyframe_map_.upper_bound(timestamp) :
1104 // to include keyframes == |timestamp|, we have to increment the iterator 1151 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 } 1152 }
1112 1153
1113 SourceBufferRange::KeyframeMap::iterator 1154 SourceBufferRange::KeyframeMap::iterator
1114 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { 1155 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) {
1115 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); 1156 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
1116 // lower_bound() returns the first element >= |timestamp|, so we want the 1157 // lower_bound() returns the first element >= |timestamp|, so we want the
1117 // previous element if it did not return the element exactly equal to 1158 // previous element if it did not return the element exactly equal to
1118 // |timestamp|. 1159 // |timestamp|.
1119 if (result != keyframe_map_.begin() && 1160 if (result != keyframe_map_.begin() &&
1120 (result == keyframe_map_.end() || result->first != timestamp)) { 1161 (result == keyframe_map_.end() || result->first != timestamp)) {
1121 --result; 1162 --result;
1122 } 1163 }
1123 return result; 1164 return result;
1124 } 1165 }
1125 1166
1126 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 1167 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
1127 return TruncateAt(buffers_.begin(), removed_buffers); 1168 return TruncateAt(buffers_.begin(), removed_buffers);
1128 } 1169 }
1129 1170
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( 1171 bool SourceBufferRange::TruncateAt(
1140 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { 1172 base::TimeDelta timestamp, BufferQueue* removed_buffers,
1173 bool is_exclusive) {
1141 // Find the place in |buffers_| where we will begin deleting data. 1174 // Find the place in |buffers_| where we will begin deleting data.
1142 BufferQueue::iterator starting_point = 1175 BufferQueue::iterator starting_point =
1143 std::lower_bound(buffers_.begin(), buffers_.end(), 1176 GetBufferItrAt(timestamp, is_exclusive);
1144 buffer,
1145 BufferComparator);
1146 return TruncateAt(starting_point, removed_buffers); 1177 return TruncateAt(starting_point, removed_buffers);
1147 } 1178 }
1148 1179
1149 int SourceBufferRange::FreeFromStart(int bytes) { 1180 int SourceBufferRange::FreeFromStart(int bytes) {
1150 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); 1181 KeyframeMap::iterator deletion_limit = keyframe_map_.end();
1151 if (HasNextBufferPosition()) { 1182 if (HasNextBufferPosition()) {
1152 base::TimeDelta next_timestamp = GetNextTimestamp(); 1183 base::TimeDelta next_timestamp = GetNextTimestamp();
1153 if (next_timestamp != kNoTimestamp()) { 1184 if (next_timestamp != kNoTimestamp()) {
1154 deletion_limit = GetFirstKeyframeBefore(next_timestamp); 1185 deletion_limit = GetFirstKeyframeBefore(next_timestamp);
1155 } else { 1186 } else {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 DCHECK(!buffers_.empty()); 1433 DCHECK(!buffers_.empty());
1403 base::TimeDelta duration = buffers_.back()->GetDuration(); 1434 base::TimeDelta duration = buffers_.back()->GetDuration();
1404 if (duration == kNoTimestamp() || duration == base::TimeDelta()) 1435 if (duration == kNoTimestamp() || duration == base::TimeDelta())
1405 duration = GetApproximateDuration(); 1436 duration = GetApproximateDuration();
1406 return GetEndTimestamp() + duration; 1437 return GetEndTimestamp() + duration;
1407 } 1438 }
1408 1439
1409 bool SourceBufferRange::IsNextInSequence( 1440 bool SourceBufferRange::IsNextInSequence(
1410 const scoped_refptr<media::StreamParserBuffer>& buffer, 1441 const scoped_refptr<media::StreamParserBuffer>& buffer,
1411 base::TimeDelta timestamp) const { 1442 base::TimeDelta timestamp) const {
1412 return buffer->GetDecodeTimestamp() < timestamp && 1443 return AreAdjacentInSequence(buffer->GetDecodeTimestamp(), timestamp);
1413 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); 1444 }
1445
1446 bool SourceBufferRange::AreAdjacentInSequence(
1447 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const {
1448 return first_timestamp < second_timestamp &&
1449 second_timestamp <= first_timestamp + GetFudgeRoom();
1414 } 1450 }
1415 1451
1416 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { 1452 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
1417 // Because we do not know exactly when is the next timestamp, any buffer 1453 // Because we do not know exactly when is the next timestamp, any buffer
1418 // that starts within 2x the approximate duration of a buffer is considered 1454 // that starts within 2x the approximate duration of a buffer is considered
1419 // within this range. 1455 // within this range.
1420 return 2 * GetApproximateDuration(); 1456 return 2 * GetApproximateDuration();
1421 } 1457 }
1422 1458
1423 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 1459 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
1424 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 1460 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
1425 DCHECK(max_interbuffer_distance != kNoTimestamp()); 1461 DCHECK(max_interbuffer_distance != kNoTimestamp());
1426 return max_interbuffer_distance; 1462 return max_interbuffer_distance;
1427 } 1463 }
1428 1464
1429 } // namespace media 1465 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698