| 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 |