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

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 10692053: Remove buffer duration calculation from WebMClusterParser and update SourceBufferStream accordingly (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 28 matching lines...) Expand all
39 void AppendToEnd(const SourceBufferRange& range, 39 void AppendToEnd(const SourceBufferRange& range,
40 bool transfer_current_position); 40 bool transfer_current_position);
41 bool CanAppendToEnd(const SourceBufferRange& range) const; 41 bool CanAppendToEnd(const SourceBufferRange& range) const;
42 42
43 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. 43 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|.
44 // Assumes |timestamp| is valid and in this range. 44 // Assumes |timestamp| is valid and in this range.
45 void Seek(base::TimeDelta timestamp); 45 void Seek(base::TimeDelta timestamp);
46 46
47 // Updates |next_buffer_index_| to point to next keyframe after or equal to 47 // Updates |next_buffer_index_| to point to next keyframe after or equal to
48 // |timestamp|. 48 // |timestamp|.
49 void SeekAfter(base::TimeDelta timestamp); 49 void SeekAheadTo(base::TimeDelta timestamp);
50
51 // Updates |next_buffer_index_| to point to next keyframe strictly after
52 // |timestamp|.
53 void SeekAheadPast(base::TimeDelta timestamp);
50 54
51 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and 55 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and
52 // returns a new SourceBufferRange with the buffers from that keyframe onward. 56 // 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 57 // 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 58 // there is no keyframe after |timestamp|, SplitRange() returns null and this
55 // range is unmodified. 59 // range is unmodified.
56 SourceBufferRange* SplitRange(base::TimeDelta timestamp); 60 SourceBufferRange* SplitRange(base::TimeDelta timestamp);
57 61
58 // Deletes the buffers from this range whose timestamps are greater than or 62 // Deletes the buffers from this range whose timestamps are greater than or
59 // equal to |buffer|'s timestamp. 63 // equal to |buffer|'s timestamp.
60 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was 64 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
61 // deleted, and deletes the |keyframe_map_| entries for the buffers that 65 // deleted, and deletes the |keyframe_map_| entries for the buffers that
62 // were removed. 66 // were removed.
63 // |deleted_buffers| contains the buffers that were deleted from this range, 67 // |deleted_buffers| contains the buffers that were deleted from this range,
64 // starting at the buffer that had been at |next_buffer_index_|. 68 // 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 69 // Returns true if the |next_buffer_index_| is reset. Note that this method
66 // deleted. 70 // may return true even if it does not add any buffers to |deleted_buffers|.
67 void DeleteAfter(scoped_refptr<StreamParserBuffer> buffer, 71 // This indicates that the range had not buffered |next_buffer_index_|, but
68 BufferQueue* deleted_buffers); 72 // a buffer at that position would have been deleted.
73 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer,
74 BufferQueue* deleted_buffers);
69 // Deletes all buffers in range. 75 // Deletes all buffers in range.
70 void DeleteAll(BufferQueue* deleted_buffers); 76 bool DeleteAll(BufferQueue* deleted_buffers);
71 77
72 // Updates |out_buffer| with the next buffer in presentation order. Seek() 78 // Updates |out_buffer| with the next buffer in presentation order. Seek()
73 // must be called before calls to GetNextBuffer(), and buffers are returned 79 // 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 80 // 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 81 // filled with a valid buffer, false if there is not enough data to fulfill
76 // the request. 82 // the request.
77 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); 83 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
78 bool HasNextBuffer() const; 84 bool HasNextBuffer() const;
79 85
80 // Returns true if the range knows the position of the next buffer it should 86 // 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 87 // return, i.e. it has been Seek()ed. This does not necessarily mean that it
82 // has the next buffer yet. 88 // has the next buffer yet.
83 bool HasNextBufferPosition() const; 89 bool HasNextBufferPosition() const;
84 90
85 // Returns the timestamp of the next buffer that will be returned from 91 // 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 92 // GetNextBuffer(). This may be an approximation if the range does not have
87 // next buffer buffered. 93 // next buffer buffered.
88 base::TimeDelta GetNextTimestamp() const; 94 base::TimeDelta GetNextTimestamp() const;
89 95
90 // Returns the start timestamp of the range. 96 // Returns the start timestamp of the range.
91 base::TimeDelta GetStartTimestamp() const; 97 base::TimeDelta GetStartTimestamp() const;
92 98
93 // Returns the end timestamp of the buffered data. (Note that this is equal to 99 // Returns the end timestamp of the buffered data.
94 // the last buffer's timestamp + its duration.)
95 base::TimeDelta GetEndTimestamp() const; 100 base::TimeDelta GetEndTimestamp() const;
96 101
97 // Returns whether a buffer with a starting timestamp of |timestamp| would 102 // 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 103 // belong in this range. This includes a buffer that would be appended to
99 // the end of the range. 104 // the end of the range.
100 bool BelongsToRange(base::TimeDelta timestamp) const; 105 bool BelongsToRange(base::TimeDelta timestamp) const;
101 106
102 // Returns true if the range has enough data to seek to the specified 107 // Returns true if the range has enough data to seek to the specified
103 // |timestamp|, false otherwise. 108 // |timestamp|, false otherwise.
104 bool CanSeekTo(base::TimeDelta timestamp) const; 109 bool CanSeekTo(base::TimeDelta timestamp) const;
105 110
106 // Returns true if this range's buffered timespan completely overlaps the 111 // Returns true if this range's buffered timespan completely overlaps the
107 // buffered timespan of |range|. 112 // buffered timespan of |range|.
108 bool CompletelyOverlaps(const SourceBufferRange& range) const; 113 bool CompletelyOverlaps(const SourceBufferRange& range) const;
109 114
110 // Returns true if the end of this range contains buffers that overlaps with 115 // Returns true if the end of this range contains buffers that overlaps with
111 // the beginning of |range|. 116 // the beginning of |range|.
112 bool EndOverlaps(const SourceBufferRange& range) const; 117 bool EndOverlaps(const SourceBufferRange& range) const;
113 118
119 // Returns true if |timestamp| is the timestamp of the next buffer in
120 // sequence after |buffer|, false otherwise.
121 bool IsNextInSequence(
122 const scoped_refptr<media::StreamParserBuffer>& buffer,
123 base::TimeDelta timestamp) const;
124
125 // Returns the distance in time estimating how far from the beginning or end
126 // of this range a buffer can be to considered in the range.
127 base::TimeDelta GetFudgeRoom() const;
128
114 private: 129 private:
115 // Helper method to delete buffers in |buffers_| starting from 130 typedef std::map<base::TimeDelta, size_t> KeyframeMap;
131
132 // Seeks the range to the next keyframe after |timestamp|. If
133 // |skip_given_timestamp| is true, the seek will go to a keyframe with a
134 // timestamp strictly greater than |timestamp|.
135 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp);
136 KeyframeMap::iterator GetFirstKeyframeAfter(
137 base::TimeDelta timestamp, bool skip_given_timestamp);
138
139 // Helper method to delete buffers in |buffers_| starting at
116 // |starting_point|, an iterator in |buffers_|. 140 // |starting_point|, an iterator in |buffers_|.
117 void DeleteAfter(const BufferQueue::iterator& starting_point, 141 bool TruncateAt(const BufferQueue::iterator& starting_point,
118 BufferQueue* deleted_buffers); 142 BufferQueue* deleted_buffers);
119 143
144 // Returns true if |timestamp| is the timestamp of the next buffer in
145 // sequence after |buffer|, false otherwise.
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 ? Is this supposed to be above the TruncateAt() de
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Oops wow, not sure why this is here! (Was the comm
120 // An ordered list of buffers in this range. 146 // An ordered list of buffers in this range.
121 BufferQueue buffers_; 147 BufferQueue buffers_;
122 148
123 // Maps keyframe timestamps to its index position in |buffers_|. 149 // Maps keyframe timestamps to its index position in |buffers_|.
124 typedef std::map<base::TimeDelta, size_t> KeyframeMap;
125 KeyframeMap keyframe_map_; 150 KeyframeMap keyframe_map_;
126 151
127 // Index into |buffers_| for the next buffer to be returned by 152 // Index into |buffers_| for the next buffer to be returned by
128 // GetNextBuffer(), set to -1 before Seek(). 153 // GetNextBuffer(), set to -1 before Seek().
129 int next_buffer_index_; 154 int next_buffer_index_;
130 155
131 // True if the range needs to wait for the next keyframe to be appended before 156 // True if the range needs to wait for the next keyframe to be appended before
132 // returning buffers from GetNextBuffer(). 157 // returning buffers from GetNextBuffer().
133 bool waiting_for_keyframe_; 158 bool waiting_for_keyframe_;
134 159
135 // If |waiting_for_keyframe_| is true, this range will wait for the next 160 // If |waiting_for_keyframe_| is true, this range will wait for the next
136 // keyframe with timestamp >= |next_keyframe_timestamp_|. 161 // keyframe with timestamp >= |next_keyframe_timestamp_|.
137 base::TimeDelta next_keyframe_timestamp_; 162 base::TimeDelta next_keyframe_timestamp_;
138 163
139 // If the first buffer in this range is the beginning of a media segment, 164 // 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. 165 // |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 166 // |media_segment_start_time_| may be <= the timestamp of the first buffer in
142 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range 167 // |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 168 // 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 169 // 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 170 // (we don't have a way of knowing the media segment timestamp for the new
146 // range). 171 // range).
147 base::TimeDelta media_segment_start_time_; 172 base::TimeDelta media_segment_start_time_;
148 173
174 // Stores the largest distance between two adjacent buffers in this range.
175 base::TimeDelta max_interbuffer_distance_;
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 Do we really want to keep track of this on a per-S
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Moved to SourceBufferStream and added a callback f
176
149 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); 177 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange);
150 }; 178 };
151 179
152 } // namespace media 180 } // namespace media
153 181
154 // Helper method that returns true if |ranges| is sorted in increasing order, 182 // Helper method that returns true if |ranges| is sorted in increasing order,
155 // false otherwise. 183 // false otherwise.
156 static bool IsRangeListSorted( 184 static bool IsRangeListSorted(
157 const std::list<media::SourceBufferRange*>& ranges) { 185 const std::list<media::SourceBufferRange*>& ranges) {
158 base::TimeDelta prev = media::kNoTimestamp(); 186 base::TimeDelta prev = media::kNoTimestamp();
159 for (std::list<media::SourceBufferRange*>::const_iterator itr = 187 for (std::list<media::SourceBufferRange*>::const_iterator itr =
160 ranges.begin(); itr != ranges.end(); itr++) { 188 ranges.begin(); itr != ranges.end(); ++itr) {
161 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp()) 189 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp())
162 return false; 190 return false;
163 prev = (*itr)->GetEndTimestamp(); 191 prev = (*itr)->GetEndTimestamp();
164 } 192 }
165 return true; 193 return true;
166 } 194 }
167 195
168 // Comparison function for two Buffers based on timestamp. 196 // Comparison function for two Buffers based on timestamp.
169 static bool BufferComparator( 197 static bool BufferComparator(
170 const scoped_refptr<media::StreamParserBuffer>& first, 198 const scoped_refptr<media::StreamParserBuffer>& first,
171 const scoped_refptr<media::StreamParserBuffer>& second) { 199 const scoped_refptr<media::StreamParserBuffer>& second) {
172 return first->GetTimestamp() < second->GetTimestamp(); 200 return first->GetTimestamp() < second->GetTimestamp();
173 } 201 }
174 202
175 // Returns the upper bound for the starting timestamp for the next buffer
176 // in sequence after |buffer|. Assumes |buffer|'s timestamp and
177 // duration are valid.
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
195 namespace media { 203 namespace media {
196 204
197 SourceBufferStream::SourceBufferStream() 205 SourceBufferStream::SourceBufferStream()
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 FYI: Also deleted this constructor; it was only be
198 : seek_pending_(false), 206 : seek_pending_(false),
199 seek_buffer_timestamp_(base::TimeDelta()), 207 seek_buffer_timestamp_(kNoTimestamp()),
200 selected_range_(NULL), 208 selected_range_(NULL),
201 end_of_stream_(false) { 209 end_of_stream_(false),
210 deleted_next_buffer_(false),
211 media_segment_start_time_(kNoTimestamp()),
212 range_for_next_append_(ranges_.end()) {
202 } 213 }
203 214
204 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config) 215 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config)
205 : seek_pending_(false), 216 : seek_pending_(false),
206 seek_buffer_timestamp_(base::TimeDelta()), 217 seek_buffer_timestamp_(kNoTimestamp()),
207 selected_range_(NULL), 218 selected_range_(NULL),
208 end_of_stream_(false) { 219 end_of_stream_(false),
220 deleted_next_buffer_(false),
221 media_segment_start_time_(kNoTimestamp()),
222 range_for_next_append_(ranges_.end()) {
209 audio_config_.CopyFrom(audio_config); 223 audio_config_.CopyFrom(audio_config);
210 } 224 }
211 225
212 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config) 226 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config)
213 : seek_pending_(false), 227 : seek_pending_(false),
214 seek_buffer_timestamp_(base::TimeDelta()), 228 seek_buffer_timestamp_(kNoTimestamp()),
215 selected_range_(NULL), 229 selected_range_(NULL),
216 end_of_stream_(false) { 230 end_of_stream_(false),
231 deleted_next_buffer_(false),
232 media_segment_start_time_(kNoTimestamp()),
233 range_for_next_append_(ranges_.end()) {
217 video_config_.CopyFrom(video_config); 234 video_config_.CopyFrom(video_config);
218 } 235 }
219 236
220 SourceBufferStream::~SourceBufferStream() { 237 SourceBufferStream::~SourceBufferStream() {
221 while (!ranges_.empty()) { 238 while (!ranges_.empty()) {
222 delete ranges_.front(); 239 delete ranges_.front();
223 ranges_.pop_front(); 240 ranges_.pop_front();
224 } 241 }
225 } 242 }
226 243
244 void SourceBufferStream::OnNewMediaSegment(
245 base::TimeDelta media_segment_start_time) {
246 media_segment_start_time_ = media_segment_start_time;
247 range_for_next_append_ = ranges_.end();
248 }
249
227 bool SourceBufferStream::Append( 250 bool SourceBufferStream::Append(
228 const SourceBufferStream::BufferQueue& buffers, 251 const SourceBufferStream::BufferQueue& buffers) {
229 base::TimeDelta media_segment_start_time) {
230 DCHECK(!buffers.empty()); 252 DCHECK(!buffers.empty());
231 DCHECK(media_segment_start_time != kNoTimestamp()); 253 DCHECK(media_segment_start_time_ != kNoTimestamp());
232 254
233 // Find a range into which we'll append |buffers|. 255 // Save a snapshot of the |next_buffer_timestamp| before range modifications
234 RangeList::iterator range_for_new_buffers = FindExistingRangeFor(buffers); 256 // are made.
257 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
258
259 // Find a range into which we'll append |buffers|. Use the last range if a new
260 // media segment hasn't been signalled since the last Append() call.
261 RangeList::iterator range_for_new_buffers = range_for_next_append_;
262 if (range_for_next_append_ == ranges_.end())
263 range_for_new_buffers = FindExistingRangeFor(buffers);
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 Could this line be moved to OnNewMediaSegment() an
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Good idea! Done.
235 264
236 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, 265 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
237 // create a new range with |buffers|. 266 // create a new range with |buffers|.
238 if (range_for_new_buffers != ranges_.end()) { 267 if (range_for_new_buffers != ranges_.end()) {
239 InsertIntoExistingRange(range_for_new_buffers, buffers); 268 InsertIntoExistingRange(range_for_new_buffers, buffers);
240 } else { 269 } else {
241 // Ranges must begin with a keyframe. 270 // Ranges must begin with a keyframe.
242 if (!buffers.front()->IsKeyframe()) 271 if (!buffers.front()->IsKeyframe())
243 return false; 272 return false;
244 range_for_new_buffers = 273 range_for_new_buffers =
245 AddToRanges(new SourceBufferRange(buffers, media_segment_start_time)); 274 AddToRanges(new SourceBufferRange(buffers, media_segment_start_time_));
246 } 275 }
247 276
277 range_for_next_append_ = range_for_new_buffers;
278
248 // Resolve overlaps. 279 // Resolve overlaps.
249 ResolveCompleteOverlaps(range_for_new_buffers); 280 ResolveCompleteOverlaps(range_for_new_buffers);
250 ResolveEndOverlap(range_for_new_buffers); 281 ResolveEndOverlap(range_for_new_buffers);
251 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); 282 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers);
252 283
253 // If these were the first buffers appended to the stream, seek to the 284 // If these were the first buffers appended to the stream, seek to the
254 // beginning of the range. 285 // beginning of the range.
255 // TODO(vrk): This should be done by ChunkDemuxer. (crbug.com/132815) 286 // TODO(vrk): This should be done by ChunkDemuxer. (crbug.com/132815)
256 if (!seek_pending_ && !selected_range_) { 287 if (!seek_pending_ && !selected_range_) {
257 selected_range_ = *range_for_new_buffers; 288 selected_range_ = *range_for_new_buffers;
258 selected_range_->Seek(buffers.front()->GetTimestamp()); 289 selected_range_->Seek(buffers.front()->GetTimestamp());
259 } 290 }
260 291
261 // Finally, try to complete pending seek if one exists. 292 // Seek to try to fulfill a previous call to Seek().
262 if (seek_pending_) 293 if (seek_pending_) {
294 DCHECK(!selected_range_);
295 DCHECK(!deleted_next_buffer_);
263 Seek(seek_buffer_timestamp_); 296 Seek(seek_buffer_timestamp_);
297 }
264 298
299 // Seek because the Append() has deleted the buffer that would have been
300 // returned in the next call to GetNextBuffer().
301 if (deleted_next_buffer_) {
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 I'm not thrilled about deleted_next_buffer_ & dele
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Yeah, I knew it was a wrong thing to do but was th
302 DCHECK(!seek_pending_);
303 selected_range_ = *range_for_new_buffers;
304 if (!deleted_buffers_.empty()) {
305 // Seek the range to the keyframe at or after |next_buffer_timestamp|.
306 selected_range_->SeekAheadTo(next_buffer_timestamp);
307 } else {
308 // If we've deleted the next buffer but |deleted_buffers_| is empty,
309 // that means |next_buffer_timestamp| represents the time we need to
310 // seek past (i.e. the keyframe timestamp needs to be strictly greater
311 // than |next_buffer_timestamp|).
312 selected_range_->SeekAheadPast(next_buffer_timestamp);
313 }
314 UpdateTrackBuffer();
315 deleted_buffers_.clear();
316 deleted_next_buffer_ = false;
317 }
318
319 DCHECK(!deleted_next_buffer_);
265 DCHECK(IsRangeListSorted(ranges_)); 320 DCHECK(IsRangeListSorted(ranges_));
266 return true; 321 return true;
267 } 322 }
268 323
269 void SourceBufferStream::InsertIntoExistingRange( 324 void SourceBufferStream::InsertIntoExistingRange(
270 const RangeList::iterator& range_for_new_buffers_itr, 325 const RangeList::iterator& range_for_new_buffers_itr,
271 const BufferQueue& new_buffers) { 326 const BufferQueue& new_buffers) {
272 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; 327 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr;
273 328
274 // If this is a simple case where we can just append to the end of the range, 329 // If this is a simple case where we can just append to the end of the range,
275 // do so and return. 330 // do so and return.
276 if (range_for_new_buffers->CanAppendToEnd(new_buffers)) { 331 if (range_for_new_buffers->CanAppendToEnd(new_buffers)) {
277 range_for_new_buffers->AppendToEnd(new_buffers); 332 range_for_new_buffers->AppendToEnd(new_buffers);
278 return; 333 return;
279 } 334 }
280 335
281 // Otherwise, this is either a start overlap or an middle overlap. 336 // Otherwise, this is either a start overlap or an middle overlap.
282 337
283 // In case this is a middle overlap, save the buffers that come after the end 338 // 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. 339 // 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 = 340 SourceBufferRange* new_next_range =
288 range_for_new_buffers->SplitRange(new_buffers.back()->GetEndTimestamp()); 341 range_for_new_buffers->SplitRange(new_buffers.back()->GetTimestamp());
289 342
290 if (new_next_range) 343 if (new_next_range)
291 AddToRanges(new_next_range); 344 AddToRanges(new_next_range);
292 345
293 // Delete the buffers that are overlapped by |new_buffers|, then append 346 // Delete the buffers that are overlapped by |new_buffers|, then append
294 // |new_buffers| to the end of the range. 347 // |new_buffers| to the end of the range.
295 BufferQueue deleted_buffers; 348 bool deleted_next_buffer =
296 range_for_new_buffers->DeleteAfter(new_buffers.front(), &deleted_buffers); 349 range_for_new_buffers->TruncateAt(new_buffers.front(), &deleted_buffers_);
297 range_for_new_buffers->AppendToEnd(new_buffers); 350 range_for_new_buffers->AppendToEnd(new_buffers);
298 351
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()->GetTimestamp()) {
303 return;
304 }
305
306 // If this was a middle overlap resulting in a new range, and the next buffer 352 // 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 353 // position has been transferred to the newly created range, update the
308 // |selected_range_| accordingly. 354 // |selected_range_| accordingly.
309 if (new_next_range && new_next_range->HasNextBufferPosition()) { 355 if (new_next_range && new_next_range->HasNextBufferPosition()) {
310 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); 356 DCHECK(!range_for_new_buffers->HasNextBufferPosition());
357 DCHECK(!deleted_next_buffer);
311 selected_range_ = new_next_range; 358 selected_range_ = new_next_range;
312 return;
313 } 359 }
314 360
315 selected_range_ = range_for_new_buffers; 361 DCHECK(!deleted_next_buffer_);
316 selected_range_->SeekAfter(next_buffer_timestamp); 362 deleted_next_buffer_ = deleted_next_buffer;
317 UpdateTrackBuffer(deleted_buffers);
318 } 363 }
319 364
320 void SourceBufferStream::ResolveCompleteOverlaps( 365 void SourceBufferStream::ResolveCompleteOverlaps(
321 const RangeList::iterator& range_with_new_buffers_itr) { 366 const RangeList::iterator& range_with_new_buffers_itr) {
322 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 367 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
323 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 368 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
324 next_range_itr++; 369 next_range_itr++;
325 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
326 370
327 while (next_range_itr != ranges_.end() && 371 while (next_range_itr != ranges_.end() &&
328 range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) { 372 range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) {
329 if (*next_range_itr == selected_range_) { 373 if (*next_range_itr == selected_range_) {
330 // Transfer the next buffer position from the old selected range to the 374 selected_range_ = NULL;
331 // range with the new buffers. 375 bool deleted_next_buffer =
332 selected_range_ = range_with_new_buffers; 376 (*next_range_itr)->DeleteAll(&deleted_buffers_);
333 selected_range_->SeekAfter(next_buffer_timestamp); 377 DCHECK(deleted_next_buffer);
334 378 DCHECK(!deleted_next_buffer_);
335 // Delete everything from the old selected range and save the next 379 deleted_next_buffer_ = true;
336 // buffers.
337 BufferQueue deleted_buffers;
338 (*next_range_itr)->DeleteAll(&deleted_buffers);
339 UpdateTrackBuffer(deleted_buffers);
340 } 380 }
341 delete *next_range_itr; 381 delete *next_range_itr;
342 next_range_itr = ranges_.erase(next_range_itr); 382 next_range_itr = ranges_.erase(next_range_itr);
343 } 383 }
344 } 384 }
345 385
346 void SourceBufferStream::ResolveEndOverlap( 386 void SourceBufferStream::ResolveEndOverlap(
347 const RangeList::iterator& range_with_new_buffers_itr) { 387 const RangeList::iterator& range_with_new_buffers_itr) {
348 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 388 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
349 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 389 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
350 next_range_itr++; 390 next_range_itr++;
351 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
352 391
353 if (next_range_itr == ranges_.end() || 392 if (next_range_itr == ranges_.end() ||
354 !range_with_new_buffers->EndOverlaps(**next_range_itr)) { 393 !range_with_new_buffers->EndOverlaps(**next_range_itr)) {
355 return; 394 return;
356 } 395 }
357 396
358 // Split the overlapped range after |range_with_new_buffers|'s last buffer 397 // Split the overlapped range after |range_with_new_buffers|'s last buffer
359 // overlaps. Now |overlapped_range| contains only the buffers that do not 398 // overlaps. Now |overlapped_range| contains only the buffers that do not
360 // belong in |ranges_| anymore, and |new_next_range| contains buffers that 399 // belong in |ranges_| anymore, and |new_next_range| contains buffers that
361 // go after |range_with_new_buffers| (without overlap). 400 // go after |range_with_new_buffers| (without overlap).
(...skipping 12 matching lines...) Expand all
374 return; 413 return;
375 414
376 // If the |overlapped_range| transfers its next buffer position to 415 // If the |overlapped_range| transfers its next buffer position to
377 // |new_next_range|, make |new_next_range| the |selected_range_|. 416 // |new_next_range|, make |new_next_range| the |selected_range_|.
378 if (new_next_range && new_next_range->HasNextBufferPosition()) { 417 if (new_next_range && new_next_range->HasNextBufferPosition()) {
379 DCHECK(!overlapped_range->HasNextBufferPosition()); 418 DCHECK(!overlapped_range->HasNextBufferPosition());
380 selected_range_ = new_next_range; 419 selected_range_ = new_next_range;
381 return; 420 return;
382 } 421 }
383 422
384 // Transfer the next buffer position from the old range to the range with 423 // Save the buffers in |overlapped_range|.
385 // the new buffers. 424 bool deleted_next_buffer = overlapped_range->DeleteAll(&deleted_buffers_);
386 selected_range_ = range_with_new_buffers; 425 DCHECK(deleted_next_buffer);
387 selected_range_->SeekAfter(next_buffer_timestamp);
388 426
389 // Update track buffer with overlapped buffers. 427 // If we end-overlap the |selected_range_|, the next buffer is either
390 BufferQueue deleted_buffers; 428 // in |new_next_range| or |deleted_buffers_|. Because we've already returned
391 scoped_refptr<StreamParserBuffer> buffer; 429 // early in the former case, we set |deleted_next_buffer_| to true.
392 while (overlapped_range->GetNextBuffer(&buffer)) { 430 DCHECK(!deleted_next_buffer_);
393 deleted_buffers.push_back(buffer); 431 deleted_next_buffer_ = true;
394 }
395 UpdateTrackBuffer(deleted_buffers);
396 } 432 }
397 433
398 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { 434 void SourceBufferStream::UpdateTrackBuffer() {
399 if (!track_buffer_.empty() || deleted_buffers.empty()) 435 if (!track_buffer_.empty() || deleted_buffers_.empty())
400 return; 436 return;
401 437
402 DCHECK(selected_range_); 438 DCHECK(selected_range_);
403 DCHECK(selected_range_->HasNextBufferPosition()); 439 DCHECK(selected_range_->HasNextBufferPosition());
404 440
405 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); 441 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp();
406 442
407 // If there is no gap between what was deleted and what was added, nothing 443 // If there is no gap between what was deleted and what was added, nothing
408 // should be added to the track buffer. 444 // should be added to the track buffer.
409 if (selected_range_->HasNextBuffer() && 445 if (selected_range_->HasNextBuffer() &&
410 next_keyframe_timestamp == deleted_buffers.front()->GetTimestamp()) { 446 next_keyframe_timestamp == deleted_buffers_.front()->GetTimestamp()) {
411 return; 447 return;
412 } 448 }
413 449
414 DCHECK(next_keyframe_timestamp >= deleted_buffers.front()->GetTimestamp()); 450 DCHECK(next_keyframe_timestamp >= deleted_buffers_.front()->GetTimestamp());
415 451
416 // If the |selected_range_| is ready to return data, fill the track buffer 452 // If the |selected_range_| is ready to return data, fill the track buffer
417 // with all buffers that come before |next_keyframe_timestamp| and return. 453 // with all buffers that come before |next_keyframe_timestamp| and return.
418 if (selected_range_->HasNextBuffer()) { 454 if (selected_range_->HasNextBuffer()) {
419 for (BufferQueue::const_iterator itr = deleted_buffers.begin(); 455 for (BufferQueue::const_iterator itr = deleted_buffers_.begin();
420 itr != deleted_buffers.end() && 456 itr != deleted_buffers_.end() &&
421 (*itr)->GetTimestamp() < next_keyframe_timestamp; ++itr) { 457 (*itr)->GetTimestamp() < next_keyframe_timestamp; ++itr) {
422 track_buffer_.push_back(*itr); 458 track_buffer_.push_back(*itr);
423 } 459 }
424 return; 460 return;
425 } 461 }
426 462
427 // Otherwise, the |selected_range_| is not ready to return data, so add all 463 // Otherwise, the |selected_range_| is not ready to return data, so add all
428 // the deleted buffers into the |track_buffer_|. 464 // the deleted buffers into the |track_buffer_|.
429 track_buffer_ = deleted_buffers; 465 track_buffer_.swap(deleted_buffers_);
430 466
431 // See if the next range contains the keyframe after the end of the 467 // See if the next range contains the keyframe after the end of the
432 // |track_buffer_|, and if so, change |selected_range_|. 468 // |track_buffer_|, and if so, change |selected_range_|.
433 RangeList::iterator next_range_itr = ++(GetSelectedRangeItr()); 469 RangeList::iterator next_range_itr = ++(GetSelectedRangeItr());
434 if (next_range_itr != ranges_.end()) { 470 if (next_range_itr != ranges_.end()) {
435 (*next_range_itr)->SeekAfter(track_buffer_.back()->GetEndTimestamp()); 471 (*next_range_itr)->SeekAheadPast(track_buffer_.back()->GetTimestamp());
436 if ((*next_range_itr)->HasNextBuffer() && 472 if ((*next_range_itr)->HasNextBuffer() &&
437 IsNextInSequence(track_buffer_.back(), 473 selected_range_->IsNextInSequence(
438 (*next_range_itr)->GetNextTimestamp())) { 474 track_buffer_.back(), (*next_range_itr)->GetNextTimestamp())) {
439 selected_range_ = *next_range_itr; 475 selected_range_ = *next_range_itr;
440 } 476 }
441 } 477 }
442 } 478 }
443 479
444 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary( 480 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
445 const RangeList::iterator& range_with_new_buffers_itr) { 481 const RangeList::iterator& range_with_new_buffers_itr) {
446 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; 482 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
447 RangeList::iterator next_range_itr = range_with_new_buffers_itr; 483 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
448 next_range_itr++; 484 next_range_itr++;
449 485
450 if (next_range_itr != ranges_.end() && 486 if (next_range_itr != ranges_.end() &&
451 range_with_new_buffers->CanAppendToEnd(**next_range_itr)) { 487 range_with_new_buffers->CanAppendToEnd(**next_range_itr)) {
452 bool transfer_current_position = selected_range_ == *next_range_itr; 488 bool transfer_current_position = selected_range_ == *next_range_itr;
453 range_with_new_buffers->AppendToEnd(**next_range_itr, 489 range_with_new_buffers->AppendToEnd(**next_range_itr,
454 transfer_current_position); 490 transfer_current_position);
455 // Update |selected_range_| pointer if |range| has become selected after 491 // Update |selected_range_| pointer if |range| has become selected after
456 // merges. 492 // merges.
457 if (transfer_current_position) 493 if (transfer_current_position)
458 selected_range_ = range_with_new_buffers; 494 selected_range_ = range_with_new_buffers;
459 495
460 delete *next_range_itr; 496 delete *next_range_itr;
461 ranges_.erase(next_range_itr); 497 ranges_.erase(next_range_itr);
462 } 498 }
463 } 499 }
464 500
465 void SourceBufferStream::Seek(base::TimeDelta timestamp) { 501 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
502 DCHECK(!deleted_next_buffer_);
503
466 selected_range_ = NULL; 504 selected_range_ = NULL;
467 track_buffer_.clear(); 505 track_buffer_.clear();
468 506
469 seek_buffer_timestamp_ = timestamp; 507 seek_buffer_timestamp_ = timestamp;
470 seek_pending_ = true; 508 seek_pending_ = true;
471 509
472 RangeList::iterator itr = ranges_.end(); 510 RangeList::iterator itr = ranges_.end();
473 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) { 511 for (itr = ranges_.begin(); itr != ranges_.end(); itr++) {
474 if ((*itr)->CanSeekTo(timestamp)) 512 if ((*itr)->CanSeekTo(timestamp))
475 break; 513 break;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 601
564 bool SourceBufferStream::CanEndOfStream() const { 602 bool SourceBufferStream::CanEndOfStream() const {
565 return ranges_.empty() || selected_range_ == ranges_.back(); 603 return ranges_.empty() || selected_range_ == ranges_.back();
566 } 604 }
567 605
568 SourceBufferRange::SourceBufferRange(const BufferQueue& new_buffers, 606 SourceBufferRange::SourceBufferRange(const BufferQueue& new_buffers,
569 base::TimeDelta media_segment_start_time) 607 base::TimeDelta media_segment_start_time)
570 : next_buffer_index_(-1), 608 : next_buffer_index_(-1),
571 waiting_for_keyframe_(false), 609 waiting_for_keyframe_(false),
572 next_keyframe_timestamp_(kNoTimestamp()), 610 next_keyframe_timestamp_(kNoTimestamp()),
573 media_segment_start_time_(media_segment_start_time) { 611 media_segment_start_time_(media_segment_start_time),
612 max_interbuffer_distance_(kNoTimestamp()) {
574 DCHECK(!new_buffers.empty()); 613 DCHECK(!new_buffers.empty());
575 DCHECK(new_buffers.front()->IsKeyframe()); 614 DCHECK(new_buffers.front()->IsKeyframe());
576 AppendToEnd(new_buffers); 615 AppendToEnd(new_buffers);
577 } 616 }
578 617
579 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) { 618 void SourceBufferRange::AppendToEnd(const BufferQueue& new_buffers) {
619 DCHECK(!new_buffers.empty());
620 base::TimeDelta prev_timestamp = kNoTimestamp();
621 if (!buffers_.empty())
622 prev_timestamp = buffers_.back()->GetTimestamp();
623
580 for (BufferQueue::const_iterator itr = new_buffers.begin(); 624 for (BufferQueue::const_iterator itr = new_buffers.begin();
581 itr != new_buffers.end(); itr++) { 625 itr != new_buffers.end(); itr++) {
582 DCHECK((*itr)->GetDuration() > base::TimeDelta()); 626 base::TimeDelta current_timestamp = (*itr)->GetTimestamp();
583 DCHECK((*itr)->GetTimestamp() != kNoTimestamp()); 627 DCHECK(current_timestamp != kNoTimestamp());
584 buffers_.push_back(*itr); 628 buffers_.push_back(*itr);
629
630 // Save the max interbuffer distance seen in the range.
631 if (prev_timestamp != kNoTimestamp()) {
632 base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp;
633 if (max_interbuffer_distance_ == kNoTimestamp()) {
634 max_interbuffer_distance_ = interbuffer_distance;
635 } else {
636 max_interbuffer_distance_ =
637 std::max(max_interbuffer_distance_, interbuffer_distance);
638 }
639 }
640 prev_timestamp = current_timestamp;
641
642 // Update keyframe index with new entry if applicable.
585 if ((*itr)->IsKeyframe()) { 643 if ((*itr)->IsKeyframe()) {
586 keyframe_map_.insert( 644 keyframe_map_.insert(
587 std::make_pair((*itr)->GetTimestamp(), buffers_.size() - 1)); 645 std::make_pair((*itr)->GetTimestamp(), buffers_.size() - 1));
588 646
589 if (waiting_for_keyframe_ && 647 if (waiting_for_keyframe_ &&
590 (*itr)->GetTimestamp() >= next_keyframe_timestamp_) { 648 (*itr)->GetTimestamp() >= next_keyframe_timestamp_) {
591 next_buffer_index_ = buffers_.size() - 1; 649 next_buffer_index_ = buffers_.size() - 1;
592 next_keyframe_timestamp_ = base::TimeDelta(); 650 next_keyframe_timestamp_ = base::TimeDelta();
593 waiting_for_keyframe_ = false; 651 waiting_for_keyframe_ = false;
594 } 652 }
(...skipping 13 matching lines...) Expand all
608 // previous element if it did not return the element exactly equal to 666 // previous element if it did not return the element exactly equal to
609 // |timestamp|. 667 // |timestamp|.
610 if (result != keyframe_map_.begin() && 668 if (result != keyframe_map_.begin() &&
611 (result == keyframe_map_.end() || result->first != timestamp)) { 669 (result == keyframe_map_.end() || result->first != timestamp)) {
612 result--; 670 result--;
613 } 671 }
614 next_buffer_index_ = result->second; 672 next_buffer_index_ = result->second;
615 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 673 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
616 } 674 }
617 675
618 void SourceBufferRange::SeekAfter(base::TimeDelta timestamp) { 676 void SourceBufferRange::SeekAheadTo(base::TimeDelta timestamp) {
677 SeekAhead(timestamp, false);
678 }
679
680 void SourceBufferRange::SeekAheadPast(base::TimeDelta timestamp) {
681 SeekAhead(timestamp, true);
682 }
683
684 void SourceBufferRange::SeekAhead(base::TimeDelta timestamp,
685 bool skip_given_timestamp) {
619 DCHECK(!keyframe_map_.empty()); 686 DCHECK(!keyframe_map_.empty());
620 687
621 // lower_bound() returns the first element >= |timestamp|, so |result| is the 688 KeyframeMap::iterator result =
622 // value that we want. 689 GetFirstKeyframeAfter(timestamp, skip_given_timestamp);
623 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
624 690
625 // If there isn't a keyframe after |timestamp|, then seek to end and return 691 // If there isn't a keyframe after |timestamp|, then seek to end and return
626 // kNoTimestamp to signal such. 692 // kNoTimestamp to signal such.
627 if (result == keyframe_map_.end()) { 693 if (result == keyframe_map_.end()) {
628 waiting_for_keyframe_ = true; 694 waiting_for_keyframe_ = true;
629 next_buffer_index_ = -1; 695 next_buffer_index_ = -1;
630 next_keyframe_timestamp_ = timestamp; 696 next_keyframe_timestamp_ = timestamp;
631 return; 697 return;
632 } 698 }
633
634 next_buffer_index_ = result->second; 699 next_buffer_index_ = result->second;
635 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); 700 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
636 } 701 }
637 702
638 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { 703 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) {
639 // Find the first keyframe after |timestamp|. 704 // Find the first keyframe after |timestamp|, not including |timestamp|.
640 KeyframeMap::iterator new_beginning_keyframe = 705 KeyframeMap::iterator new_beginning_keyframe =
641 keyframe_map_.lower_bound(timestamp); 706 GetFirstKeyframeAfter(timestamp, true);
642 707
643 // If there is no keyframe after |timestamp|, we can't split the range. 708 // If there is no keyframe after |timestamp|, we can't split the range.
644 if (new_beginning_keyframe == keyframe_map_.end()) 709 if (new_beginning_keyframe == keyframe_map_.end())
645 return NULL; 710 return NULL;
646 711
647 // Remove the data beginning at |keyframe_index| from |buffers_| and save it 712 // Remove the data beginning at |keyframe_index| from |buffers_| and save it
648 // into |removed_buffers|. 713 // into |removed_buffers|.
649 int keyframe_index = new_beginning_keyframe->second; 714 int keyframe_index = new_beginning_keyframe->second;
650 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); 715 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
651 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; 716 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
652 BufferQueue removed_buffers(starting_point, buffers_.end()); 717 BufferQueue removed_buffers(starting_point, buffers_.end());
653 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end()); 718 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
654 buffers_.erase(starting_point, buffers_.end()); 719 buffers_.erase(starting_point, buffers_.end());
655 720
656 // Create a new range with |removed_buffers|. 721 // Create a new range with |removed_buffers|.
657 SourceBufferRange* split_range = 722 SourceBufferRange* split_range =
658 new SourceBufferRange(removed_buffers, kNoTimestamp()); 723 new SourceBufferRange(removed_buffers, kNoTimestamp());
659 724
660 // If |next_buffer_index_| points to a buffer in |split_range|, update the 725 // If |next_buffer_index_| points to a buffer in |split_range|, update the
661 // |next_buffer_index_| of this range and |split_range| accordingly. 726 // |next_buffer_index_| of this range and |split_range| accordingly.
662 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) { 727 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
663 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index; 728 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
664 next_buffer_index_ = -1; 729 next_buffer_index_ = -1;
665 } 730 }
666 return split_range; 731 return split_range;
667 } 732 }
668 733
669 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 734 SourceBufferRange::KeyframeMap::iterator
670 DeleteAfter(buffers_.begin(), removed_buffers); 735 SourceBufferRange::GetFirstKeyframeAfter(base::TimeDelta timestamp,
736 bool skip_given_timestamp) {
737 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
738 // lower_bound() returns the first element >= |timestamp|, so if we don't want
739 // to include keyframes == |timestamp|, we have to increment the iterator
740 // accordingly.
741 if (skip_given_timestamp &&
742 result != keyframe_map_.end() && result->first == timestamp) {
743 ++result;
744 }
745 return result;
671 } 746 }
672 747
673 void SourceBufferRange::DeleteAfter( 748 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
749 return TruncateAt(buffers_.begin(), removed_buffers);
750 }
751
752 bool SourceBufferRange::TruncateAt(
674 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { 753 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) {
675 // Find the place in |buffers_| where we will begin deleting data. 754 // Find the place in |buffers_| where we will begin deleting data.
676 BufferQueue::iterator starting_point = 755 BufferQueue::iterator starting_point =
677 std::lower_bound(buffers_.begin(), buffers_.end(), 756 std::lower_bound(buffers_.begin(), buffers_.end(),
678 buffer, 757 buffer,
679 BufferComparator); 758 BufferComparator);
680 DeleteAfter(starting_point, removed_buffers); 759 return TruncateAt(starting_point, removed_buffers);
681 } 760 }
682 761
683 void SourceBufferRange::DeleteAfter( 762 bool SourceBufferRange::TruncateAt(
684 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { 763 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) {
685 DCHECK(removed_buffers); 764 DCHECK(removed_buffers);
765 DCHECK(removed_buffers->empty());
766
686 // Return if we're not deleting anything. 767 // Return if we're not deleting anything.
687 if (starting_point == buffers_.end()) 768 if (starting_point == buffers_.end())
688 return; 769 return false;
689 770
771 bool removed_next_buffer = false;
690 // Reset the next buffer index if we will be deleting the buffer that's next 772 // Reset the next buffer index if we will be deleting the buffer that's next
691 // in sequence. 773 // in sequence.
692 if (HasNextBuffer() && 774 if (HasNextBufferPosition() &&
693 GetNextTimestamp() >= (*starting_point)->GetTimestamp()) { 775 GetNextTimestamp() >= (*starting_point)->GetTimestamp()) {
694 // Save the buffers we're about to delete if the output parameter is valid. 776 if (HasNextBuffer()) {
695 int starting_offset = starting_point - buffers_.begin(); 777 int starting_offset = starting_point - buffers_.begin();
696 int next_buffer_offset = next_buffer_index_ - starting_offset; 778 int next_buffer_offset = next_buffer_index_ - starting_offset;
697 DCHECK_GE(next_buffer_offset, 0); 779 DCHECK_GE(next_buffer_offset, 0);
698 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); 780 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end());
699 removed_buffers->swap(saved); 781 removed_buffers->swap(saved);
782 }
700 next_buffer_index_ = -1; 783 next_buffer_index_ = -1;
784 removed_next_buffer = true;
701 } 785 }
702 786
703 // Remove keyframes from |starting_point| onward. 787 // Remove keyframes from |starting_point| onward.
704 KeyframeMap::iterator starting_point_keyframe = 788 KeyframeMap::iterator starting_point_keyframe =
705 keyframe_map_.lower_bound((*starting_point)->GetTimestamp()); 789 keyframe_map_.lower_bound((*starting_point)->GetTimestamp());
706 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end()); 790 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end());
707 791
708 // Remove everything from |starting_point| onward. 792 // Remove everything from |starting_point| onward.
709 buffers_.erase(starting_point, buffers_.end()); 793 buffers_.erase(starting_point, buffers_.end());
794 return removed_next_buffer;
710 } 795 }
711 796
712 bool SourceBufferRange::GetNextBuffer( 797 bool SourceBufferRange::GetNextBuffer(
713 scoped_refptr<StreamParserBuffer>* out_buffer) { 798 scoped_refptr<StreamParserBuffer>* out_buffer) {
714 if (waiting_for_keyframe_ || 799 if (waiting_for_keyframe_ ||
715 next_buffer_index_ >= static_cast<int>(buffers_.size())) { 800 next_buffer_index_ >= static_cast<int>(buffers_.size())) {
716 return false; 801 return false;
717 } 802 }
718 803
719 DCHECK_GE(next_buffer_index_, 0); 804 DCHECK_GE(next_buffer_index_, 0);
720 *out_buffer = buffers_.at(next_buffer_index_); 805 *out_buffer = buffers_.at(next_buffer_index_);
721 next_buffer_index_++; 806 next_buffer_index_++;
722 return true; 807 return true;
723 } 808 }
724 809
725 bool SourceBufferRange::HasNextBuffer() const { 810 bool SourceBufferRange::HasNextBuffer() const {
726 return next_buffer_index_ >= 0 && 811 return next_buffer_index_ >= 0 &&
727 next_buffer_index_ < static_cast<int>(buffers_.size()); 812 next_buffer_index_ < static_cast<int>(buffers_.size());
728 } 813 }
729 814
730 base::TimeDelta SourceBufferRange::GetNextTimestamp() const { 815 base::TimeDelta SourceBufferRange::GetNextTimestamp() const {
731 DCHECK(!buffers_.empty()); 816 DCHECK(!buffers_.empty());
732 DCHECK(HasNextBufferPosition()); 817 DCHECK(HasNextBufferPosition());
733 818
734 if (waiting_for_keyframe_) 819 if (waiting_for_keyframe_)
735 return next_keyframe_timestamp_; 820 return next_keyframe_timestamp_;
736 821
737 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) 822 if (next_buffer_index_ >= static_cast<int>(buffers_.size()))
738 return buffers_.back()->GetEndTimestamp(); 823 return buffers_.back()->GetTimestamp();
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 Why is this ok? Wouldn't we want to use fudge room
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Talked offline, returning kNoTimestamp() instead a
739 824
740 return buffers_.at(next_buffer_index_)->GetTimestamp(); 825 return buffers_.at(next_buffer_index_)->GetTimestamp();
741 } 826 }
742 827
743 bool SourceBufferRange::HasNextBufferPosition() const { 828 bool SourceBufferRange::HasNextBufferPosition() const {
744 return next_buffer_index_ >= 0 || waiting_for_keyframe_; 829 return next_buffer_index_ >= 0 || waiting_for_keyframe_;
745 } 830 }
746 831
747 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, 832 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range,
748 bool transfer_current_position) { 833 bool transfer_current_position) {
(...skipping 16 matching lines...) Expand all
765 } 850 }
766 851
767 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const { 852 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const {
768 DCHECK(!buffers_.empty()); 853 DCHECK(!buffers_.empty());
769 854
770 return (IsNextInSequence(buffers_.back(), timestamp) || 855 return (IsNextInSequence(buffers_.back(), timestamp) ||
771 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp())); 856 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
772 } 857 }
773 858
774 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const { 859 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const {
775 return !keyframe_map_.empty() && GetStartTimestamp() <= timestamp && 860 base::TimeDelta start_range =
776 GetEndTimestamp() > timestamp; 861 std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom());
862 return !keyframe_map_.empty() && start_range <= timestamp &&
863 timestamp <= GetEndTimestamp();
777 } 864 }
778 865
779 bool SourceBufferRange::CompletelyOverlaps( 866 bool SourceBufferRange::CompletelyOverlaps(
780 const SourceBufferRange& range) const { 867 const SourceBufferRange& range) const {
781 return GetStartTimestamp() <= range.GetStartTimestamp() && 868 return GetStartTimestamp() <= range.GetStartTimestamp() &&
782 GetEndTimestamp() >= range.GetEndTimestamp(); 869 GetEndTimestamp() >= range.GetEndTimestamp();
783 } 870 }
784 871
785 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const { 872 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
786 return range.GetStartTimestamp() < GetEndTimestamp() && 873 return range.GetStartTimestamp() <= GetEndTimestamp() &&
787 GetEndTimestamp() < range.GetEndTimestamp(); 874 GetEndTimestamp() < range.GetEndTimestamp();
788 } 875 }
789 876
790 base::TimeDelta SourceBufferRange::GetStartTimestamp() const { 877 base::TimeDelta SourceBufferRange::GetStartTimestamp() const {
791 DCHECK(!buffers_.empty()); 878 DCHECK(!buffers_.empty());
792 base::TimeDelta start_timestamp = media_segment_start_time_; 879 base::TimeDelta start_timestamp = media_segment_start_time_;
793 if (start_timestamp == kNoTimestamp()) 880 if (start_timestamp == kNoTimestamp())
794 start_timestamp = buffers_.front()->GetTimestamp(); 881 start_timestamp = buffers_.front()->GetTimestamp();
795 return start_timestamp; 882 return start_timestamp;
796 } 883 }
797 884
798 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { 885 base::TimeDelta SourceBufferRange::GetEndTimestamp() const {
799 DCHECK(!buffers_.empty()); 886 DCHECK(!buffers_.empty());
800 return buffers_.back()->GetEndTimestamp(); 887 return buffers_.back()->GetTimestamp();
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 Shouldn't we be using fudge here?
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 I avoided it here because this was being used in t
888 }
889
890 bool SourceBufferRange::IsNextInSequence(
891 const scoped_refptr<media::StreamParserBuffer>& buffer,
892 base::TimeDelta timestamp) const {
893 return buffer->GetTimestamp() < timestamp &&
894 timestamp <= buffer->GetTimestamp() + GetFudgeRoom();
895 }
896
897 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
898 // Use a constant default fudge room of 250ms if we've seen fewer than 2
899 // buffers in this range.
900 base::TimeDelta fudge = base::TimeDelta::FromMilliseconds(250);
901
902 // Because we do not know exactly when is the next timestamp, any buffer
903 // that starts within 2x the |max_interbuffer_distance_| seen so far in this
904 // range is considered the next buffer in the sequence.
905 if (max_interbuffer_distance_ != kNoTimestamp())
acolwell GONE FROM CHROMIUM 2012/07/02 17:12:33 nit: Reverse check and early return default then j
vrk (LEFT CHROMIUM) 2012/07/04 02:50:18 Done.
906 fudge = 2 * max_interbuffer_distance_;
907 return fudge;
801 } 908 }
802 909
803 } // namespace media 910 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698