OLD | NEW |
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/logging.h" | 10 #include "base/logging.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // filled with a valid buffer, false if there is not enough data to fulfill | 79 // filled with a valid buffer, false if there is not enough data to fulfill |
80 // the request. | 80 // the request. |
81 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); | 81 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); |
82 bool HasNextBuffer() const; | 82 bool HasNextBuffer() const; |
83 | 83 |
84 // Returns the timestamp of the next buffer that will be returned from | 84 // Returns the timestamp of the next buffer that will be returned from |
85 // GetNextBuffer(). Returns kNoTimestamp() if Seek() has never been called or | 85 // GetNextBuffer(). Returns kNoTimestamp() if Seek() has never been called or |
86 // if this range does not have the next buffer yet. | 86 // if this range does not have the next buffer yet. |
87 base::TimeDelta GetNextTimestamp() const; | 87 base::TimeDelta GetNextTimestamp() const; |
88 | 88 |
| 89 // Returns the start timestamp of the range. |
| 90 base::TimeDelta GetStartTimestamp() const; |
| 91 |
89 // Returns the end timestamp of the buffered data. (Note that this is equal to | 92 // Returns the end timestamp of the buffered data. (Note that this is equal to |
90 // the last buffer's timestamp + its duration.) | 93 // the last buffer's timestamp + its duration.) |
91 base::TimeDelta GetEndTimestamp() const; | 94 base::TimeDelta GetEndTimestamp() const; |
92 | 95 |
93 // Returns the Timespan of buffered time in this range. | |
94 SourceBufferStream::Timespan GetBufferedTime() const; | |
95 | |
96 // Returns whether a buffer with a starting timestamp of |timestamp| would | 96 // Returns whether a buffer with a starting timestamp of |timestamp| would |
97 // belong in this range. This includes a buffer that would be appended to | 97 // belong in this range. This includes a buffer that would be appended to |
98 // the end of the range. | 98 // the end of the range. |
99 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears | 99 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears |
100 // before this range, or 1 if |timestamp| appears after this range. | 100 // before this range, or 1 if |timestamp| appears after this range. |
101 int BelongsToRange(base::TimeDelta timestamp) const; | 101 int BelongsToRange(base::TimeDelta timestamp) const; |
102 | 102 |
103 // Returns true if the range has enough data to seek to the specified | 103 // Returns true if the range has enough data to seek to the specified |
104 // |timestamp|, false otherwise. | 104 // |timestamp|, false otherwise. |
105 bool CanSeekTo(base::TimeDelta timestamp) const; | 105 bool CanSeekTo(base::TimeDelta timestamp) const; |
106 | 106 |
107 // Returns true if this range's buffered timespan completely overlaps the | 107 // Returns true if this range's buffered timespan completely overlaps the |
108 // buffered timespan of |range|. | 108 // buffered timespan of |range|. |
109 bool CompletelyOverlaps(const SourceBufferRange& range) const; | 109 bool CompletelyOverlaps(const SourceBufferRange& range) const; |
110 | 110 |
111 // Returns true if the end of this range contains buffers that overlaps with | 111 // Returns true if the end of this range contains buffers that overlaps with |
112 // the beginning of |range|. | 112 // the beginning of |range|. |
113 bool EndOverlaps(const SourceBufferRange& range) const; | 113 bool EndOverlaps(const SourceBufferRange& range) const; |
114 | 114 |
115 private: | 115 private: |
116 // Helper method to delete buffers in |buffers_| starting from | 116 // Helper method to delete buffers in |buffers_| starting from |
117 // |starting_point|, an iterator in |buffers_|. | 117 // |starting_point|, an iterator in |buffers_|. |
118 void DeleteAfter(const BufferQueue::iterator& starting_point, | 118 void DeleteAfter(const BufferQueue::iterator& starting_point, |
119 BufferQueue* deleted_buffers, | 119 BufferQueue* deleted_buffers, |
120 BufferQueue::iterator* next_buffer); | 120 BufferQueue::iterator* next_buffer); |
121 | 121 |
122 // Returns the start timestamp of the range. | |
123 base::TimeDelta GetStartTimestamp() const; | |
124 | |
125 // An ordered list of buffers in this range. | 122 // An ordered list of buffers in this range. |
126 BufferQueue buffers_; | 123 BufferQueue buffers_; |
127 | 124 |
128 // Maps keyframe timestamps to its index position in |buffers_|. | 125 // Maps keyframe timestamps to its index position in |buffers_|. |
129 typedef std::map<base::TimeDelta, size_t> KeyframeMap; | 126 typedef std::map<base::TimeDelta, size_t> KeyframeMap; |
130 KeyframeMap keyframe_map_; | 127 KeyframeMap keyframe_map_; |
131 | 128 |
132 // Index into |buffers_| for the next buffer to be returned by | 129 // Index into |buffers_| for the next buffer to be returned by |
133 // GetBufferedTime(), set to -1 before Seek(). | 130 // GetNextBuffer(), set to -1 before Seek(). |
134 int next_buffer_index_; | 131 int next_buffer_index_; |
135 | 132 |
136 // True if the range needs to wait for the next keyframe to be appended before | 133 // True if the range needs to wait for the next keyframe to be appended before |
137 // returning buffers from GetNextBuffer(). | 134 // returning buffers from GetNextBuffer(). |
138 bool waiting_for_keyframe_; | 135 bool waiting_for_keyframe_; |
139 | 136 |
140 // If |waiting_for_keyframe_| is true, this range will wait for the next | 137 // If |waiting_for_keyframe_| is true, this range will wait for the next |
141 // keyframe with timestamp >= |next_keyframe_timestamp_|. | 138 // keyframe with timestamp >= |next_keyframe_timestamp_|. |
142 base::TimeDelta next_keyframe_timestamp_; | 139 base::TimeDelta next_keyframe_timestamp_; |
143 | 140 |
(...skipping 12 matching lines...) Expand all Loading... |
156 | 153 |
157 } // namespace media | 154 } // namespace media |
158 | 155 |
159 // Helper method that returns true if |ranges| is sorted in increasing order, | 156 // Helper method that returns true if |ranges| is sorted in increasing order, |
160 // false otherwise. | 157 // false otherwise. |
161 static bool IsRangeListSorted( | 158 static bool IsRangeListSorted( |
162 const std::list<media::SourceBufferRange*>& ranges) { | 159 const std::list<media::SourceBufferRange*>& ranges) { |
163 base::TimeDelta prev = media::kNoTimestamp(); | 160 base::TimeDelta prev = media::kNoTimestamp(); |
164 for (std::list<media::SourceBufferRange*>::const_iterator itr = | 161 for (std::list<media::SourceBufferRange*>::const_iterator itr = |
165 ranges.begin(); itr != ranges.end(); itr++) { | 162 ranges.begin(); itr != ranges.end(); itr++) { |
166 media::SourceBufferStream::Timespan buffered = (*itr)->GetBufferedTime(); | 163 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
167 if (prev != media::kNoTimestamp() && prev >= buffered.first) | |
168 return false; | 164 return false; |
169 prev = buffered.second; | 165 prev = (*itr)->GetEndTimestamp(); |
170 } | 166 } |
171 return true; | 167 return true; |
172 } | 168 } |
173 | 169 |
174 // Comparison function for two Buffers based on timestamp. | 170 // Comparison function for two Buffers based on timestamp. |
175 static bool BufferComparator( | 171 static bool BufferComparator( |
176 const scoped_refptr<media::StreamParserBuffer>& first, | 172 const scoped_refptr<media::StreamParserBuffer>& first, |
177 const scoped_refptr<media::StreamParserBuffer>& second) { | 173 const scoped_refptr<media::StreamParserBuffer>& second) { |
178 return first->GetTimestamp() < second->GetTimestamp(); | 174 return first->GetTimestamp() < second->GetTimestamp(); |
179 } | 175 } |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 | 492 |
497 if (end_of_stream_ && (!selected_range_ || | 493 if (end_of_stream_ && (!selected_range_ || |
498 !selected_range_->HasNextBuffer())) { | 494 !selected_range_->HasNextBuffer())) { |
499 *out_buffer = StreamParserBuffer::CreateEOSBuffer(); | 495 *out_buffer = StreamParserBuffer::CreateEOSBuffer(); |
500 return true; | 496 return true; |
501 } | 497 } |
502 | 498 |
503 return selected_range_ && selected_range_->GetNextBuffer(out_buffer); | 499 return selected_range_ && selected_range_->GetNextBuffer(out_buffer); |
504 } | 500 } |
505 | 501 |
506 SourceBufferStream::TimespanList SourceBufferStream::GetBufferedTime() const { | 502 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { |
507 TimespanList timespans; | 503 Ranges<base::TimeDelta> ranges; |
508 for (RangeList::const_iterator itr = ranges_.begin(); | 504 for (RangeList::const_iterator itr = ranges_.begin(); |
509 itr != ranges_.end(); itr++) { | 505 itr != ranges_.end(); itr++) { |
510 timespans.push_back((*itr)->GetBufferedTime()); | 506 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetEndTimestamp()); |
511 } | 507 } |
512 return timespans; | 508 return ranges; |
513 } | 509 } |
514 | 510 |
515 void SourceBufferStream::EndOfStream() { | 511 void SourceBufferStream::EndOfStream() { |
516 DCHECK(CanEndOfStream()); | 512 DCHECK(CanEndOfStream()); |
517 end_of_stream_ = true; | 513 end_of_stream_ = true; |
518 } | 514 } |
519 | 515 |
520 bool SourceBufferStream::CanEndOfStream() const { | 516 bool SourceBufferStream::CanEndOfStream() const { |
521 return ranges_.empty() || selected_range_ == ranges_.back(); | 517 return ranges_.empty() || selected_range_ == ranges_.back(); |
522 } | 518 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 DCHECK(!buffers_.empty()); | 692 DCHECK(!buffers_.empty()); |
697 | 693 |
698 if (next_buffer_index_ >= static_cast<int>(buffers_.size()) || | 694 if (next_buffer_index_ >= static_cast<int>(buffers_.size()) || |
699 next_buffer_index_ < 0 || waiting_for_keyframe_) { | 695 next_buffer_index_ < 0 || waiting_for_keyframe_) { |
700 return kNoTimestamp(); | 696 return kNoTimestamp(); |
701 } | 697 } |
702 | 698 |
703 return buffers_.at(next_buffer_index_)->GetTimestamp(); | 699 return buffers_.at(next_buffer_index_)->GetTimestamp(); |
704 } | 700 } |
705 | 701 |
706 SourceBufferStream::Timespan | |
707 SourceBufferRange::GetBufferedTime() const { | |
708 return std::make_pair(GetStartTimestamp(), GetEndTimestamp()); | |
709 } | |
710 | |
711 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, | 702 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, |
712 bool transfer_current_position) { | 703 bool transfer_current_position) { |
713 DCHECK(CanAppendToEnd(range)); | 704 DCHECK(CanAppendToEnd(range)); |
714 DCHECK(!buffers_.empty()); | 705 DCHECK(!buffers_.empty()); |
715 | 706 |
716 if (transfer_current_position) | 707 if (transfer_current_position) |
717 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); | 708 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); |
718 | 709 |
719 AppendToEnd(range.buffers_); | 710 AppendToEnd(range.buffers_); |
720 } | 711 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 start_timestamp = buffers_.front()->GetTimestamp(); | 757 start_timestamp = buffers_.front()->GetTimestamp(); |
767 return start_timestamp; | 758 return start_timestamp; |
768 } | 759 } |
769 | 760 |
770 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { | 761 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { |
771 DCHECK(!buffers_.empty()); | 762 DCHECK(!buffers_.empty()); |
772 return buffers_.back()->GetEndTimestamp(); | 763 return buffers_.back()->GetEndTimestamp(); |
773 } | 764 } |
774 | 765 |
775 } // namespace media | 766 } // namespace media |
OLD | NEW |