| 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" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 | 13 |
| 14 // Helper class representing a range of buffered data. All buffers in a | 14 // Helper class representing a range of buffered data. All buffers in a |
| 15 // SourceBufferRange are ordered sequentially in presentation order with no | 15 // SourceBufferRange are ordered sequentially in presentation order with no |
| 16 // gaps. | 16 // gaps. |
| 17 class SourceBufferRange { | 17 class SourceBufferRange { |
| 18 public: | 18 public: |
| 19 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 19 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
| 20 | 20 |
| 21 SourceBufferRange(); | 21 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be |
| 22 // empty and the front of |new_buffers| must be a keyframe. |
| 23 explicit SourceBufferRange(const BufferQueue& new_buffers); |
| 22 | 24 |
| 23 // Adds |new_buffers| into this range. |new_buffers| must belong to this | 25 // Appends |buffers| to the end of the range and updates |keyframe_map_| as |
| 24 // range. Garbage collection may occur after Append(). | 26 // it encounters new keyframes. Assumes |buffers| belongs at the end of the |
| 25 void Append(const BufferQueue& new_buffers); | 27 // range. |
| 28 void AppendToEnd(const BufferQueue& buffers); |
| 29 bool CanAppendToEnd(const BufferQueue& buffers) const; |
| 30 |
| 31 // Appends the buffers from |range| into this range. |
| 32 // The first buffer in |range| must come directly after the last buffer |
| 33 // in this range. |
| 34 // If |transfer_current_position| is true, |range|'s |next_buffer_index_| |
| 35 // is transfered to this SourceBufferRange. |
| 36 void AppendToEnd(const SourceBufferRange& range, |
| 37 bool transfer_current_position); |
| 38 bool CanAppendToEnd(const SourceBufferRange& range) const; |
| 26 | 39 |
| 27 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. | 40 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. |
| 28 // Assumes |timestamp| is valid and in this range. | 41 // Assumes |timestamp| is valid and in this range. |
| 29 void Seek(base::TimeDelta timestamp); | 42 void Seek(base::TimeDelta timestamp); |
| 30 | 43 |
| 31 // Updates |next_buffer_index_| to point to next keyframe after or equal to | 44 // Updates |next_buffer_index_| to point to next keyframe after or equal to |
| 32 // |timestamp|. If there is no such keyframe, then this range will seek to | 45 // |timestamp|. |
| 33 // the end and return kNoTimestamp(). | 46 void SeekAfter(base::TimeDelta timestamp); |
| 34 // Assumes |timestamp| is valid and in this range. | 47 |
| 35 base::TimeDelta SeekAfter(base::TimeDelta timestamp); | 48 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and |
| 49 // returns a new SourceBufferRange with the buffers from that keyframe onward. |
| 50 // The buffers in the new SourceBufferRange are moved out of this range. If |
| 51 // there is no keyframe after |timestamp|, SplitRange() returns null and this |
| 52 // range is unmodified. |
| 53 SourceBufferRange* SplitRange(base::TimeDelta timestamp); |
| 54 |
| 55 // Deletes the buffers from this range whose timestamps are greater than or |
| 56 // equal to |buffer|'s timestamp. |
| 57 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was |
| 58 // deleted, and deletes the |keyframe_map_| entries for the buffers that |
| 59 // were removed. |
| 60 // If |deleted_buffers| or |next_buffer| are null, they are ignored. |
| 61 // Otherwise, |deleted_buffers| contains the buffers that were deleted from |
| 62 // this range, and |next_buffer| points to the buffer in |deleted_buffers| |
| 63 // that had been at |next_buffer_index_|. If |next_buffer_index_| did not |
| 64 // point to any buffer added to |deleted_buffers|, then |next_buffer| points |
| 65 // to |deleted_buffers.end()|. |
| 66 void DeleteAfter(scoped_refptr<StreamParserBuffer> buffer, |
| 67 BufferQueue* deleted_buffers, |
| 68 BufferQueue::iterator* next_buffer); |
| 69 // Deletes all buffers in range. |
| 70 void DeleteAll(BufferQueue* deleted_buffers, |
| 71 BufferQueue::iterator* next_buffer); |
| 36 | 72 |
| 37 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 73 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
| 38 // must be called before calls to GetNextBuffer(), and buffers are returned | 74 // must be called before calls to GetNextBuffer(), and buffers are returned |
| 39 // in order from the last call to Seek(). Returns true if |out_buffer| is | 75 // in order from the last call to Seek(). Returns true if |out_buffer| is |
| 40 // filled with a valid buffer, false if there is not enough data to fulfill | 76 // filled with a valid buffer, false if there is not enough data to fulfill |
| 41 // the request. | 77 // the request. |
| 42 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); | 78 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); |
| 43 bool HasNextBuffer() const; | 79 bool HasNextBuffer() const; |
| 80 |
| 81 // Returns the timestamp of the next buffer that will be returned from |
| 82 // GetNextBuffer(). Returns kNoTimestamp() if Seek() has never been called or |
| 83 // if this range does not have the next buffer yet. |
| 44 base::TimeDelta GetNextTimestamp() const; | 84 base::TimeDelta GetNextTimestamp() const; |
| 45 | 85 |
| 86 // Returns the end timestamp of the buffered data. (Note that this is equal to |
| 87 // the last buffer's timestamp + its duration.) |
| 88 base::TimeDelta GetEndTimestamp() const; |
| 89 |
| 46 // Returns the Timespan of buffered time in this range. | 90 // Returns the Timespan of buffered time in this range. |
| 47 SourceBufferStream::Timespan GetBufferedTime() const; | 91 SourceBufferStream::Timespan GetBufferedTime() const; |
| 48 | 92 |
| 49 // Appends the buffers from |range| into this range. | |
| 50 // The first buffer in |range| must come directly after the last buffer | |
| 51 // in this range. | |
| 52 // If |transfer_current_position| is true, |range|'s |next_buffer_position_| | |
| 53 // is transfered to this SourceBufferRange. | |
| 54 void AppendToEnd(const SourceBufferRange& range, | |
| 55 bool transfer_current_position); | |
| 56 bool CanAppendToEnd(const SourceBufferRange& range) const; | |
| 57 bool CanAppendToEnd(const BufferQueue& buffers) const; | |
| 58 | |
| 59 // Returns whether a buffer with a starting timestamp of |timestamp| would | 93 // Returns whether a buffer with a starting timestamp of |timestamp| would |
| 60 // belong in this range. This includes a buffer that would be appended to | 94 // belong in this range. This includes a buffer that would be appended to |
| 61 // the end of the range. | 95 // the end of the range. |
| 62 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears | 96 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears |
| 63 // before this range, or 1 if |timestamp| appears after this range. | 97 // before this range, or 1 if |timestamp| appears after this range. |
| 64 int BelongsToRange(base::TimeDelta timestamp) const; | 98 int BelongsToRange(base::TimeDelta timestamp) const; |
| 65 | 99 |
| 66 // Returns true if the range has enough data to seek to the specified | 100 // Returns true if the range has enough data to seek to the specified |
| 67 // |timestamp|, false otherwise. | 101 // |timestamp|, false otherwise. |
| 68 bool CanSeekTo(base::TimeDelta timestamp) const; | 102 bool CanSeekTo(base::TimeDelta timestamp) const; |
| 69 | 103 |
| 70 // Returns true if this range's buffered timespan completely overlaps the | 104 // Returns true if this range's buffered timespan completely overlaps the |
| 71 // buffered timespan of |range|. | 105 // buffered timespan of |range|. |
| 72 bool CompletelyOverlaps(const SourceBufferRange& range) const; | 106 bool CompletelyOverlaps(const SourceBufferRange& range) const; |
| 73 | 107 |
| 74 // Returns true if the end of this range contains buffers that overlaps with | 108 // Returns true if the end of this range contains buffers that overlaps with |
| 75 // the beginning of |range|. | 109 // the beginning of |range|. |
| 76 bool EndOverlaps(const SourceBufferRange& range) const; | 110 bool EndOverlaps(const SourceBufferRange& range) const; |
| 77 | 111 |
| 78 // Functions that tell how |buffers| intersects with this range. | 112 private: |
| 79 // TODO(vrk): These functions should be unnecessary when overlapping the | 113 // Helper method to delete buffers in |buffers_| starting from |
| 80 // selected range is implemented properly. (crbug.com/126560) | 114 // |starting_point|, an iterator in |buffers_|. |
| 81 bool IsStartOverlappedBy(const BufferQueue& buffers) const; | 115 void DeleteAfter(BufferQueue::iterator starting_point, |
| 82 bool IsEndOverlappedBy(const BufferQueue& buffers) const; | 116 BufferQueue* deleted_buffers, |
| 83 bool IsCompletelyOverlappedBy(const BufferQueue& buffers) const; | 117 BufferQueue::iterator* next_buffer); |
| 84 | 118 |
| 85 private: | 119 // Returns the start timestamp of the range. |
| 86 // Appends |buffers| to the end of the range and updates |keyframe_map_| as | 120 base::TimeDelta GetStartTimestamp() const; |
| 87 // it encounters new keyframes. Assumes |buffers| belongs at the end of the | |
| 88 // range. | |
| 89 void AppendToEnd(const BufferQueue& buffers); | |
| 90 | |
| 91 // Returns the start timestamp of the range, or kNoTimestamp if the range is | |
| 92 // empty. | |
| 93 base::TimeDelta BufferedStart() const; | |
| 94 | |
| 95 // Returns the end timestamp of the buffered data. (Note that this is equal to | |
| 96 // the last buffer's timestamp + its duration.) Returns kNoTimestamp if the | |
| 97 // range is empty. | |
| 98 base::TimeDelta BufferedEnd() const; | |
| 99 | 121 |
| 100 // An ordered list of buffers in this range. | 122 // An ordered list of buffers in this range. |
| 101 BufferQueue buffers_; | 123 BufferQueue buffers_; |
| 102 | 124 |
| 103 // Maps keyframe timestamps to its index position in |buffers_|. | 125 // Maps keyframe timestamps to its index position in |buffers_|. |
| 104 typedef std::map<base::TimeDelta, size_t> KeyframeMap; | 126 typedef std::map<base::TimeDelta, size_t> KeyframeMap; |
| 105 KeyframeMap keyframe_map_; | 127 KeyframeMap keyframe_map_; |
| 106 | 128 |
| 107 // Index into |buffers_| for the next buffer to be returned by | 129 // Index into |buffers_| for the next buffer to be returned by |
| 108 // GetBufferedTime(), set to -1 before Seek(). | 130 // GetBufferedTime(), set to -1 before Seek(). |
| 109 int next_buffer_index_; | 131 int next_buffer_index_; |
| 110 | 132 |
| 133 // True if the range needs to wait for the next keyframe to be appended before |
| 134 // returning buffers from GetNextBuffer(). |
| 135 bool waiting_for_keyframe_; |
| 136 |
| 137 // If |waiting_for_keyframe_| is true, this range will wait for the next |
| 138 // keyframe with timestamp >= |next_keyframe_timestamp_|. |
| 139 base::TimeDelta next_keyframe_timestamp_; |
| 140 |
| 111 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); | 141 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); |
| 112 }; | 142 }; |
| 113 | 143 |
| 114 } // namespace media | 144 } // namespace media |
| 115 | 145 |
| 116 // Helper method that returns true if |ranges| is sorted in increasing order, | 146 // Helper method that returns true if |ranges| is sorted in increasing order, |
| 117 // false otherwise. | 147 // false otherwise. |
| 118 static bool IsRangeListSorted( | 148 static bool IsRangeListSorted( |
| 119 const std::list<media::SourceBufferRange*>& ranges) { | 149 const std::list<media::SourceBufferRange*>& ranges) { |
| 120 base::TimeDelta prev = media::kNoTimestamp(); | 150 base::TimeDelta prev = media::kNoTimestamp(); |
| 121 for (std::list<media::SourceBufferRange*>::const_iterator itr = | 151 for (std::list<media::SourceBufferRange*>::const_iterator itr = |
| 122 ranges.begin(); itr != ranges.end(); itr++) { | 152 ranges.begin(); itr != ranges.end(); itr++) { |
| 123 media::SourceBufferStream::Timespan buffered = (*itr)->GetBufferedTime(); | 153 media::SourceBufferStream::Timespan buffered = (*itr)->GetBufferedTime(); |
| 124 if (prev != media::kNoTimestamp() && prev >= buffered.first) | 154 if (prev != media::kNoTimestamp() && prev >= buffered.first) |
| 125 return false; | 155 return false; |
| 126 prev = buffered.second; | 156 prev = buffered.second; |
| 127 } | 157 } |
| 128 return true; | 158 return true; |
| 129 } | 159 } |
| 130 | 160 |
| 131 // Comparison function for two Buffers based on timestamp. | 161 // Comparison function for two Buffers based on timestamp. |
| 132 static bool BufferComparator(scoped_refptr<media::Buffer> first, | 162 static bool BufferComparator( |
| 133 scoped_refptr<media::Buffer> second) { | 163 const scoped_refptr<media::StreamParserBuffer>& first, |
| 164 const scoped_refptr<media::StreamParserBuffer>& second) { |
| 134 return first->GetTimestamp() < second->GetTimestamp(); | 165 return first->GetTimestamp() < second->GetTimestamp(); |
| 135 } | 166 } |
| 136 | 167 |
| 137 // Returns the upper bound for the starting timestamp for the next buffer | 168 // Returns the upper bound for the starting timestamp for the next buffer |
| 138 // in sequence after |buffer|. Assumes |buffer|'s timestamp and | 169 // in sequence after |buffer|. Assumes |buffer|'s timestamp and |
| 139 // duration are valid. | 170 // duration are valid. |
| 140 static base::TimeDelta MaxNextTimestamp( | 171 static base::TimeDelta MaxNextTimestamp( |
| 141 const scoped_refptr<media::StreamParserBuffer>& buffer) { | 172 const scoped_refptr<media::StreamParserBuffer>& buffer) { |
| 142 // Because we do not know exactly when is the next timestamp, any buffer | 173 // Because we do not know exactly when is the next timestamp, any buffer |
| 143 // that starts within 1/3 of the duration past the end of this buffer | 174 // that starts within 1/3 of the duration past the end of this buffer |
| 144 // is considered the next buffer in the sequence. | 175 // is considered the next buffer in the sequence. |
| 145 return buffer->GetEndTimestamp() + buffer->GetDuration() / 3; | 176 return buffer->GetEndTimestamp() + buffer->GetDuration() / 3; |
| 146 } | 177 } |
| 147 | 178 |
| 148 // Returns true if |timestamp| is the timestamp of the next buffer in | 179 // Returns true if |timestamp| is the timestamp of the next buffer in |
| 149 // sequence after |buffer|, false otherwise. | 180 // sequence after |buffer|, false otherwise. |
| 150 static bool IsNextInSequence( | 181 static bool IsNextInSequence( |
| 151 const scoped_refptr<media::StreamParserBuffer>& buffer, | 182 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 152 base::TimeDelta timestamp) { | 183 base::TimeDelta timestamp) { |
| 153 return timestamp >= buffer->GetEndTimestamp() && | 184 return timestamp >= buffer->GetEndTimestamp() && |
| 154 timestamp <= MaxNextTimestamp(buffer); | 185 timestamp <= MaxNextTimestamp(buffer); |
| 155 } | 186 } |
| 156 | 187 |
| 157 namespace media { | 188 namespace media { |
| 158 | 189 |
| 159 SourceBufferStream::SourceBufferStream() | 190 SourceBufferStream::SourceBufferStream() |
| 160 : seek_pending_(true), | 191 : seek_pending_(true), |
| 161 seek_buffer_timestamp_(base::TimeDelta()), | 192 seek_buffer_timestamp_(base::TimeDelta()), |
| 162 selected_range_(NULL), | 193 selected_range_(NULL), |
| 163 waiting_for_keyframe_(false), | |
| 164 end_of_stream_(false) { | 194 end_of_stream_(false) { |
| 165 } | 195 } |
| 166 | 196 |
| 167 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) | 197 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) |
| 168 : seek_pending_(true), | 198 : seek_pending_(true), |
| 169 seek_buffer_timestamp_(base::TimeDelta()), | 199 seek_buffer_timestamp_(base::TimeDelta()), |
| 170 selected_range_(NULL), | 200 selected_range_(NULL), |
| 171 waiting_for_keyframe_(false), | |
| 172 end_of_stream_(false) { | 201 end_of_stream_(false) { |
| 173 audio_config_.CopyFrom(audio_config); | 202 audio_config_.CopyFrom(audio_config); |
| 174 } | 203 } |
| 175 | 204 |
| 176 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) | 205 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) |
| 177 : seek_pending_(true), | 206 : seek_pending_(true), |
| 178 seek_buffer_timestamp_(base::TimeDelta()), | 207 seek_buffer_timestamp_(base::TimeDelta()), |
| 179 selected_range_(NULL), | 208 selected_range_(NULL), |
| 180 waiting_for_keyframe_(false), | |
| 181 end_of_stream_(false) { | 209 end_of_stream_(false) { |
| 182 video_config_.CopyFrom(video_config); | 210 video_config_.CopyFrom(video_config); |
| 183 } | 211 } |
| 184 | 212 |
| 185 SourceBufferStream::~SourceBufferStream() { | 213 SourceBufferStream::~SourceBufferStream() { |
| 186 while (!ranges_.empty()) { | 214 while (!ranges_.empty()) { |
| 187 delete ranges_.front(); | 215 delete ranges_.front(); |
| 188 ranges_.pop_front(); | 216 ranges_.pop_front(); |
| 189 } | 217 } |
| 190 } | 218 } |
| 191 | 219 |
| 192 bool SourceBufferStream::Append( | 220 bool SourceBufferStream::Append( |
| 193 const SourceBufferStream::BufferQueue& buffers) { | 221 const SourceBufferStream::BufferQueue& buffers) { |
| 194 DCHECK(!buffers.empty()); | 222 DCHECK(!buffers.empty()); |
| 195 | 223 |
| 196 // Check to see if |buffers| will overlap the currently |selected_range_|, | 224 RangeList::iterator range_for_new_buffers = ranges_.end(); |
| 197 // and if so, ignore this Append() request. | |
| 198 // TODO(vrk): Support overlapping selected range properly. (crbug.com/126560) | |
| 199 if (selected_range_ && | |
| 200 (selected_range_->IsEndOverlappedBy(buffers) || | |
| 201 selected_range_->IsStartOverlappedBy(buffers))) { | |
| 202 return false; | |
| 203 } | |
| 204 | |
| 205 SourceBufferRange* range = NULL; | |
| 206 RangeList::iterator itr = ranges_.end(); | 225 RangeList::iterator itr = ranges_.end(); |
| 207 base::TimeDelta start_timestamp = buffers.front()->GetTimestamp(); | 226 base::TimeDelta start_timestamp = buffers.front()->GetTimestamp(); |
| 208 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) { | 227 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) { |
| 209 int range_value = (*itr)->BelongsToRange(start_timestamp); | 228 int range_value = (*itr)->BelongsToRange(start_timestamp); |
| 210 | |
| 211 // |start_timestamp| is before the current range in this loop. Because | 229 // |start_timestamp| is before the current range in this loop. Because |
| 212 // |ranges_| is sorted, this means that we need to create a new range and it | 230 // |ranges_| is sorted, this means that we need to create a new range and |
| 213 // should be placed before |itr|. | 231 // should be placed before |itr|. |
| 214 // TODO(vrk): We also break out of the loop if |buffers| completely overlaps | 232 if (range_value < 0) |
| 215 // the current range. This is to cover the case when |buffers| belongs to | |
| 216 // the current range, but also completely overlaps it. This should be | |
| 217 // removed when start overlap is handled properly. | |
| 218 if (range_value < 0 || (*itr)->IsCompletelyOverlappedBy(buffers)) | |
| 219 break; | 233 break; |
| 220 | 234 |
| 221 if (range_value == 0) { | 235 if (range_value == 0) { |
| 222 // Found an existing range into which we can append buffers. | 236 // Found an existing range into which we can append buffers. |
| 223 range = *itr; | 237 range_for_new_buffers = itr; |
| 224 | |
| 225 if (range->CanAppendToEnd(buffers) && waiting_for_keyframe_) { | |
| 226 // Currently we do not support the case where the next buffer after the | |
| 227 // buffers in the track buffer is not a keyframe. | |
| 228 if (!buffers.front()->IsKeyframe()) | |
| 229 return false; | |
| 230 waiting_for_keyframe_ = false; | |
| 231 } | |
| 232 break; | 238 break; |
| 233 } | 239 } |
| 234 } | 240 } |
| 235 | 241 |
| 236 if (!range) { | 242 if (range_for_new_buffers == ranges_.end()) { |
| 237 // Ranges must begin with a keyframe. | 243 // Ranges must begin with a keyframe. |
| 238 if (!buffers.front()->IsKeyframe()) | 244 if (!buffers.front()->IsKeyframe()) |
| 239 return false; | 245 return false; |
| 240 | 246 range_for_new_buffers = |
| 241 range = new SourceBufferRange(); | 247 ranges_.insert(itr, new SourceBufferRange(buffers)); |
| 242 itr = ranges_.insert(itr, range); | 248 } else { |
| 249 InsertIntoExistingRange(range_for_new_buffers, buffers); |
| 243 } | 250 } |
| 244 | 251 |
| 245 // Append buffers to the appropriate range. | |
| 246 range->Append(buffers); | |
| 247 | |
| 248 // Increment |itr| to be the range after |range|. | |
| 249 itr++; | |
| 250 | |
| 251 // Resolve overlaps. | 252 // Resolve overlaps. |
| 252 itr = ResolveCompleteOverlaps(itr, range); | 253 ResolveCompleteOverlaps(range_for_new_buffers); |
| 253 itr = ResolveEndOverlaps(itr, range); | 254 ResolveEndOverlap(range_for_new_buffers); |
| 254 MergeWithAdjacentRangeIfNecessary(itr, range); | 255 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); |
| 255 | 256 |
| 256 // Finally, try to complete pending seek if one exists. | 257 // Finally, try to complete pending seek if one exists. |
| 257 if (seek_pending_) | 258 if (seek_pending_) |
| 258 Seek(seek_buffer_timestamp_); | 259 Seek(seek_buffer_timestamp_); |
| 259 | 260 |
| 260 DCHECK(IsRangeListSorted(ranges_)); | 261 DCHECK(IsRangeListSorted(ranges_)); |
| 261 return true; | 262 return true; |
| 262 } | 263 } |
| 263 | 264 |
| 264 SourceBufferStream::RangeList::iterator | 265 void SourceBufferStream::InsertIntoExistingRange( |
| 265 SourceBufferStream::ResolveCompleteOverlaps( | 266 const RangeList::iterator& range_for_new_buffers_itr, |
| 266 const RangeList::iterator& range_itr, SourceBufferRange* new_range) { | 267 const BufferQueue& new_buffers) { |
| 267 RangeList::iterator itr = range_itr; | 268 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
| 268 while (itr != ranges_.end() && new_range->CompletelyOverlaps(**itr)) { | 269 RangeList::iterator next_range_itr = range_for_new_buffers_itr; |
| 269 if (*itr == selected_range_) { | 270 next_range_itr++; |
| 270 // Get the timestamp for the next buffer in the sequence. | |
| 271 base::TimeDelta next_timestamp = selected_range_->GetNextTimestamp(); | |
| 272 // Then seek to the next keyframe after (or equal to) |next_timestamp|. | |
| 273 // This will allow us to transition from the old buffers to the new | |
| 274 // buffers seamlessly. | |
| 275 base::TimeDelta next_keyframe_timestamp = | |
| 276 new_range->SeekAfter(next_timestamp); | |
| 277 | 271 |
| 278 // If there's no keyframe after |next_timestamp|, then set flag to wait | 272 // In case this is a middle overlap, save the buffers that come after the end |
| 279 // for the next keyframe in this range to be appended. | 273 // of |new_buffers|, and add them into a new range. |
| 280 if (next_keyframe_timestamp == kNoTimestamp()) | 274 SourceBufferRange* new_portion = |
| 281 waiting_for_keyframe_ = true; | 275 range_for_new_buffers->SplitRange(new_buffers.back()->GetEndTimestamp()); |
| 282 | 276 |
| 283 // Add all the old buffers up until |next_keyframe_timestamp| into | 277 if (new_portion) { |
| 284 // |track_buffer_|. If there was no keyframe, then we add all buffers into | 278 next_range_itr = ranges_.insert(next_range_itr, new_portion); |
| 285 // |track_buffer_|. | 279 // If |range_for_new_buffers| was selected and the next buffer was in the |
| 286 scoped_refptr<StreamParserBuffer> next_buffer; | 280 // |new_portion| half, update |selected_range_|. |
| 287 while (selected_range_->GetNextBuffer(&next_buffer) && | 281 if (selected_range_ == range_for_new_buffers && |
| 288 (waiting_for_keyframe_ || | 282 new_portion->GetNextTimestamp() != kNoTimestamp()) { |
| 289 next_buffer->GetTimestamp() < next_keyframe_timestamp)) { | 283 selected_range_ = new_portion; |
| 290 track_buffer_.push_back(next_buffer); | 284 } |
| 291 } | 285 } |
| 292 | 286 |
| 293 selected_range_ = new_range; | 287 BufferQueue deleted_buffers; |
| 294 } | 288 BufferQueue::iterator next_buffer; |
| 295 delete *itr; | 289 range_for_new_buffers->DeleteAfter( |
| 296 itr = ranges_.erase(itr); | 290 new_buffers.front(), &deleted_buffers, &next_buffer); |
| 291 range_for_new_buffers->AppendToEnd(new_buffers); |
| 292 |
| 293 if (selected_range_ == range_for_new_buffers && |
| 294 !deleted_buffers.empty() && next_buffer != deleted_buffers.end()) { |
| 295 UpdateTrackBuffer(range_for_new_buffers_itr, deleted_buffers, next_buffer); |
| 297 } | 296 } |
| 298 return itr; | |
| 299 } | 297 } |
| 300 | 298 |
| 301 SourceBufferStream::RangeList::iterator | 299 void SourceBufferStream::ResolveCompleteOverlaps( |
| 302 SourceBufferStream::ResolveEndOverlaps( | 300 const RangeList::iterator& range_with_new_buffers_itr) { |
| 303 const RangeList::iterator& range_itr, SourceBufferRange* new_range) { | 301 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 304 RangeList::iterator itr = range_itr; | 302 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| 305 while (itr != ranges_.end() && new_range->EndOverlaps(**itr)) { | 303 next_range_itr++; |
| 306 DCHECK_NE(*itr, selected_range_); | 304 |
| 307 delete *itr; | 305 while (next_range_itr != ranges_.end() && |
| 308 itr = ranges_.erase(itr); | 306 range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) { |
| 307 if (*next_range_itr == selected_range_) { |
| 308 // Delete everything from the selected range that |new_range| overlaps, |
| 309 // and save the next buffers. |
| 310 BufferQueue deleted_buffers; |
| 311 BufferQueue::iterator next_buffer; |
| 312 (*next_range_itr)->DeleteAll(&deleted_buffers, &next_buffer); |
| 313 UpdateTrackBuffer(range_with_new_buffers_itr, deleted_buffers, |
| 314 next_buffer); |
| 315 DCHECK_NE(selected_range_, *next_range_itr); |
| 316 } |
| 317 delete *next_range_itr; |
| 318 next_range_itr = ranges_.erase(next_range_itr); |
| 309 } | 319 } |
| 310 return itr; | 320 } |
| 321 |
| 322 void SourceBufferStream::ResolveEndOverlap( |
| 323 const RangeList::iterator& range_with_new_buffers_itr) { |
| 324 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 325 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| 326 next_range_itr++; |
| 327 |
| 328 if (next_range_itr == ranges_.end() || |
| 329 !range_with_new_buffers->EndOverlaps(**next_range_itr)) { |
| 330 return; |
| 331 } |
| 332 |
| 333 // Split the overlapped range after |range_with_new_buffers|'s last buffer |
| 334 // overlaps. Now |overlapped_range| contains only the buffers that do not |
| 335 // belong in |ranges_| anymore, and |new_next_range| contains buffers that |
| 336 // go after |range_with_new_buffers| (without overlap). |
| 337 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); |
| 338 next_range_itr = ranges_.erase(next_range_itr); |
| 339 |
| 340 SourceBufferRange* new_next_range = |
| 341 overlapped_range->SplitRange(range_with_new_buffers->GetEndTimestamp()); |
| 342 |
| 343 // If there were non-overlapped buffers, add the new range to |ranges_|. |
| 344 if (new_next_range) |
| 345 ranges_.insert(next_range_itr, new_next_range); |
| 346 |
| 347 // If we didn't overlap a selected range, return. |
| 348 if (selected_range_ != overlapped_range.get()) |
| 349 return; |
| 350 |
| 351 // If the next buffer was in the |new_next_range| half of the overlapped |
| 352 // range, then the |selected_range_| is now |new_next_range|. |
| 353 if (new_next_range && |
| 354 new_next_range->GetNextTimestamp() != kNoTimestamp()) { |
| 355 selected_range_ = new_next_range; |
| 356 return; |
| 357 } |
| 358 |
| 359 // Otherwise, update track buffer with overlapped buffers. |
| 360 BufferQueue deleted_buffers; |
| 361 scoped_refptr<StreamParserBuffer> buffer; |
| 362 while (overlapped_range->GetNextBuffer(&buffer)) { |
| 363 deleted_buffers.push_back(buffer); |
| 364 } |
| 365 BufferQueue::iterator next_buffer = deleted_buffers.begin(); |
| 366 |
| 367 // This will update |selected_range_| to no longer point to |
| 368 // |overlapped_range|. |
| 369 UpdateTrackBuffer(range_with_new_buffers_itr, deleted_buffers, next_buffer); |
| 370 DCHECK_NE(selected_range_, overlapped_range.get()); |
| 371 } |
| 372 |
| 373 void SourceBufferStream::UpdateTrackBuffer( |
| 374 const RangeList::iterator& range_with_new_buffers_itr, |
| 375 const BufferQueue& deleted_buffers, |
| 376 const BufferQueue::iterator& next_buffer) { |
| 377 DCHECK(!deleted_buffers.empty() && next_buffer != deleted_buffers.end()); |
| 378 |
| 379 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 380 |
| 381 // Seek to the next keyframe after (or equal to) the timestamp of the next |
| 382 // buffer being overlapped. |
| 383 range_with_new_buffers->SeekAfter((*next_buffer)->GetTimestamp()); |
| 384 selected_range_ = range_with_new_buffers; |
| 385 |
| 386 base::TimeDelta next_keyframe_timestamp = |
| 387 range_with_new_buffers->GetNextTimestamp(); |
| 388 |
| 389 if (track_buffer_.empty()) { |
| 390 // Add all the old buffers up until |next_keyframe_timestamp| into |
| 391 // |track_buffer_|. If there was no next keyframe, then we add all buffers |
| 392 // into |track_buffer_|. |
| 393 BufferQueue::iterator next_buffer_itr = next_buffer; |
| 394 while (next_buffer_itr != deleted_buffers.end() && |
| 395 (next_keyframe_timestamp == kNoTimestamp() || |
| 396 (*next_buffer_itr)->GetTimestamp() < next_keyframe_timestamp)) { |
| 397 track_buffer_.push_back(*next_buffer_itr); |
| 398 next_buffer_itr++; |
| 399 } |
| 400 } |
| 401 |
| 402 // See if the next range contains the keyframe after the end of the |
| 403 // |track_buffer_|, and if so, change |selected_range_|. |
| 404 if (next_keyframe_timestamp == kNoTimestamp()) { |
| 405 DCHECK(!track_buffer_.empty()); |
| 406 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| 407 next_range_itr++; |
| 408 if (next_range_itr != ranges_.end()) { |
| 409 (*next_range_itr)->SeekAfter(track_buffer_.back()->GetEndTimestamp()); |
| 410 if (IsNextInSequence(track_buffer_.back(), |
| 411 (*next_range_itr)->GetNextTimestamp())) { |
| 412 selected_range_ = *next_range_itr; |
| 413 } |
| 414 } |
| 415 } |
| 311 } | 416 } |
| 312 | 417 |
| 313 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( | 418 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( |
| 314 const RangeList::iterator& itr, SourceBufferRange* new_range) { | 419 const RangeList::iterator& range_with_new_buffers_itr) { |
| 315 if (itr != ranges_.end() && new_range->CanAppendToEnd(**itr)) { | 420 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 316 bool transfer_current_position = selected_range_ == *itr; | 421 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| 317 new_range->AppendToEnd(**itr, transfer_current_position); | 422 next_range_itr++; |
| 423 |
| 424 if (next_range_itr != ranges_.end() && |
| 425 range_with_new_buffers->CanAppendToEnd(**next_range_itr)) { |
| 426 bool transfer_current_position = selected_range_ == *next_range_itr; |
| 427 range_with_new_buffers->AppendToEnd(**next_range_itr, |
| 428 transfer_current_position); |
| 318 // Update |selected_range_| pointer if |range| has become selected after | 429 // Update |selected_range_| pointer if |range| has become selected after |
| 319 // merges. | 430 // merges. |
| 320 if (transfer_current_position) | 431 if (transfer_current_position) |
| 321 selected_range_ = new_range; | 432 selected_range_ = range_with_new_buffers; |
| 322 | 433 |
| 323 delete *itr; | 434 delete *next_range_itr; |
| 324 ranges_.erase(itr); | 435 ranges_.erase(next_range_itr); |
| 325 } | 436 } |
| 326 } | 437 } |
| 327 | 438 |
| 328 void SourceBufferStream::Seek(base::TimeDelta timestamp) { | 439 void SourceBufferStream::Seek(base::TimeDelta timestamp) { |
| 329 selected_range_ = NULL; | 440 selected_range_ = NULL; |
| 330 track_buffer_.clear(); | 441 track_buffer_.clear(); |
| 331 waiting_for_keyframe_ = false; | |
| 332 | 442 |
| 333 seek_buffer_timestamp_ = timestamp; | 443 seek_buffer_timestamp_ = timestamp; |
| 334 seek_pending_ = true; | 444 seek_pending_ = true; |
| 335 | 445 |
| 336 RangeList::iterator itr = ranges_.end(); | 446 RangeList::iterator itr = ranges_.end(); |
| 337 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) { | 447 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) { |
| 338 if ((*itr)->CanSeekTo(timestamp)) | 448 if ((*itr)->CanSeekTo(timestamp)) |
| 339 break; | 449 break; |
| 340 } | 450 } |
| 341 | 451 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 | 491 |
| 382 void SourceBufferStream::EndOfStream() { | 492 void SourceBufferStream::EndOfStream() { |
| 383 DCHECK(CanEndOfStream()); | 493 DCHECK(CanEndOfStream()); |
| 384 end_of_stream_ = true; | 494 end_of_stream_ = true; |
| 385 } | 495 } |
| 386 | 496 |
| 387 bool SourceBufferStream::CanEndOfStream() const { | 497 bool SourceBufferStream::CanEndOfStream() const { |
| 388 return ranges_.empty() || selected_range_ == ranges_.back(); | 498 return ranges_.empty() || selected_range_ == ranges_.back(); |
| 389 } | 499 } |
| 390 | 500 |
| 391 SourceBufferRange::SourceBufferRange() | 501 SourceBufferRange::SourceBufferRange(const BufferQueue& new_buffers) |
| 392 : next_buffer_index_(-1) { | 502 : next_buffer_index_(-1), |
| 393 } | 503 waiting_for_keyframe_(false), |
| 394 | 504 next_keyframe_timestamp_(kNoTimestamp()) { |
| 395 void SourceBufferRange::Append(const BufferQueue& new_buffers) { | 505 DCHECK(!new_buffers.empty()); |
| 396 base::TimeDelta start_timestamp = new_buffers.front()->GetTimestamp(); | 506 DCHECK(new_buffers.front()->IsKeyframe()); |
| 397 | |
| 398 if (!buffers_.empty() && start_timestamp < BufferedEnd()) { | |
| 399 // We are overwriting existing data, so find the starting point where | |
| 400 // things will get overwritten. | |
| 401 BufferQueue::iterator starting_point = | |
| 402 std::lower_bound(buffers_.begin(), buffers_.end(), | |
| 403 new_buffers.front(), | |
| 404 BufferComparator); | |
| 405 | |
| 406 // Remove everything from |starting_point| onward. | |
| 407 buffers_.erase(starting_point, buffers_.end()); | |
| 408 } | |
| 409 | |
| 410 // Append data. | |
| 411 AppendToEnd(new_buffers); | 507 AppendToEnd(new_buffers); |
| 412 } | 508 } |
| 413 | 509 |
| 414 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) { | 510 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) { |
| 415 for (BufferQueue::const_iterator itr = new_buffers.begin(); | 511 for (BufferQueue::const_iterator itr = new_buffers.begin(); |
| 416 itr != new_buffers.end(); itr++) { | 512 itr != new_buffers.end(); itr++) { |
| 417 DCHECK((*itr)->GetDuration() > base::TimeDelta()); | 513 DCHECK((*itr)->GetDuration() > base::TimeDelta()); |
| 418 DCHECK((*itr)->GetTimestamp() != kNoTimestamp()); | 514 DCHECK((*itr)->GetTimestamp() != kNoTimestamp()); |
| 419 buffers_.push_back(*itr); | 515 buffers_.push_back(*itr); |
| 420 if ((*itr)->IsKeyframe()) { | 516 if ((*itr)->IsKeyframe()) { |
| 421 keyframe_map_.insert( | 517 keyframe_map_.insert( |
| 422 std::make_pair((*itr)->GetTimestamp(), buffers_.size() - 1)); | 518 std::make_pair((*itr)->GetTimestamp(), buffers_.size() - 1)); |
| 519 |
| 520 if (waiting_for_keyframe_ && |
| 521 (*itr)->GetTimestamp() >= next_keyframe_timestamp_) { |
| 522 next_buffer_index_ = buffers_.size() - 1; |
| 523 next_keyframe_timestamp_ = base::TimeDelta(); |
| 524 waiting_for_keyframe_ = false; |
| 525 } |
| 423 } | 526 } |
| 424 } | 527 } |
| 425 } | 528 } |
| 426 | 529 |
| 427 void SourceBufferRange::Seek(base::TimeDelta timestamp) { | 530 void SourceBufferRange::Seek(base::TimeDelta timestamp) { |
| 428 DCHECK(CanSeekTo(timestamp)); | 531 DCHECK(CanSeekTo(timestamp)); |
| 429 DCHECK(!keyframe_map_.empty()); | 532 DCHECK(!keyframe_map_.empty()); |
| 430 | 533 |
| 534 next_keyframe_timestamp_ = base::TimeDelta(); |
| 535 waiting_for_keyframe_ = false; |
| 536 |
| 431 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 537 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
| 432 // lower_bound() returns the first element >= |timestamp|, so we want the | 538 // lower_bound() returns the first element >= |timestamp|, so we want the |
| 433 // previous element if it did not return the element exactly equal to | 539 // previous element if it did not return the element exactly equal to |
| 434 // |timestamp|. | 540 // |timestamp|. |
| 435 if (result == keyframe_map_.end() || result->first != timestamp) { | 541 if (result == keyframe_map_.end() || result->first != timestamp) { |
| 436 DCHECK(result != keyframe_map_.begin()); | 542 DCHECK(result != keyframe_map_.begin()); |
| 437 result--; | 543 result--; |
| 438 } | 544 } |
| 439 next_buffer_index_ = result->second; | 545 next_buffer_index_ = result->second; |
| 440 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 546 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
| 441 } | 547 } |
| 442 | 548 |
| 443 base::TimeDelta SourceBufferRange::SeekAfter(base::TimeDelta timestamp) { | 549 void SourceBufferRange::SeekAfter(base::TimeDelta timestamp) { |
| 444 DCHECK_EQ(BelongsToRange(timestamp), 0); | |
| 445 DCHECK(!keyframe_map_.empty()); | 550 DCHECK(!keyframe_map_.empty()); |
| 446 | 551 |
| 447 // lower_bound() returns the first element >= |timestamp|, so |result| is the | 552 // lower_bound() returns the first element >= |timestamp|, so |result| is the |
| 448 // value that we want. | 553 // value that we want. |
| 449 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 554 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
| 450 | 555 |
| 451 // If there isn't a keyframe after |timestamp|, then seek to end and return | 556 // If there isn't a keyframe after |timestamp|, then seek to end and return |
| 452 // kNoTimestamp to signal such. | 557 // kNoTimestamp to signal such. |
| 453 if (result == keyframe_map_.end()) { | 558 if (result == keyframe_map_.end()) { |
| 454 next_buffer_index_ = buffers_.size(); | 559 waiting_for_keyframe_ = true; |
| 455 return kNoTimestamp(); | 560 next_buffer_index_ = -1; |
| 561 next_keyframe_timestamp_ = timestamp; |
| 562 return; |
| 456 } | 563 } |
| 457 | 564 |
| 458 next_buffer_index_ = result->second; | 565 next_buffer_index_ = result->second; |
| 459 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 566 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
| 460 return result->first; | 567 } |
| 568 |
| 569 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { |
| 570 // Find the first keyframe after |timestamp|. |
| 571 KeyframeMap::iterator new_beginning_keyframe = |
| 572 keyframe_map_.lower_bound(timestamp); |
| 573 |
| 574 // If there is no keyframe after |timestamp|, we can't split the range. |
| 575 if (new_beginning_keyframe == keyframe_map_.end()) |
| 576 return NULL; |
| 577 |
| 578 int keyframe_index = new_beginning_keyframe->second; |
| 579 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
| 580 |
| 581 BufferQueue removed_buffers; |
| 582 BufferQueue::iterator next_buffer; |
| 583 DeleteAfter( |
| 584 buffers_.begin() + keyframe_index, &removed_buffers, &next_buffer); |
| 585 |
| 586 SourceBufferRange* split_range = new SourceBufferRange(removed_buffers); |
| 587 if (next_buffer != removed_buffers.end()) { |
| 588 split_range->next_buffer_index_ = next_buffer - removed_buffers.begin(); |
| 589 } |
| 590 return split_range; |
| 591 } |
| 592 |
| 593 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers, |
| 594 BufferQueue::iterator* next_buffer) { |
| 595 DeleteAfter(buffers_.begin(), removed_buffers, next_buffer); |
| 596 } |
| 597 |
| 598 void SourceBufferRange::DeleteAfter( |
| 599 scoped_refptr<StreamParserBuffer> buffer, |
| 600 BufferQueue* removed_buffers, |
| 601 BufferQueue::iterator* next_buffer) { |
| 602 // Find the place in |buffers_| where we will begin deleting data. |
| 603 BufferQueue::iterator starting_point = |
| 604 std::lower_bound(buffers_.begin(), buffers_.end(), |
| 605 buffer, |
| 606 BufferComparator); |
| 607 DeleteAfter(starting_point, removed_buffers, next_buffer); |
| 608 } |
| 609 |
| 610 void SourceBufferRange::DeleteAfter( |
| 611 BufferQueue::iterator starting_point, |
| 612 BufferQueue* removed_buffers, |
| 613 BufferQueue::iterator* next_buffer) { |
| 614 // Return if we're not deleting anything. |
| 615 if (starting_point == buffers_.end()) |
| 616 return; |
| 617 |
| 618 // Find the first keyframe after |starting_point|. |
| 619 KeyframeMap::iterator starting_point_keyframe = |
| 620 keyframe_map_.lower_bound((*starting_point)->GetTimestamp()); |
| 621 |
| 622 // Save the buffers we're about to delete. |
| 623 if (removed_buffers) { |
| 624 BufferQueue saved(starting_point, buffers_.end()); |
| 625 removed_buffers->swap(saved); |
| 626 if (next_buffer) |
| 627 *next_buffer = removed_buffers->end(); |
| 628 } |
| 629 |
| 630 // Reset the next buffer index if we will be deleting the buffer that's next |
| 631 // in sequence. |
| 632 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); |
| 633 if (next_buffer_timestamp != kNoTimestamp() && |
| 634 next_buffer_timestamp >= (*starting_point)->GetTimestamp()) { |
| 635 if (removed_buffers && next_buffer) { |
| 636 int starting_offset = starting_point - buffers_.begin(); |
| 637 int next_buffer_offset = next_buffer_index_ - starting_offset; |
| 638 DCHECK_GE(next_buffer_offset, 0); |
| 639 *next_buffer = removed_buffers->begin() + next_buffer_offset; |
| 640 } |
| 641 next_buffer_index_ = -1; |
| 642 } |
| 643 |
| 644 // Remove keyframes from |starting_point| onward. |
| 645 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); |
| 646 |
| 647 // Remove everything from |starting_point| onward. |
| 648 buffers_.erase(starting_point, buffers_.end()); |
| 461 } | 649 } |
| 462 | 650 |
| 463 bool SourceBufferRange::GetNextBuffer( | 651 bool SourceBufferRange::GetNextBuffer( |
| 464 scoped_refptr<StreamParserBuffer>* out_buffer) { | 652 scoped_refptr<StreamParserBuffer>* out_buffer) { |
| 653 if (waiting_for_keyframe_ || |
| 654 next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
| 655 return false; |
| 656 } |
| 657 |
| 465 DCHECK_GE(next_buffer_index_, 0); | 658 DCHECK_GE(next_buffer_index_, 0); |
| 466 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) | |
| 467 return false; | |
| 468 | |
| 469 *out_buffer = buffers_.at(next_buffer_index_); | 659 *out_buffer = buffers_.at(next_buffer_index_); |
| 470 next_buffer_index_++; | 660 next_buffer_index_++; |
| 471 return true; | 661 return true; |
| 472 } | 662 } |
| 473 | 663 |
| 474 bool SourceBufferRange::HasNextBuffer() const { | 664 bool SourceBufferRange::HasNextBuffer() const { |
| 475 return next_buffer_index_ >= 0 && | 665 return next_buffer_index_ >= 0 && |
| 476 next_buffer_index_ < static_cast<int>(buffers_.size()); | 666 next_buffer_index_ < static_cast<int>(buffers_.size()); |
| 477 } | 667 } |
| 478 | 668 |
| 479 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 669 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
| 480 DCHECK_GE(next_buffer_index_, 0); | |
| 481 DCHECK(!buffers_.empty()); | 670 DCHECK(!buffers_.empty()); |
| 482 | 671 |
| 483 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) | 672 if (next_buffer_index_ >= static_cast<int>(buffers_.size()) || |
| 484 return buffers_.back()->GetEndTimestamp(); | 673 next_buffer_index_ < 0 || waiting_for_keyframe_) { |
| 674 return kNoTimestamp(); |
| 675 } |
| 485 | 676 |
| 486 return buffers_.at(next_buffer_index_)->GetTimestamp(); | 677 return buffers_.at(next_buffer_index_)->GetTimestamp(); |
| 487 } | 678 } |
| 488 | 679 |
| 489 SourceBufferStream::Timespan | 680 SourceBufferStream::Timespan |
| 490 SourceBufferRange::GetBufferedTime() const { | 681 SourceBufferRange::GetBufferedTime() const { |
| 491 return std::make_pair(BufferedStart(), BufferedEnd()); | 682 return std::make_pair(GetStartTimestamp(), GetEndTimestamp()); |
| 492 } | 683 } |
| 493 | 684 |
| 494 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, | 685 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, |
| 495 bool transfer_current_position) { | 686 bool transfer_current_position) { |
| 496 DCHECK(CanAppendToEnd(range)); | 687 DCHECK(CanAppendToEnd(range)); |
| 497 DCHECK(!buffers_.empty()); | 688 DCHECK(!buffers_.empty()); |
| 498 | 689 |
| 499 if (transfer_current_position) | 690 if (transfer_current_position) |
| 500 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); | 691 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); |
| 501 | 692 |
| 502 AppendToEnd(range.buffers_); | 693 AppendToEnd(range.buffers_); |
| 503 } | 694 } |
| 504 | 695 |
| 505 bool SourceBufferRange::CanAppendToEnd(const SourceBufferRange& range) const { | 696 bool SourceBufferRange::CanAppendToEnd(const SourceBufferRange& range) const { |
| 506 return CanAppendToEnd(range.buffers_); | 697 return CanAppendToEnd(range.buffers_); |
| 507 } | 698 } |
| 508 | 699 |
| 509 bool SourceBufferRange::CanAppendToEnd(const BufferQueue& buffers) const { | 700 bool SourceBufferRange::CanAppendToEnd(const BufferQueue& buffers) const { |
| 510 return buffers_.empty() || | 701 DCHECK(!buffers_.empty()); |
| 511 IsNextInSequence(buffers_.back(), buffers.front()->GetTimestamp()); | 702 return IsNextInSequence(buffers_.back(), buffers.front()->GetTimestamp()); |
| 512 } | 703 } |
| 513 | 704 |
| 514 int SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { | 705 int SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { |
| 515 if (buffers_.empty()) | 706 DCHECK(!buffers_.empty()); |
| 516 return 1; | |
| 517 | 707 |
| 518 if (IsNextInSequence(buffers_.back(), timestamp) || | 708 if (IsNextInSequence(buffers_.back(), timestamp) || |
| 519 (BufferedEnd() >= timestamp && BufferedStart() <= timestamp)) { | 709 (GetEndTimestamp() >= timestamp && GetStartTimestamp() <= timestamp)) { |
| 520 return 0; | 710 return 0; |
| 521 } | 711 } |
| 522 | 712 |
| 523 if (BufferedStart() > timestamp) | 713 if (GetStartTimestamp() > timestamp) |
| 524 return -1; | 714 return -1; |
| 525 | 715 |
| 526 // |timestamp| must be after this range. | 716 // |timestamp| must be after this range. |
| 527 return 1; | 717 return 1; |
| 528 } | 718 } |
| 529 | 719 |
| 530 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { | 720 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { |
| 531 return !keyframe_map_.empty() && BufferedStart() <= timestamp && | 721 return !keyframe_map_.empty() && GetStartTimestamp() <= timestamp && |
| 532 BufferedEnd() > timestamp; | 722 GetEndTimestamp() > timestamp; |
| 533 } | 723 } |
| 534 | 724 |
| 535 bool SourceBufferRange::CompletelyOverlaps( | 725 bool SourceBufferRange::CompletelyOverlaps( |
| 536 const SourceBufferRange& range) const { | 726 const SourceBufferRange& range) const { |
| 537 return BufferedStart() <= range.BufferedStart() && | 727 return GetStartTimestamp() <= range.GetStartTimestamp() && |
| 538 BufferedEnd() >= range.BufferedEnd(); | 728 GetEndTimestamp() >= range.GetEndTimestamp(); |
| 539 } | 729 } |
| 540 | 730 |
| 541 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { | 731 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { |
| 542 return range.BufferedStart() < BufferedEnd() && | 732 return range.GetStartTimestamp() < GetEndTimestamp() && |
| 543 BufferedEnd() < range.BufferedEnd(); | 733 GetEndTimestamp() < range.GetEndTimestamp(); |
| 544 } | 734 } |
| 545 | 735 |
| 546 bool SourceBufferRange::IsStartOverlappedBy(const BufferQueue& buffers) const { | 736 base::TimeDelta SourceBufferRange::GetStartTimestamp() const { |
| 547 base::TimeDelta start_timestamp = buffers.front()->GetTimestamp(); | 737 DCHECK(!buffers_.empty()); |
| 548 return BufferedStart() < start_timestamp && start_timestamp < BufferedEnd(); | |
| 549 } | |
| 550 | |
| 551 bool SourceBufferRange::IsEndOverlappedBy(const BufferQueue& buffers) const { | |
| 552 base::TimeDelta end_timestamp = buffers.back()->GetEndTimestamp(); | |
| 553 return BufferedStart() < end_timestamp && end_timestamp < BufferedEnd(); | |
| 554 } | |
| 555 | |
| 556 bool SourceBufferRange::IsCompletelyOverlappedBy( | |
| 557 const BufferQueue& buffers) const { | |
| 558 base::TimeDelta start_timestamp = buffers.front()->GetTimestamp(); | |
| 559 base::TimeDelta end_timestamp = buffers.back()->GetEndTimestamp(); | |
| 560 return start_timestamp <= BufferedStart() && BufferedEnd() <= end_timestamp; | |
| 561 } | |
| 562 | |
| 563 base::TimeDelta SourceBufferRange::BufferedStart() const { | |
| 564 if (buffers_.empty()) | |
| 565 return kNoTimestamp(); | |
| 566 | |
| 567 return buffers_.front()->GetTimestamp(); | 738 return buffers_.front()->GetTimestamp(); |
| 568 } | 739 } |
| 569 | 740 |
| 570 base::TimeDelta SourceBufferRange::BufferedEnd() const { | 741 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { |
| 571 if (buffers_.empty()) | 742 DCHECK(!buffers_.empty()); |
| 572 return kNoTimestamp(); | |
| 573 | |
| 574 return buffers_.back()->GetEndTimestamp(); | 743 return buffers_.back()->GetEndTimestamp(); |
| 575 } | 744 } |
| 576 | 745 |
| 577 } // namespace media | 746 } // namespace media |
| OLD | NEW |