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/bind.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 | 12 |
12 namespace media { | 13 namespace media { |
13 | 14 |
14 // Helper class representing a range of buffered data. All buffers in a | 15 // Helper class representing a range of buffered data. All buffers in a |
15 // SourceBufferRange are ordered sequentially in presentation order with no | 16 // SourceBufferRange are ordered sequentially in presentation order with no |
16 // gaps. | 17 // gaps. |
17 class SourceBufferRange { | 18 class SourceBufferRange { |
18 public: | 19 public: |
19 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 20 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
20 | 21 |
| 22 // Returns the maximum distance in time between any buffer seen in this |
| 23 // stream. Used to estimate the duration of a buffer if its duration is not |
| 24 // known. |
| 25 typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB; |
| 26 |
21 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be | 27 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be |
22 // empty and the front of |new_buffers| must be a keyframe. | 28 // empty and the front of |new_buffers| must be a keyframe. |
23 // |media_segment_start_time| refers to the starting timestamp for the media | 29 // |media_segment_start_time| refers to the starting timestamp for the media |
24 // segment to which these buffers belong. | 30 // segment to which these buffers belong. |
25 SourceBufferRange(const BufferQueue& new_buffers, | 31 SourceBufferRange(const BufferQueue& new_buffers, |
26 base::TimeDelta media_segment_start_time); | 32 base::TimeDelta media_segment_start_time, |
| 33 const InterbufferDistanceCB& interbuffer_distance_cb); |
27 | 34 |
28 // Appends |buffers| to the end of the range and updates |keyframe_map_| as | 35 // Appends |buffers| to the end of the range and updates |keyframe_map_| as |
29 // it encounters new keyframes. Assumes |buffers| belongs at the end of the | 36 // it encounters new keyframes. Assumes |buffers| belongs at the end of the |
30 // range. | 37 // range. |
31 void AppendToEnd(const BufferQueue& buffers); | 38 void AppendToEnd(const BufferQueue& buffers); |
32 bool CanAppendToEnd(const BufferQueue& buffers) const; | 39 bool CanAppendToEnd(const BufferQueue& buffers) const; |
33 | 40 |
34 // Appends the buffers from |range| into this range. | 41 // Appends the buffers from |range| into this range. |
35 // The first buffer in |range| must come directly after the last buffer | 42 // The first buffer in |range| must come directly after the last buffer |
36 // in this range. | 43 // in this range. |
37 // If |transfer_current_position| is true, |range|'s |next_buffer_index_| | 44 // If |transfer_current_position| is true, |range|'s |next_buffer_index_| |
38 // is transfered to this SourceBufferRange. | 45 // is transfered to this SourceBufferRange. |
39 void AppendToEnd(const SourceBufferRange& range, | 46 void AppendToEnd(const SourceBufferRange& range, |
40 bool transfer_current_position); | 47 bool transfer_current_position); |
41 bool CanAppendToEnd(const SourceBufferRange& range) const; | 48 bool CanAppendToEnd(const SourceBufferRange& range) const; |
42 | 49 |
43 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. | 50 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. |
44 // Assumes |timestamp| is valid and in this range. | 51 // Assumes |timestamp| is valid and in this range. |
45 void Seek(base::TimeDelta timestamp); | 52 void Seek(base::TimeDelta timestamp); |
46 | 53 |
47 // Updates |next_buffer_index_| to point to next keyframe after or equal to | 54 // Updates |next_buffer_index_| to point to next keyframe after or equal to |
48 // |timestamp|. | 55 // |timestamp|. |
49 void SeekAfter(base::TimeDelta timestamp); | 56 void SeekAheadTo(base::TimeDelta timestamp); |
| 57 |
| 58 // Updates |next_buffer_index_| to point to next keyframe strictly after |
| 59 // |timestamp|. |
| 60 void SeekAheadPast(base::TimeDelta timestamp); |
50 | 61 |
51 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and | 62 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and |
52 // returns a new SourceBufferRange with the buffers from that keyframe onward. | 63 // returns a new SourceBufferRange with the buffers from that keyframe onward. |
53 // The buffers in the new SourceBufferRange are moved out of this range. If | 64 // The buffers in the new SourceBufferRange are moved out of this range. If |
54 // there is no keyframe after |timestamp|, SplitRange() returns null and this | 65 // there is no keyframe after |timestamp|, SplitRange() returns null and this |
55 // range is unmodified. | 66 // range is unmodified. |
56 SourceBufferRange* SplitRange(base::TimeDelta timestamp); | 67 SourceBufferRange* SplitRange(base::TimeDelta timestamp); |
57 | 68 |
58 // Deletes the buffers from this range whose timestamps are greater than or | 69 // Deletes the buffers from this range whose timestamps are greater than or |
59 // equal to |buffer|'s timestamp. | 70 // equal to |buffer|'s timestamp. |
60 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was | 71 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was |
61 // deleted, and deletes the |keyframe_map_| entries for the buffers that | 72 // deleted, and deletes the |keyframe_map_| entries for the buffers that |
62 // were removed. | 73 // were removed. |
63 // |deleted_buffers| contains the buffers that were deleted from this range, | 74 // |deleted_buffers| contains the buffers that were deleted from this range, |
64 // starting at the buffer that had been at |next_buffer_index_|. | 75 // starting at the buffer that had been at |next_buffer_index_|. |
65 // |deleted_buffers| is empty if the buffer at |next_buffer_index_| was not | 76 // Returns true if the |next_buffer_index_| is reset. Note that this method |
66 // deleted. | 77 // may return true even if it does not add any buffers to |deleted_buffers|. |
67 void DeleteAfter(scoped_refptr<StreamParserBuffer> buffer, | 78 // This indicates that the range had not buffered |next_buffer_index_|, but |
68 BufferQueue* deleted_buffers); | 79 // a buffer at that position would have been deleted. |
| 80 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer, |
| 81 BufferQueue* deleted_buffers); |
69 // Deletes all buffers in range. | 82 // Deletes all buffers in range. |
70 void DeleteAll(BufferQueue* deleted_buffers); | 83 bool DeleteAll(BufferQueue* deleted_buffers); |
71 | 84 |
72 // Updates |out_buffer| with the next buffer in presentation order. Seek() | 85 // Updates |out_buffer| with the next buffer in presentation order. Seek() |
73 // must be called before calls to GetNextBuffer(), and buffers are returned | 86 // must be called before calls to GetNextBuffer(), and buffers are returned |
74 // in order from the last call to Seek(). Returns true if |out_buffer| is | 87 // in order from the last call to Seek(). Returns true if |out_buffer| is |
75 // filled with a valid buffer, false if there is not enough data to fulfill | 88 // filled with a valid buffer, false if there is not enough data to fulfill |
76 // the request. | 89 // the request. |
77 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); | 90 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); |
78 bool HasNextBuffer() const; | 91 bool HasNextBuffer() const; |
79 | 92 |
80 // Returns true if the range knows the position of the next buffer it should | 93 // Returns true if the range knows the position of the next buffer it should |
81 // return, i.e. it has been Seek()ed. This does not necessarily mean that it | 94 // return, i.e. it has been Seek()ed. This does not necessarily mean that it |
82 // has the next buffer yet. | 95 // has the next buffer yet. |
83 bool HasNextBufferPosition() const; | 96 bool HasNextBufferPosition() const; |
84 | 97 |
85 // Returns the timestamp of the next buffer that will be returned from | 98 // Returns the timestamp of the next buffer that will be returned from |
86 // GetNextBuffer(). This may be an approximation if the range does not have | 99 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. |
87 // next buffer buffered. | |
88 base::TimeDelta GetNextTimestamp() const; | 100 base::TimeDelta GetNextTimestamp() const; |
89 | 101 |
90 // Returns the start timestamp of the range. | 102 // Returns the start timestamp of the range. |
91 base::TimeDelta GetStartTimestamp() const; | 103 base::TimeDelta GetStartTimestamp() const; |
92 | 104 |
93 // Returns the end timestamp of the buffered data. (Note that this is equal to | 105 // Returns the timestamp of the last buffer in the range. |
94 // the last buffer's timestamp + its duration.) | |
95 base::TimeDelta GetEndTimestamp() const; | 106 base::TimeDelta GetEndTimestamp() const; |
96 | 107 |
| 108 // Returns the timestamp for the end of the buffered region in this range. |
| 109 // This is an approximation if the duration for the last buffer in the range |
| 110 // is unset. |
| 111 base::TimeDelta GetBufferedEndTimestamp() const; |
| 112 |
97 // Returns whether a buffer with a starting timestamp of |timestamp| would | 113 // Returns whether a buffer with a starting timestamp of |timestamp| would |
98 // belong in this range. This includes a buffer that would be appended to | 114 // belong in this range. This includes a buffer that would be appended to |
99 // the end of the range. | 115 // the end of the range. |
100 bool BelongsToRange(base::TimeDelta timestamp) const; | 116 bool BelongsToRange(base::TimeDelta timestamp) const; |
101 | 117 |
102 // Returns true if the range has enough data to seek to the specified | 118 // Returns true if the range has enough data to seek to the specified |
103 // |timestamp|, false otherwise. | 119 // |timestamp|, false otherwise. |
104 bool CanSeekTo(base::TimeDelta timestamp) const; | 120 bool CanSeekTo(base::TimeDelta timestamp) const; |
105 | 121 |
106 // Returns true if this range's buffered timespan completely overlaps the | 122 // Returns true if this range's buffered timespan completely overlaps the |
107 // buffered timespan of |range|. | 123 // buffered timespan of |range|. |
108 bool CompletelyOverlaps(const SourceBufferRange& range) const; | 124 bool CompletelyOverlaps(const SourceBufferRange& range) const; |
109 | 125 |
110 // Returns true if the end of this range contains buffers that overlaps with | 126 // Returns true if the end of this range contains buffers that overlaps with |
111 // the beginning of |range|. | 127 // the beginning of |range|. |
112 bool EndOverlaps(const SourceBufferRange& range) const; | 128 bool EndOverlaps(const SourceBufferRange& range) const; |
113 | 129 |
| 130 // Returns true if |timestamp| is the timestamp of the next buffer in |
| 131 // sequence after |buffer|, false otherwise. |
| 132 bool IsNextInSequence( |
| 133 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 134 base::TimeDelta timestamp) const; |
| 135 |
114 private: | 136 private: |
115 // Helper method to delete buffers in |buffers_| starting from | 137 typedef std::map<base::TimeDelta, size_t> KeyframeMap; |
| 138 |
| 139 // Seeks the range to the next keyframe after |timestamp|. If |
| 140 // |skip_given_timestamp| is true, the seek will go to a keyframe with a |
| 141 // timestamp strictly greater than |timestamp|. |
| 142 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); |
| 143 |
| 144 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after |
| 145 // |timestamp|. If |skip_given_timestamp| is true, this returns the first |
| 146 // keyframe with a timestamp strictly greater than |timestamp|. |
| 147 KeyframeMap::iterator GetFirstKeyframeAt( |
| 148 base::TimeDelta timestamp, bool skip_given_timestamp); |
| 149 |
| 150 // Helper method to delete buffers in |buffers_| starting at |
116 // |starting_point|, an iterator in |buffers_|. | 151 // |starting_point|, an iterator in |buffers_|. |
117 void DeleteAfter(const BufferQueue::iterator& starting_point, | 152 bool TruncateAt(const BufferQueue::iterator& starting_point, |
118 BufferQueue* deleted_buffers); | 153 BufferQueue* deleted_buffers); |
| 154 |
| 155 // Returns the distance in time estimating how far from the beginning or end |
| 156 // of this range a buffer can be to considered in the range. |
| 157 base::TimeDelta GetFudgeRoom() const; |
| 158 |
| 159 // Returns the approximate duration of a buffer in this range. |
| 160 base::TimeDelta GetApproximateDuration() const; |
119 | 161 |
120 // An ordered list of buffers in this range. | 162 // An ordered list of buffers in this range. |
121 BufferQueue buffers_; | 163 BufferQueue buffers_; |
122 | 164 |
123 // Maps keyframe timestamps to its index position in |buffers_|. | 165 // Maps keyframe timestamps to its index position in |buffers_|. |
124 typedef std::map<base::TimeDelta, size_t> KeyframeMap; | |
125 KeyframeMap keyframe_map_; | 166 KeyframeMap keyframe_map_; |
126 | 167 |
127 // Index into |buffers_| for the next buffer to be returned by | 168 // Index into |buffers_| for the next buffer to be returned by |
128 // GetNextBuffer(), set to -1 before Seek(). | 169 // GetNextBuffer(), set to -1 before Seek(). |
129 int next_buffer_index_; | 170 int next_buffer_index_; |
130 | 171 |
131 // True if the range needs to wait for the next keyframe to be appended before | 172 // True if the range needs to wait for the next keyframe to be appended before |
132 // returning buffers from GetNextBuffer(). | 173 // returning buffers from GetNextBuffer(). |
133 bool waiting_for_keyframe_; | 174 bool waiting_for_keyframe_; |
134 | 175 |
135 // If |waiting_for_keyframe_| is true, this range will wait for the next | 176 // If |waiting_for_keyframe_| is true, this range will wait for the next |
136 // keyframe with timestamp >= |next_keyframe_timestamp_|. | 177 // keyframe with timestamp >= |next_keyframe_timestamp_|. |
137 base::TimeDelta next_keyframe_timestamp_; | 178 base::TimeDelta next_keyframe_timestamp_; |
138 | 179 |
139 // If the first buffer in this range is the beginning of a media segment, | 180 // If the first buffer in this range is the beginning of a media segment, |
140 // |media_segment_start_time_| is the time when the media segment begins. | 181 // |media_segment_start_time_| is the time when the media segment begins. |
141 // |media_segment_start_time_| may be <= the timestamp of the first buffer in | 182 // |media_segment_start_time_| may be <= the timestamp of the first buffer in |
142 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range | 183 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range |
143 // does not start at the beginning of a media segment, which can only happen | 184 // does not start at the beginning of a media segment, which can only happen |
144 // garbage collection or after an end overlap that results in a split range | 185 // garbage collection or after an end overlap that results in a split range |
145 // (we don't have a way of knowing the media segment timestamp for the new | 186 // (we don't have a way of knowing the media segment timestamp for the new |
146 // range). | 187 // range). |
147 base::TimeDelta media_segment_start_time_; | 188 base::TimeDelta media_segment_start_time_; |
148 | 189 |
| 190 // Called to get the largest interbuffer distance seen so far in the stream. |
| 191 InterbufferDistanceCB interbuffer_distance_cb_; |
| 192 |
149 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); | 193 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); |
150 }; | 194 }; |
151 | 195 |
152 } // namespace media | 196 } // namespace media |
153 | 197 |
154 // Helper method that returns true if |ranges| is sorted in increasing order, | 198 // Helper method that returns true if |ranges| is sorted in increasing order, |
155 // false otherwise. | 199 // false otherwise. |
156 static bool IsRangeListSorted( | 200 static bool IsRangeListSorted( |
157 const std::list<media::SourceBufferRange*>& ranges) { | 201 const std::list<media::SourceBufferRange*>& ranges) { |
158 base::TimeDelta prev = media::kNoTimestamp(); | 202 base::TimeDelta prev = media::kNoTimestamp(); |
159 for (std::list<media::SourceBufferRange*>::const_iterator itr = | 203 for (std::list<media::SourceBufferRange*>::const_iterator itr = |
160 ranges.begin(); itr != ranges.end(); itr++) { | 204 ranges.begin(); itr != ranges.end(); ++itr) { |
161 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp()) | 205 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp()) |
162 return false; | 206 return false; |
163 prev = (*itr)->GetEndTimestamp(); | 207 prev = (*itr)->GetEndTimestamp(); |
164 } | 208 } |
165 return true; | 209 return true; |
166 } | 210 } |
167 | 211 |
168 // Comparison function for two Buffers based on timestamp. | 212 // Comparison function for two Buffers based on timestamp. |
169 static bool BufferComparator( | 213 static bool BufferComparator( |
170 const scoped_refptr<media::StreamParserBuffer>& first, | 214 const scoped_refptr<media::StreamParserBuffer>& first, |
171 const scoped_refptr<media::StreamParserBuffer>& second) { | 215 const scoped_refptr<media::StreamParserBuffer>& second) { |
172 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); | 216 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); |
173 } | 217 } |
174 | 218 |
175 // Returns the upper bound for the starting timestamp for the next buffer | 219 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
176 // in sequence after |buffer|. Assumes |buffer|'s timestamp and | 220 // is set and there's not enough information to get a better estimate. |
177 // duration are valid. | 221 static int kDefaultBufferDurationInMs = 125; |
178 static base::TimeDelta MaxNextTimestamp( | |
179 const scoped_refptr<media::StreamParserBuffer>& buffer) { | |
180 // Because we do not know exactly when is the next timestamp, any buffer | |
181 // that starts within 1/3 of the duration past the end of this buffer | |
182 // is considered the next buffer in the sequence. | |
183 return buffer->GetEndTimestamp() + buffer->GetDuration() / 3; | |
184 } | |
185 | |
186 // Returns true if |timestamp| is the timestamp of the next buffer in | |
187 // sequence after |buffer|, false otherwise. | |
188 static bool IsNextInSequence( | |
189 const scoped_refptr<media::StreamParserBuffer>& buffer, | |
190 base::TimeDelta timestamp) { | |
191 return timestamp >= buffer->GetEndTimestamp() && | |
192 timestamp <= MaxNextTimestamp(buffer); | |
193 } | |
194 | 222 |
195 namespace media { | 223 namespace media { |
196 | 224 |
197 SourceBufferStream::SourceBufferStream() | |
198 : seek_pending_(false), | |
199 seek_buffer_timestamp_(base::TimeDelta()), | |
200 selected_range_(NULL), | |
201 end_of_stream_(false) { | |
202 } | |
203 | |
204 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) | 225 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) |
205 : seek_pending_(false), | 226 : seek_pending_(false), |
206 seek_buffer_timestamp_(base::TimeDelta()), | 227 seek_buffer_timestamp_(kNoTimestamp()), |
207 selected_range_(NULL), | 228 selected_range_(NULL), |
208 end_of_stream_(false) { | 229 end_of_stream_(false), |
| 230 media_segment_start_time_(kNoTimestamp()), |
| 231 range_for_next_append_(ranges_.end()), |
| 232 new_media_segment_(false), |
| 233 last_buffer_timestamp_(kNoTimestamp()), |
| 234 max_interbuffer_distance_(kNoTimestamp()) { |
209 audio_config_.CopyFrom(audio_config); | 235 audio_config_.CopyFrom(audio_config); |
210 } | 236 } |
211 | 237 |
212 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) | 238 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) |
213 : seek_pending_(false), | 239 : seek_pending_(false), |
214 seek_buffer_timestamp_(base::TimeDelta()), | 240 seek_buffer_timestamp_(kNoTimestamp()), |
215 selected_range_(NULL), | 241 selected_range_(NULL), |
216 end_of_stream_(false) { | 242 end_of_stream_(false), |
| 243 media_segment_start_time_(kNoTimestamp()), |
| 244 range_for_next_append_(ranges_.end()), |
| 245 new_media_segment_(false), |
| 246 last_buffer_timestamp_(kNoTimestamp()), |
| 247 max_interbuffer_distance_(kNoTimestamp()) { |
217 video_config_.CopyFrom(video_config); | 248 video_config_.CopyFrom(video_config); |
218 } | 249 } |
219 | 250 |
220 SourceBufferStream::~SourceBufferStream() { | 251 SourceBufferStream::~SourceBufferStream() { |
221 while (!ranges_.empty()) { | 252 while (!ranges_.empty()) { |
222 delete ranges_.front(); | 253 delete ranges_.front(); |
223 ranges_.pop_front(); | 254 ranges_.pop_front(); |
224 } | 255 } |
225 } | 256 } |
226 | 257 |
| 258 void SourceBufferStream::OnNewMediaSegment( |
| 259 base::TimeDelta media_segment_start_time) { |
| 260 media_segment_start_time_ = media_segment_start_time; |
| 261 |
| 262 // Find the range that will house the buffers appended through the next |
| 263 // Append() call. |
| 264 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
| 265 new_media_segment_ = true; |
| 266 last_buffer_timestamp_ = kNoTimestamp(); |
| 267 } |
| 268 |
227 bool SourceBufferStream::Append( | 269 bool SourceBufferStream::Append( |
228 const SourceBufferStream::BufferQueue& buffers, | 270 const SourceBufferStream::BufferQueue& buffers) { |
229 base::TimeDelta media_segment_start_time) { | |
230 DCHECK(!buffers.empty()); | 271 DCHECK(!buffers.empty()); |
231 DCHECK(media_segment_start_time != kNoTimestamp()); | 272 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
232 | 273 |
233 // Find a range into which we'll append |buffers|. | 274 // New media segments must begin with a keyframe. |
234 RangeList::iterator range_for_new_buffers = FindExistingRangeFor(buffers); | 275 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { |
| 276 DVLOG(1) << "Media segment did not begin with keyframe."; |
| 277 return false; |
| 278 } |
235 | 279 |
| 280 // Buffers within a media segment should be monotonically increasing. |
| 281 if (!IsMonotonicallyIncreasing(buffers)) { |
| 282 DVLOG(1) << "Buffers were not monotonically increasing."; |
| 283 return false; |
| 284 } |
| 285 |
| 286 UpdateMaxInterbufferDistance(buffers); |
| 287 |
| 288 // Save a snapshot of the |selected_range_| state before range modifications |
| 289 // are made. |
| 290 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
| 291 base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp(); |
| 292 |
| 293 bool deleted_next_buffer = false; |
| 294 BufferQueue deleted_buffers; |
| 295 |
| 296 RangeList::iterator range_for_new_buffers = range_for_next_append_; |
236 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 297 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
237 // create a new range with |buffers|. | 298 // create a new range with |buffers|. |
238 if (range_for_new_buffers != ranges_.end()) { | 299 if (range_for_new_buffers != ranges_.end()) { |
239 InsertIntoExistingRange(range_for_new_buffers, buffers); | 300 InsertIntoExistingRange(range_for_new_buffers, buffers, |
| 301 &deleted_next_buffer, &deleted_buffers); |
240 } else { | 302 } else { |
241 // Ranges must begin with a keyframe. | 303 DCHECK(new_media_segment_); |
242 if (!buffers.front()->IsKeyframe()) | |
243 return false; | |
244 range_for_new_buffers = | 304 range_for_new_buffers = |
245 AddToRanges(new SourceBufferRange(buffers, media_segment_start_time)); | 305 AddToRanges(new SourceBufferRange( |
| 306 buffers, media_segment_start_time_, |
| 307 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
| 308 base::Unretained(this)))); |
246 } | 309 } |
247 | 310 |
| 311 range_for_next_append_ = range_for_new_buffers; |
| 312 new_media_segment_ = false; |
| 313 last_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
| 314 |
248 // Resolve overlaps. | 315 // Resolve overlaps. |
249 ResolveCompleteOverlaps(range_for_new_buffers); | 316 ResolveCompleteOverlaps( |
250 ResolveEndOverlap(range_for_new_buffers); | 317 range_for_new_buffers, &deleted_next_buffer, &deleted_buffers); |
| 318 ResolveEndOverlap( |
| 319 range_for_new_buffers, &deleted_next_buffer, &deleted_buffers); |
251 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); | 320 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); |
252 | 321 |
253 // If these were the first buffers appended to the stream, seek to the | 322 // If these were the first buffers appended to the stream, seek to the |
254 // beginning of the range. | 323 // beginning of the range. |
255 // TODO(vrk): This should be done by ChunkDemuxer. (crbug.com/132815) | 324 // TODO(vrk): This should be done by ChunkDemuxer. (crbug.com/132815) |
256 if (!seek_pending_ && !selected_range_) { | 325 if (!seek_pending_ && !selected_range_) { |
257 selected_range_ = *range_for_new_buffers; | 326 selected_range_ = *range_for_new_buffers; |
258 selected_range_->Seek(buffers.front()->GetDecodeTimestamp()); | 327 selected_range_->Seek(buffers.front()->GetDecodeTimestamp()); |
259 } | 328 } |
260 | 329 |
261 // Finally, try to complete pending seek if one exists. | 330 // Seek to try to fulfill a previous call to Seek(). |
262 if (seek_pending_) | 331 if (seek_pending_) { |
| 332 DCHECK(!selected_range_); |
| 333 DCHECK(!deleted_next_buffer); |
263 Seek(seek_buffer_timestamp_); | 334 Seek(seek_buffer_timestamp_); |
| 335 } |
| 336 |
| 337 // Seek because the Append() has deleted the buffer that would have been |
| 338 // returned in the next call to GetNextBuffer(). |
| 339 if (deleted_next_buffer) { |
| 340 DCHECK(!seek_pending_); |
| 341 selected_range_ = *range_for_new_buffers; |
| 342 if (!deleted_buffers.empty()) { |
| 343 // Seek the range to the keyframe at or after |next_buffer_timestamp|. |
| 344 selected_range_->SeekAheadTo(next_buffer_timestamp); |
| 345 UpdateTrackBuffer(deleted_buffers); |
| 346 } else { |
| 347 // If we've deleted the next buffer but |deleted_buffers| is empty, |
| 348 // that means we need to seek past the timestamp of the last buffer in |
| 349 // the range (i.e. the keyframe timestamp needs to be strictly greater |
| 350 // than |end_buffer_timestamp|). |
| 351 selected_range_->SeekAheadPast(end_buffer_timestamp); |
| 352 } |
| 353 } |
264 | 354 |
265 DCHECK(IsRangeListSorted(ranges_)); | 355 DCHECK(IsRangeListSorted(ranges_)); |
266 return true; | 356 return true; |
267 } | 357 } |
268 | 358 |
| 359 bool SourceBufferStream::IsMonotonicallyIncreasing( |
| 360 const BufferQueue& buffers) { |
| 361 DCHECK(!buffers.empty()); |
| 362 base::TimeDelta prev_timestamp = last_buffer_timestamp_; |
| 363 for (BufferQueue::const_iterator itr = buffers.begin(); |
| 364 itr != buffers.end(); ++itr) { |
| 365 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); |
| 366 DCHECK(current_timestamp != kNoTimestamp()); |
| 367 |
| 368 if (prev_timestamp != kNoTimestamp() && current_timestamp < prev_timestamp) |
| 369 return false; |
| 370 |
| 371 prev_timestamp = current_timestamp; |
| 372 } |
| 373 return true; |
| 374 } |
| 375 |
| 376 void SourceBufferStream::UpdateMaxInterbufferDistance( |
| 377 const BufferQueue& buffers) { |
| 378 DCHECK(!buffers.empty()); |
| 379 base::TimeDelta prev_timestamp = last_buffer_timestamp_; |
| 380 for (BufferQueue::const_iterator itr = buffers.begin(); |
| 381 itr != buffers.end(); ++itr) { |
| 382 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); |
| 383 DCHECK(current_timestamp != kNoTimestamp()); |
| 384 |
| 385 if (prev_timestamp != kNoTimestamp()) { |
| 386 base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp; |
| 387 if (max_interbuffer_distance_ == kNoTimestamp()) { |
| 388 max_interbuffer_distance_ = interbuffer_distance; |
| 389 } else { |
| 390 max_interbuffer_distance_ = |
| 391 std::max(max_interbuffer_distance_, interbuffer_distance); |
| 392 } |
| 393 } |
| 394 prev_timestamp = current_timestamp; |
| 395 } |
| 396 } |
| 397 |
269 void SourceBufferStream::InsertIntoExistingRange( | 398 void SourceBufferStream::InsertIntoExistingRange( |
270 const RangeList::iterator& range_for_new_buffers_itr, | 399 const RangeList::iterator& range_for_new_buffers_itr, |
271 const BufferQueue& new_buffers) { | 400 const BufferQueue& new_buffers, |
| 401 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 402 DCHECK(deleted_next_buffer); |
| 403 DCHECK(deleted_buffers); |
| 404 |
272 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 405 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
273 | 406 |
274 // If this is a simple case where we can just append to the end of the range, | 407 // If this is a simple case where we can just append to the end of the range, |
275 // do so and return. | 408 // do so and return. |
276 if (range_for_new_buffers->CanAppendToEnd(new_buffers)) { | 409 if (range_for_new_buffers->CanAppendToEnd(new_buffers)) { |
277 range_for_new_buffers->AppendToEnd(new_buffers); | 410 range_for_new_buffers->AppendToEnd(new_buffers); |
278 return; | 411 return; |
279 } | 412 } |
280 | 413 |
281 // Otherwise, this is either a start overlap or an middle overlap. | 414 // Otherwise, this is either a start overlap or an middle overlap. |
282 | 415 |
283 // In case this is a middle overlap, save the buffers that come after the end | 416 // In case this is a middle overlap, save the buffers that come after the end |
284 // of |new_buffers|, and add them into a new range. | 417 // of |new_buffers|, and add them into a new range. |
285 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | |
286 bool had_next_buffer = range_for_new_buffers->HasNextBuffer(); | |
287 SourceBufferRange* new_next_range = | 418 SourceBufferRange* new_next_range = |
288 range_for_new_buffers->SplitRange(new_buffers.back()->GetEndTimestamp()); | 419 range_for_new_buffers->SplitRange( |
| 420 new_buffers.back()->GetDecodeTimestamp()); |
289 | 421 |
290 if (new_next_range) | 422 if (new_next_range) |
291 AddToRanges(new_next_range); | 423 AddToRanges(new_next_range); |
292 | 424 |
293 // Delete the buffers that are overlapped by |new_buffers|, then append | 425 // Delete the buffers that are overlapped by |new_buffers|, then append |
294 // |new_buffers| to the end of the range. | 426 // |new_buffers| to the end of the range. |
295 BufferQueue deleted_buffers; | 427 DCHECK(!*deleted_next_buffer); |
296 range_for_new_buffers->DeleteAfter(new_buffers.front(), &deleted_buffers); | 428 *deleted_next_buffer = |
| 429 range_for_new_buffers->TruncateAt(new_buffers.front(), deleted_buffers); |
297 range_for_new_buffers->AppendToEnd(new_buffers); | 430 range_for_new_buffers->AppendToEnd(new_buffers); |
298 | 431 |
299 // If |new_buffers| doesn't overlap the selected range, no need to do anything | |
300 // more. | |
301 if (selected_range_ != range_for_new_buffers || !had_next_buffer || | |
302 next_buffer_timestamp < new_buffers.front()->GetDecodeTimestamp()) { | |
303 return; | |
304 } | |
305 | |
306 // If this was a middle overlap resulting in a new range, and the next buffer | 432 // If this was a middle overlap resulting in a new range, and the next buffer |
307 // position has been transferred to the newly created range, update the | 433 // position has been transferred to the newly created range, update the |
308 // |selected_range_| accordingly. | 434 // |selected_range_| accordingly. |
309 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 435 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
310 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); | 436 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); |
| 437 DCHECK(!*deleted_next_buffer); |
311 selected_range_ = new_next_range; | 438 selected_range_ = new_next_range; |
312 return; | |
313 } | 439 } |
314 | |
315 selected_range_ = range_for_new_buffers; | |
316 selected_range_->SeekAfter(next_buffer_timestamp); | |
317 UpdateTrackBuffer(deleted_buffers); | |
318 } | 440 } |
319 | 441 |
320 void SourceBufferStream::ResolveCompleteOverlaps( | 442 void SourceBufferStream::ResolveCompleteOverlaps( |
321 const RangeList::iterator& range_with_new_buffers_itr) { | 443 const RangeList::iterator& range_with_new_buffers_itr, |
| 444 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 445 DCHECK(deleted_next_buffer); |
| 446 DCHECK(deleted_buffers); |
| 447 |
322 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 448 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
323 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 449 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
324 next_range_itr++; | 450 next_range_itr++; |
325 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | |
326 | 451 |
327 while (next_range_itr != ranges_.end() && | 452 while (next_range_itr != ranges_.end() && |
328 range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) { | 453 range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) { |
329 if (*next_range_itr == selected_range_) { | 454 if (*next_range_itr == selected_range_) { |
330 // Transfer the next buffer position from the old selected range to the | 455 selected_range_ = NULL; |
331 // range with the new buffers. | 456 DCHECK(!*deleted_next_buffer); |
332 selected_range_ = range_with_new_buffers; | 457 *deleted_next_buffer = (*next_range_itr)->DeleteAll(deleted_buffers); |
333 selected_range_->SeekAfter(next_buffer_timestamp); | 458 DCHECK(*deleted_next_buffer); |
334 | |
335 // Delete everything from the old selected range and save the next | |
336 // buffers. | |
337 BufferQueue deleted_buffers; | |
338 (*next_range_itr)->DeleteAll(&deleted_buffers); | |
339 UpdateTrackBuffer(deleted_buffers); | |
340 } | 459 } |
341 delete *next_range_itr; | 460 delete *next_range_itr; |
342 next_range_itr = ranges_.erase(next_range_itr); | 461 next_range_itr = ranges_.erase(next_range_itr); |
343 } | 462 } |
344 } | 463 } |
345 | 464 |
346 void SourceBufferStream::ResolveEndOverlap( | 465 void SourceBufferStream::ResolveEndOverlap( |
347 const RangeList::iterator& range_with_new_buffers_itr) { | 466 const RangeList::iterator& range_with_new_buffers_itr, |
| 467 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 468 DCHECK(deleted_next_buffer); |
| 469 DCHECK(deleted_buffers); |
| 470 |
348 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 471 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
349 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 472 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
350 next_range_itr++; | 473 next_range_itr++; |
351 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | |
352 | 474 |
353 if (next_range_itr == ranges_.end() || | 475 if (next_range_itr == ranges_.end() || |
354 !range_with_new_buffers->EndOverlaps(**next_range_itr)) { | 476 !range_with_new_buffers->EndOverlaps(**next_range_itr)) { |
355 return; | 477 return; |
356 } | 478 } |
357 | 479 |
358 // Split the overlapped range after |range_with_new_buffers|'s last buffer | 480 // Split the overlapped range after |range_with_new_buffers|'s last buffer |
359 // overlaps. Now |overlapped_range| contains only the buffers that do not | 481 // overlaps. Now |overlapped_range| contains only the buffers that do not |
360 // belong in |ranges_| anymore, and |new_next_range| contains buffers that | 482 // belong in |ranges_| anymore, and |new_next_range| contains buffers that |
361 // go after |range_with_new_buffers| (without overlap). | 483 // go after |range_with_new_buffers| (without overlap). |
(...skipping 12 matching lines...) Expand all Loading... |
374 return; | 496 return; |
375 | 497 |
376 // If the |overlapped_range| transfers its next buffer position to | 498 // If the |overlapped_range| transfers its next buffer position to |
377 // |new_next_range|, make |new_next_range| the |selected_range_|. | 499 // |new_next_range|, make |new_next_range| the |selected_range_|. |
378 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 500 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
379 DCHECK(!overlapped_range->HasNextBufferPosition()); | 501 DCHECK(!overlapped_range->HasNextBufferPosition()); |
380 selected_range_ = new_next_range; | 502 selected_range_ = new_next_range; |
381 return; | 503 return; |
382 } | 504 } |
383 | 505 |
384 // Transfer the next buffer position from the old range to the range with | 506 // Save the buffers in |overlapped_range|. |
385 // the new buffers. | 507 DCHECK(!*deleted_next_buffer); |
386 selected_range_ = range_with_new_buffers; | 508 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); |
387 selected_range_->SeekAfter(next_buffer_timestamp); | 509 DCHECK(*deleted_next_buffer); |
388 | |
389 // Update track buffer with overlapped buffers. | |
390 BufferQueue deleted_buffers; | |
391 scoped_refptr<StreamParserBuffer> buffer; | |
392 while (overlapped_range->GetNextBuffer(&buffer)) { | |
393 deleted_buffers.push_back(buffer); | |
394 } | |
395 UpdateTrackBuffer(deleted_buffers); | |
396 } | 510 } |
397 | 511 |
398 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { | 512 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { |
399 if (!track_buffer_.empty() || deleted_buffers.empty()) | 513 DCHECK(!deleted_buffers.empty()); |
| 514 if (!track_buffer_.empty()) |
400 return; | 515 return; |
401 | 516 |
402 DCHECK(selected_range_); | 517 DCHECK(selected_range_); |
403 DCHECK(selected_range_->HasNextBufferPosition()); | 518 DCHECK(selected_range_->HasNextBufferPosition()); |
404 | 519 |
405 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); | 520 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); |
406 | 521 |
407 // If there is no gap between what was deleted and what was added, nothing | 522 // If there is no gap between what was deleted and what was added, nothing |
408 // should be added to the track buffer. | 523 // should be added to the track buffer. |
409 if (selected_range_->HasNextBuffer() && | 524 if (selected_range_->HasNextBuffer() && |
(...skipping 17 matching lines...) Expand all Loading... |
427 } | 542 } |
428 | 543 |
429 // Otherwise, the |selected_range_| is not ready to return data, so add all | 544 // Otherwise, the |selected_range_| is not ready to return data, so add all |
430 // the deleted buffers into the |track_buffer_|. | 545 // the deleted buffers into the |track_buffer_|. |
431 track_buffer_ = deleted_buffers; | 546 track_buffer_ = deleted_buffers; |
432 | 547 |
433 // See if the next range contains the keyframe after the end of the | 548 // See if the next range contains the keyframe after the end of the |
434 // |track_buffer_|, and if so, change |selected_range_|. | 549 // |track_buffer_|, and if so, change |selected_range_|. |
435 RangeList::iterator next_range_itr = ++(GetSelectedRangeItr()); | 550 RangeList::iterator next_range_itr = ++(GetSelectedRangeItr()); |
436 if (next_range_itr != ranges_.end()) { | 551 if (next_range_itr != ranges_.end()) { |
437 (*next_range_itr)->SeekAfter(track_buffer_.back()->GetEndTimestamp()); | 552 (*next_range_itr)->SeekAheadPast( |
| 553 track_buffer_.back()->GetDecodeTimestamp()); |
438 if ((*next_range_itr)->HasNextBuffer() && | 554 if ((*next_range_itr)->HasNextBuffer() && |
439 IsNextInSequence(track_buffer_.back(), | 555 selected_range_->IsNextInSequence( |
440 (*next_range_itr)->GetNextTimestamp())) { | 556 track_buffer_.back(), (*next_range_itr)->GetNextTimestamp())) { |
441 selected_range_ = *next_range_itr; | 557 selected_range_ = *next_range_itr; |
442 } | 558 } |
443 } | 559 } |
444 } | 560 } |
445 | 561 |
446 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( | 562 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( |
447 const RangeList::iterator& range_with_new_buffers_itr) { | 563 const RangeList::iterator& range_with_new_buffers_itr) { |
448 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 564 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
449 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 565 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
450 next_range_itr++; | 566 next_range_itr++; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 } | 624 } |
509 | 625 |
510 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { | 626 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() { |
511 if (!selected_range_) | 627 if (!selected_range_) |
512 return kNoTimestamp(); | 628 return kNoTimestamp(); |
513 | 629 |
514 DCHECK(selected_range_->HasNextBufferPosition()); | 630 DCHECK(selected_range_->HasNextBufferPosition()); |
515 return selected_range_->GetNextTimestamp(); | 631 return selected_range_->GetNextTimestamp(); |
516 } | 632 } |
517 | 633 |
| 634 base::TimeDelta SourceBufferStream::GetEndBufferTimestamp() { |
| 635 if (!selected_range_) |
| 636 return kNoTimestamp(); |
| 637 return selected_range_->GetEndTimestamp(); |
| 638 } |
| 639 |
518 SourceBufferStream::RangeList::iterator | 640 SourceBufferStream::RangeList::iterator |
519 SourceBufferStream::FindExistingRangeFor(const BufferQueue& new_buffers) { | 641 SourceBufferStream::FindExistingRangeFor(base::TimeDelta start_timestamp) { |
520 DCHECK(!new_buffers.empty()); | |
521 base::TimeDelta start_timestamp = new_buffers.front()->GetDecodeTimestamp(); | |
522 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); itr++) { | 642 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); itr++) { |
523 if ((*itr)->BelongsToRange(start_timestamp)) | 643 if ((*itr)->BelongsToRange(start_timestamp)) |
524 return itr; | 644 return itr; |
525 } | 645 } |
526 return ranges_.end(); | 646 return ranges_.end(); |
527 } | 647 } |
528 | 648 |
529 SourceBufferStream::RangeList::iterator | 649 SourceBufferStream::RangeList::iterator |
530 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) { | 650 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) { |
531 base::TimeDelta start_timestamp = new_range->GetStartTimestamp(); | 651 base::TimeDelta start_timestamp = new_range->GetStartTimestamp(); |
(...skipping 14 matching lines...) Expand all Loading... |
546 break; | 666 break; |
547 } | 667 } |
548 DCHECK(itr != ranges_.end()); | 668 DCHECK(itr != ranges_.end()); |
549 return itr; | 669 return itr; |
550 } | 670 } |
551 | 671 |
552 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { | 672 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { |
553 Ranges<base::TimeDelta> ranges; | 673 Ranges<base::TimeDelta> ranges; |
554 for (RangeList::const_iterator itr = ranges_.begin(); | 674 for (RangeList::const_iterator itr = ranges_.begin(); |
555 itr != ranges_.end(); itr++) { | 675 itr != ranges_.end(); itr++) { |
556 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetEndTimestamp()); | 676 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp()); |
557 } | 677 } |
558 return ranges; | 678 return ranges; |
559 } | 679 } |
560 | 680 |
561 void SourceBufferStream::EndOfStream() { | 681 void SourceBufferStream::EndOfStream() { |
562 DCHECK(CanEndOfStream()); | 682 DCHECK(CanEndOfStream()); |
563 end_of_stream_ = true; | 683 end_of_stream_ = true; |
564 } | 684 } |
565 | 685 |
566 bool SourceBufferStream::CanEndOfStream() const { | 686 bool SourceBufferStream::CanEndOfStream() const { |
567 return ranges_.empty() || selected_range_ == ranges_.back(); | 687 return ranges_.empty() || selected_range_ == ranges_.back(); |
568 } | 688 } |
569 | 689 |
570 SourceBufferRange::SourceBufferRange(const BufferQueue& new_buffers, | 690 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { |
571 base::TimeDelta media_segment_start_time) | 691 if (max_interbuffer_distance_ == kNoTimestamp()) |
| 692 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
| 693 return max_interbuffer_distance_; |
| 694 } |
| 695 |
| 696 SourceBufferRange::SourceBufferRange( |
| 697 const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time, |
| 698 const InterbufferDistanceCB& interbuffer_distance_cb) |
572 : next_buffer_index_(-1), | 699 : next_buffer_index_(-1), |
573 waiting_for_keyframe_(false), | 700 waiting_for_keyframe_(false), |
574 next_keyframe_timestamp_(kNoTimestamp()), | 701 next_keyframe_timestamp_(kNoTimestamp()), |
575 media_segment_start_time_(media_segment_start_time) { | 702 media_segment_start_time_(media_segment_start_time), |
| 703 interbuffer_distance_cb_(interbuffer_distance_cb) { |
576 DCHECK(!new_buffers.empty()); | 704 DCHECK(!new_buffers.empty()); |
577 DCHECK(new_buffers.front()->IsKeyframe()); | 705 DCHECK(new_buffers.front()->IsKeyframe()); |
| 706 DCHECK(!interbuffer_distance_cb.is_null()); |
578 AppendToEnd(new_buffers); | 707 AppendToEnd(new_buffers); |
579 } | 708 } |
580 | 709 |
581 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) { | 710 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) { |
582 for (BufferQueue::const_iterator itr = new_buffers.begin(); | 711 for (BufferQueue::const_iterator itr = new_buffers.begin(); |
583 itr != new_buffers.end(); itr++) { | 712 itr != new_buffers.end(); itr++) { |
584 DCHECK((*itr)->GetDuration() > base::TimeDelta()); | |
585 DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp()); | 713 DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp()); |
586 buffers_.push_back(*itr); | 714 buffers_.push_back(*itr); |
587 if ((*itr)->IsKeyframe()) { | 715 if ((*itr)->IsKeyframe()) { |
588 keyframe_map_.insert( | 716 keyframe_map_.insert( |
589 std::make_pair((*itr)->GetDecodeTimestamp(), buffers_.size() - 1)); | 717 std::make_pair((*itr)->GetDecodeTimestamp(), buffers_.size() - 1)); |
590 | 718 |
591 if (waiting_for_keyframe_ && | 719 if (waiting_for_keyframe_ && |
592 (*itr)->GetDecodeTimestamp() >= next_keyframe_timestamp_) { | 720 (*itr)->GetDecodeTimestamp() >= next_keyframe_timestamp_) { |
593 next_buffer_index_ = buffers_.size() - 1; | 721 next_buffer_index_ = buffers_.size() - 1; |
594 next_keyframe_timestamp_ = base::TimeDelta(); | 722 next_keyframe_timestamp_ = base::TimeDelta(); |
(...skipping 15 matching lines...) Expand all Loading... |
610 // previous element if it did not return the element exactly equal to | 738 // previous element if it did not return the element exactly equal to |
611 // |timestamp|. | 739 // |timestamp|. |
612 if (result != keyframe_map_.begin() && | 740 if (result != keyframe_map_.begin() && |
613 (result == keyframe_map_.end() || result->first != timestamp)) { | 741 (result == keyframe_map_.end() || result->first != timestamp)) { |
614 result--; | 742 result--; |
615 } | 743 } |
616 next_buffer_index_ = result->second; | 744 next_buffer_index_ = result->second; |
617 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 745 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
618 } | 746 } |
619 | 747 |
620 void SourceBufferRange::SeekAfter(base::TimeDelta timestamp) { | 748 void SourceBufferRange::SeekAheadTo(base::TimeDelta timestamp) { |
| 749 SeekAhead(timestamp, false); |
| 750 } |
| 751 |
| 752 void SourceBufferRange::SeekAheadPast(base::TimeDelta timestamp) { |
| 753 SeekAhead(timestamp, true); |
| 754 } |
| 755 |
| 756 void SourceBufferRange::SeekAhead(base::TimeDelta timestamp, |
| 757 bool skip_given_timestamp) { |
621 DCHECK(!keyframe_map_.empty()); | 758 DCHECK(!keyframe_map_.empty()); |
622 | 759 |
623 // lower_bound() returns the first element >= |timestamp|, so |result| is the | 760 KeyframeMap::iterator result = |
624 // value that we want. | 761 GetFirstKeyframeAt(timestamp, skip_given_timestamp); |
625 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | |
626 | 762 |
627 // If there isn't a keyframe after |timestamp|, then seek to end and return | 763 // If there isn't a keyframe after |timestamp|, then seek to end and return |
628 // kNoTimestamp to signal such. | 764 // kNoTimestamp to signal such. |
629 if (result == keyframe_map_.end()) { | 765 if (result == keyframe_map_.end()) { |
630 waiting_for_keyframe_ = true; | 766 waiting_for_keyframe_ = true; |
631 next_buffer_index_ = -1; | 767 next_buffer_index_ = -1; |
632 next_keyframe_timestamp_ = timestamp; | 768 next_keyframe_timestamp_ = timestamp; |
633 return; | 769 return; |
634 } | 770 } |
635 | |
636 next_buffer_index_ = result->second; | 771 next_buffer_index_ = result->second; |
637 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 772 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
638 } | 773 } |
639 | 774 |
640 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { | 775 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { |
641 // Find the first keyframe after |timestamp|. | 776 // Find the first keyframe after |timestamp|, not including |timestamp|. |
642 KeyframeMap::iterator new_beginning_keyframe = | 777 KeyframeMap::iterator new_beginning_keyframe = |
643 keyframe_map_.lower_bound(timestamp); | 778 GetFirstKeyframeAt(timestamp, true); |
644 | 779 |
645 // If there is no keyframe after |timestamp|, we can't split the range. | 780 // If there is no keyframe after |timestamp|, we can't split the range. |
646 if (new_beginning_keyframe == keyframe_map_.end()) | 781 if (new_beginning_keyframe == keyframe_map_.end()) |
647 return NULL; | 782 return NULL; |
648 | 783 |
649 // Remove the data beginning at |keyframe_index| from |buffers_| and save it | 784 // Remove the data beginning at |keyframe_index| from |buffers_| and save it |
650 // into |removed_buffers|. | 785 // into |removed_buffers|. |
651 int keyframe_index = new_beginning_keyframe->second; | 786 int keyframe_index = new_beginning_keyframe->second; |
652 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); | 787 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
653 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; | 788 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; |
654 BufferQueue removed_buffers(starting_point, buffers_.end()); | 789 BufferQueue removed_buffers(starting_point, buffers_.end()); |
655 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); | 790 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); |
656 buffers_.erase(starting_point, buffers_.end()); | 791 buffers_.erase(starting_point, buffers_.end()); |
657 | 792 |
658 // Create a new range with |removed_buffers|. | 793 // Create a new range with |removed_buffers|. |
659 SourceBufferRange* split_range = | 794 SourceBufferRange* split_range = |
660 new SourceBufferRange(removed_buffers, kNoTimestamp()); | 795 new SourceBufferRange( |
| 796 removed_buffers, kNoTimestamp(), interbuffer_distance_cb_); |
661 | 797 |
662 // If |next_buffer_index_| points to a buffer in |split_range|, update the | 798 // If |next_buffer_index_| points to a buffer in |split_range|, update the |
663 // |next_buffer_index_| of this range and |split_range| accordingly. | 799 // |next_buffer_index_| of this range and |split_range| accordingly. |
664 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 800 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
665 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; | 801 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; |
666 next_buffer_index_ = -1; | 802 next_buffer_index_ = -1; |
667 } | 803 } |
668 return split_range; | 804 return split_range; |
669 } | 805 } |
670 | 806 |
671 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { | 807 SourceBufferRange::KeyframeMap::iterator |
672 DeleteAfter(buffers_.begin(), removed_buffers); | 808 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, |
| 809 bool skip_given_timestamp) { |
| 810 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
| 811 // lower_bound() returns the first element >= |timestamp|, so if we don't want |
| 812 // to include keyframes == |timestamp|, we have to increment the iterator |
| 813 // accordingly. |
| 814 if (skip_given_timestamp && |
| 815 result != keyframe_map_.end() && result->first == timestamp) { |
| 816 ++result; |
| 817 } |
| 818 return result; |
673 } | 819 } |
674 | 820 |
675 void SourceBufferRange::DeleteAfter( | 821 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { |
| 822 return TruncateAt(buffers_.begin(), removed_buffers); |
| 823 } |
| 824 |
| 825 bool SourceBufferRange::TruncateAt( |
676 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { | 826 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { |
677 // Find the place in |buffers_| where we will begin deleting data. | 827 // Find the place in |buffers_| where we will begin deleting data. |
678 BufferQueue::iterator starting_point = | 828 BufferQueue::iterator starting_point = |
679 std::lower_bound(buffers_.begin(), buffers_.end(), | 829 std::lower_bound(buffers_.begin(), buffers_.end(), |
680 buffer, | 830 buffer, |
681 BufferComparator); | 831 BufferComparator); |
682 DeleteAfter(starting_point, removed_buffers); | 832 return TruncateAt(starting_point, removed_buffers); |
683 } | 833 } |
684 | 834 |
685 void SourceBufferRange::DeleteAfter( | 835 bool SourceBufferRange::TruncateAt( |
686 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { | 836 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { |
687 DCHECK(removed_buffers); | 837 DCHECK(removed_buffers); |
| 838 DCHECK(removed_buffers->empty()); |
| 839 |
688 // Return if we're not deleting anything. | 840 // Return if we're not deleting anything. |
689 if (starting_point == buffers_.end()) | 841 if (starting_point == buffers_.end()) |
690 return; | 842 return false; |
691 | 843 |
692 // Reset the next buffer index if we will be deleting the buffer that's next | 844 // Reset the next buffer index if we will be deleting the buffer that's next |
693 // in sequence. | 845 // in sequence. |
694 if (HasNextBuffer() && | 846 bool removed_next_buffer = false; |
695 GetNextTimestamp() >= (*starting_point)->GetDecodeTimestamp()) { | 847 if (HasNextBufferPosition()) { |
696 // Save the buffers we're about to delete if the output parameter is valid. | 848 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); |
697 int starting_offset = starting_point - buffers_.begin(); | 849 if (next_buffer_timestamp == kNoTimestamp() || |
698 int next_buffer_offset = next_buffer_index_ - starting_offset; | 850 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { |
699 DCHECK_GE(next_buffer_offset, 0); | 851 if (HasNextBuffer()) { |
700 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); | 852 int starting_offset = starting_point - buffers_.begin(); |
701 removed_buffers->swap(saved); | 853 int next_buffer_offset = next_buffer_index_ - starting_offset; |
702 next_buffer_index_ = -1; | 854 DCHECK_GE(next_buffer_offset, 0); |
| 855 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); |
| 856 removed_buffers->swap(saved); |
| 857 } |
| 858 next_buffer_index_ = -1; |
| 859 removed_next_buffer = true; |
| 860 } |
703 } | 861 } |
704 | 862 |
705 // Remove keyframes from |starting_point| onward. | 863 // Remove keyframes from |starting_point| onward. |
706 KeyframeMap::iterator starting_point_keyframe = | 864 KeyframeMap::iterator starting_point_keyframe = |
707 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); | 865 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp()); |
708 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); | 866 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); |
709 | 867 |
710 // Remove everything from |starting_point| onward. | 868 // Remove everything from |starting_point| onward. |
711 buffers_.erase(starting_point, buffers_.end()); | 869 buffers_.erase(starting_point, buffers_.end()); |
| 870 return removed_next_buffer; |
712 } | 871 } |
713 | 872 |
714 bool SourceBufferRange::GetNextBuffer( | 873 bool SourceBufferRange::GetNextBuffer( |
715 scoped_refptr<StreamParserBuffer>* out_buffer) { | 874 scoped_refptr<StreamParserBuffer>* out_buffer) { |
716 if (waiting_for_keyframe_ || | 875 if (waiting_for_keyframe_ || |
717 next_buffer_index_ >= static_cast<int>(buffers_.size())) { | 876 next_buffer_index_ >= static_cast<int>(buffers_.size())) { |
718 return false; | 877 return false; |
719 } | 878 } |
720 | 879 |
721 DCHECK_GE(next_buffer_index_, 0); | 880 DCHECK_GE(next_buffer_index_, 0); |
722 *out_buffer = buffers_.at(next_buffer_index_); | 881 *out_buffer = buffers_.at(next_buffer_index_); |
723 next_buffer_index_++; | 882 next_buffer_index_++; |
724 return true; | 883 return true; |
725 } | 884 } |
726 | 885 |
727 bool SourceBufferRange::HasNextBuffer() const { | 886 bool SourceBufferRange::HasNextBuffer() const { |
728 return next_buffer_index_ >= 0 && | 887 return next_buffer_index_ >= 0 && |
729 next_buffer_index_ < static_cast<int>(buffers_.size()); | 888 next_buffer_index_ < static_cast<int>(buffers_.size()); |
730 } | 889 } |
731 | 890 |
732 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { | 891 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { |
733 DCHECK(!buffers_.empty()); | 892 DCHECK(!buffers_.empty()); |
734 DCHECK(HasNextBufferPosition()); | 893 DCHECK(HasNextBufferPosition()); |
735 | 894 |
736 if (waiting_for_keyframe_) | 895 if (waiting_for_keyframe_) |
737 return next_keyframe_timestamp_; | 896 return next_keyframe_timestamp_; |
738 | 897 |
739 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) | 898 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) |
740 return buffers_.back()->GetEndTimestamp(); | 899 return kNoTimestamp(); |
741 | 900 |
742 return buffers_.at(next_buffer_index_)->GetDecodeTimestamp(); | 901 return buffers_.at(next_buffer_index_)->GetDecodeTimestamp(); |
743 } | 902 } |
744 | 903 |
745 bool SourceBufferRange::HasNextBufferPosition() const { | 904 bool SourceBufferRange::HasNextBufferPosition() const { |
746 return next_buffer_index_ >= 0 || waiting_for_keyframe_; | 905 return next_buffer_index_ >= 0 || waiting_for_keyframe_; |
747 } | 906 } |
748 | 907 |
749 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, | 908 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, |
750 bool transfer_current_position) { | 909 bool transfer_current_position) { |
(...skipping 17 matching lines...) Expand all Loading... |
768 } | 927 } |
769 | 928 |
770 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { | 929 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { |
771 DCHECK(!buffers_.empty()); | 930 DCHECK(!buffers_.empty()); |
772 | 931 |
773 return (IsNextInSequence(buffers_.back(), timestamp) || | 932 return (IsNextInSequence(buffers_.back(), timestamp) || |
774 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); | 933 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); |
775 } | 934 } |
776 | 935 |
777 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { | 936 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { |
778 return !keyframe_map_.empty() && GetStartTimestamp() <= timestamp && | 937 base::TimeDelta start_timestamp = |
779 GetEndTimestamp() > timestamp; | 938 std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom()); |
| 939 return !keyframe_map_.empty() && start_timestamp <= timestamp && |
| 940 timestamp < GetBufferedEndTimestamp(); |
780 } | 941 } |
781 | 942 |
782 bool SourceBufferRange::CompletelyOverlaps( | 943 bool SourceBufferRange::CompletelyOverlaps( |
783 const SourceBufferRange& range) const { | 944 const SourceBufferRange& range) const { |
784 return GetStartTimestamp() <= range.GetStartTimestamp() && | 945 return GetStartTimestamp() <= range.GetStartTimestamp() && |
785 GetEndTimestamp() >= range.GetEndTimestamp(); | 946 GetEndTimestamp() >= range.GetEndTimestamp(); |
786 } | 947 } |
787 | 948 |
788 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { | 949 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { |
789 return range.GetStartTimestamp() < GetEndTimestamp() && | 950 return range.GetStartTimestamp() <= GetEndTimestamp() && |
790 GetEndTimestamp() < range.GetEndTimestamp(); | 951 GetEndTimestamp() < range.GetEndTimestamp(); |
791 } | 952 } |
792 | 953 |
793 base::TimeDelta SourceBufferRange::GetStartTimestamp() const { | 954 base::TimeDelta SourceBufferRange::GetStartTimestamp() const { |
794 DCHECK(!buffers_.empty()); | 955 DCHECK(!buffers_.empty()); |
795 base::TimeDelta start_timestamp = media_segment_start_time_; | 956 base::TimeDelta start_timestamp = media_segment_start_time_; |
796 if (start_timestamp == kNoTimestamp()) | 957 if (start_timestamp == kNoTimestamp()) |
797 start_timestamp = buffers_.front()->GetDecodeTimestamp(); | 958 start_timestamp = buffers_.front()->GetDecodeTimestamp(); |
798 return start_timestamp; | 959 return start_timestamp; |
799 } | 960 } |
800 | 961 |
801 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { | 962 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { |
802 DCHECK(!buffers_.empty()); | 963 DCHECK(!buffers_.empty()); |
803 return buffers_.back()->GetEndTimestamp(); | 964 return buffers_.back()->GetDecodeTimestamp(); |
| 965 } |
| 966 |
| 967 base::TimeDelta SourceBufferRange::GetBufferedEndTimestamp() const { |
| 968 DCHECK(!buffers_.empty()); |
| 969 base::TimeDelta duration = buffers_.back()->GetDuration(); |
| 970 if (duration == kNoTimestamp() || duration == base::TimeDelta()) |
| 971 duration = GetApproximateDuration(); |
| 972 return GetEndTimestamp() + duration; |
| 973 } |
| 974 |
| 975 bool SourceBufferRange::IsNextInSequence( |
| 976 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 977 base::TimeDelta timestamp) const { |
| 978 return buffer->GetDecodeTimestamp() < timestamp && |
| 979 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); |
| 980 } |
| 981 |
| 982 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { |
| 983 // Because we do not know exactly when is the next timestamp, any buffer |
| 984 // that starts within 2x the approximate duration of a buffer is considered |
| 985 // within this range. |
| 986 return 2 * GetApproximateDuration(); |
| 987 } |
| 988 |
| 989 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
| 990 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
| 991 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
| 992 return max_interbuffer_distance; |
804 } | 993 } |
805 | 994 |
806 } // namespace media | 995 } // namespace media |
OLD | NEW |