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

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

Powered by Google App Engine
This is Rietveld 408576698