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

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

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