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

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

Powered by Google App Engine
This is Rietveld 408576698