OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_range.h" | 5 #include "media/filters/source_buffer_range.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 namespace media { | 9 namespace media { |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 media_segment_start_time_ <= | 49 media_segment_start_time_ <= |
50 new_buffers.front()->GetDecodeTimestamp()); | 50 new_buffers.front()->GetDecodeTimestamp()); |
51 | 51 |
52 AdjustEstimatedDurationForNewAppend(new_buffers); | 52 AdjustEstimatedDurationForNewAppend(new_buffers); |
53 | 53 |
54 for (BufferQueue::const_iterator itr = new_buffers.begin(); | 54 for (BufferQueue::const_iterator itr = new_buffers.begin(); |
55 itr != new_buffers.end(); | 55 itr != new_buffers.end(); |
56 ++itr) { | 56 ++itr) { |
57 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); | 57 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp()); |
58 buffers_.push_back(*itr); | 58 buffers_.push_back(*itr); |
59 size_in_bytes_ += (*itr)->data_size(); | 59 size_in_bytes_ += (*itr)->data_size(); |
wolenetz
2015/07/20 19:29:42
nit: ISTM the DCHECK would be good here, too.
Fix
servolk
2015/07/22 19:02:11
Yes, DecoderBuffer::Initialize already has CHECK_G
| |
60 | 60 |
61 if ((*itr)->is_key_frame()) { | 61 if ((*itr)->is_key_frame()) { |
62 keyframe_map_.insert( | 62 keyframe_map_.insert( |
63 std::make_pair((*itr)->GetDecodeTimestamp(), | 63 std::make_pair((*itr)->GetDecodeTimestamp(), |
64 buffers_.size() - 1 + keyframe_map_index_base_)); | 64 buffers_.size() - 1 + keyframe_map_index_base_)); |
65 } | 65 } |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 void SourceBufferRange::AdjustEstimatedDurationForNewAppend( | 69 void SourceBufferRange::AdjustEstimatedDurationForNewAppend( |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 | 218 |
219 bool SourceBufferRange::TruncateAt( | 219 bool SourceBufferRange::TruncateAt( |
220 DecodeTimestamp timestamp, BufferQueue* removed_buffers, | 220 DecodeTimestamp timestamp, BufferQueue* removed_buffers, |
221 bool is_exclusive) { | 221 bool is_exclusive) { |
222 // Find the place in |buffers_| where we will begin deleting data. | 222 // Find the place in |buffers_| where we will begin deleting data. |
223 BufferQueue::iterator starting_point = | 223 BufferQueue::iterator starting_point = |
224 GetBufferItrAt(timestamp, is_exclusive); | 224 GetBufferItrAt(timestamp, is_exclusive); |
225 return TruncateAt(starting_point, removed_buffers); | 225 return TruncateAt(starting_point, removed_buffers); |
226 } | 226 } |
227 | 227 |
228 int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) { | 228 size_t SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) { |
229 DCHECK(!FirstGOPContainsNextBufferPosition()); | 229 DCHECK(!FirstGOPContainsNextBufferPosition()); |
230 DCHECK(deleted_buffers); | 230 DCHECK(deleted_buffers); |
231 | 231 |
232 int buffers_deleted = 0; | 232 int buffers_deleted = 0; |
233 int total_bytes_deleted = 0; | 233 size_t total_bytes_deleted = 0; |
234 | 234 |
235 KeyframeMap::iterator front = keyframe_map_.begin(); | 235 KeyframeMap::iterator front = keyframe_map_.begin(); |
236 DCHECK(front != keyframe_map_.end()); | 236 DCHECK(front != keyframe_map_.end()); |
237 | 237 |
238 // Delete the keyframe at the start of |keyframe_map_|. | 238 // Delete the keyframe at the start of |keyframe_map_|. |
239 keyframe_map_.erase(front); | 239 keyframe_map_.erase(front); |
240 | 240 |
241 // Now we need to delete all the buffers that depend on the keyframe we've | 241 // Now we need to delete all the buffers that depend on the keyframe we've |
242 // just deleted. | 242 // just deleted. |
243 int end_index = keyframe_map_.size() > 0 ? | 243 int end_index = keyframe_map_.size() > 0 ? |
244 keyframe_map_.begin()->second - keyframe_map_index_base_ : | 244 keyframe_map_.begin()->second - keyframe_map_index_base_ : |
245 buffers_.size(); | 245 buffers_.size(); |
246 | 246 |
247 // Delete buffers from the beginning of the buffered range up until (but not | 247 // Delete buffers from the beginning of the buffered range up until (but not |
248 // including) the next keyframe. | 248 // including) the next keyframe. |
249 for (int i = 0; i < end_index; i++) { | 249 for (int i = 0; i < end_index; i++) { |
250 int bytes_deleted = buffers_.front()->data_size(); | 250 DCHECK_GE(buffers_.front()->data_size(), 0); |
251 size_t bytes_deleted = buffers_.front()->data_size(); | |
252 DCHECK_GE(size_in_bytes_, bytes_deleted); | |
251 size_in_bytes_ -= bytes_deleted; | 253 size_in_bytes_ -= bytes_deleted; |
252 total_bytes_deleted += bytes_deleted; | 254 total_bytes_deleted += bytes_deleted; |
253 deleted_buffers->push_back(buffers_.front()); | 255 deleted_buffers->push_back(buffers_.front()); |
254 buffers_.pop_front(); | 256 buffers_.pop_front(); |
255 ++buffers_deleted; | 257 ++buffers_deleted; |
256 } | 258 } |
257 | 259 |
258 // Update |keyframe_map_index_base_| to account for the deleted buffers. | 260 // Update |keyframe_map_index_base_| to account for the deleted buffers. |
259 keyframe_map_index_base_ += buffers_deleted; | 261 keyframe_map_index_base_ += buffers_deleted; |
260 | 262 |
261 if (next_buffer_index_ > -1) { | 263 if (next_buffer_index_ > -1) { |
262 next_buffer_index_ -= buffers_deleted; | 264 next_buffer_index_ -= buffers_deleted; |
263 DCHECK_GE(next_buffer_index_, 0); | 265 DCHECK_GE(next_buffer_index_, 0); |
264 } | 266 } |
265 | 267 |
266 // Invalidate media segment start time if we've deleted the first buffer of | 268 // Invalidate media segment start time if we've deleted the first buffer of |
267 // the range. | 269 // the range. |
268 if (buffers_deleted > 0) | 270 if (buffers_deleted > 0) |
269 media_segment_start_time_ = kNoDecodeTimestamp(); | 271 media_segment_start_time_ = kNoDecodeTimestamp(); |
270 | 272 |
271 return total_bytes_deleted; | 273 return total_bytes_deleted; |
272 } | 274 } |
273 | 275 |
274 int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { | 276 size_t SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) { |
275 DCHECK(!LastGOPContainsNextBufferPosition()); | 277 DCHECK(!LastGOPContainsNextBufferPosition()); |
276 DCHECK(deleted_buffers); | 278 DCHECK(deleted_buffers); |
277 | 279 |
278 // Remove the last GOP's keyframe from the |keyframe_map_|. | 280 // Remove the last GOP's keyframe from the |keyframe_map_|. |
279 KeyframeMap::iterator back = keyframe_map_.end(); | 281 KeyframeMap::iterator back = keyframe_map_.end(); |
280 DCHECK_GT(keyframe_map_.size(), 0u); | 282 DCHECK_GT(keyframe_map_.size(), 0u); |
281 --back; | 283 --back; |
282 | 284 |
283 // The index of the first buffer in the last GOP is equal to the new size of | 285 // The index of the first buffer in the last GOP is equal to the new size of |
284 // |buffers_| after that GOP is deleted. | 286 // |buffers_| after that GOP is deleted. |
285 size_t goal_size = back->second - keyframe_map_index_base_; | 287 size_t goal_size = back->second - keyframe_map_index_base_; |
286 keyframe_map_.erase(back); | 288 keyframe_map_.erase(back); |
287 | 289 |
288 int total_bytes_deleted = 0; | 290 size_t total_bytes_deleted = 0; |
289 while (buffers_.size() != goal_size) { | 291 while (buffers_.size() != goal_size) { |
290 int bytes_deleted = buffers_.back()->data_size(); | 292 DCHECK_GE(buffers_.back()->data_size(), 0); |
293 size_t bytes_deleted = buffers_.back()->data_size(); | |
294 DCHECK_GE(size_in_bytes_, bytes_deleted); | |
291 size_in_bytes_ -= bytes_deleted; | 295 size_in_bytes_ -= bytes_deleted; |
292 total_bytes_deleted += bytes_deleted; | 296 total_bytes_deleted += bytes_deleted; |
293 // We're removing buffers from the back, so push each removed buffer to the | 297 // We're removing buffers from the back, so push each removed buffer to the |
294 // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing | 298 // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing |
295 // order. | 299 // order. |
296 deleted_buffers->push_front(buffers_.back()); | 300 deleted_buffers->push_front(buffers_.back()); |
297 buffers_.pop_back(); | 301 buffers_.pop_back(); |
298 } | 302 } |
299 | 303 |
300 return total_bytes_deleted; | 304 return total_bytes_deleted; |
301 } | 305 } |
302 | 306 |
303 int SourceBufferRange::GetRemovalGOP( | 307 size_t SourceBufferRange::GetRemovalGOP( |
304 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, | 308 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, |
305 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { | 309 size_t total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { |
306 int bytes_to_free = total_bytes_to_free; | 310 size_t bytes_removed = 0; |
307 int bytes_removed = 0; | |
308 | 311 |
309 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); | 312 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false); |
310 if (gop_itr == keyframe_map_.end()) | 313 if (gop_itr == keyframe_map_.end()) |
311 return 0; | 314 return 0; |
312 int keyframe_index = gop_itr->second - keyframe_map_index_base_; | 315 int keyframe_index = gop_itr->second - keyframe_map_index_base_; |
313 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; | 316 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index; |
314 KeyframeMap::iterator gop_end = keyframe_map_.end(); | 317 KeyframeMap::iterator gop_end = keyframe_map_.end(); |
315 if (end_timestamp < GetBufferedEndTimestamp()) | 318 if (end_timestamp < GetBufferedEndTimestamp()) |
316 gop_end = GetFirstKeyframeAtOrBefore(end_timestamp); | 319 gop_end = GetFirstKeyframeAtOrBefore(end_timestamp); |
317 | 320 |
318 // Check if the removal range is within a GOP and skip the loop if so. | 321 // Check if the removal range is within a GOP and skip the loop if so. |
319 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] | 322 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe] |
320 KeyframeMap::iterator gop_itr_prev = gop_itr; | 323 KeyframeMap::iterator gop_itr_prev = gop_itr; |
321 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) | 324 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end) |
322 gop_end = gop_itr; | 325 gop_end = gop_itr; |
323 | 326 |
324 while (gop_itr != gop_end && bytes_to_free > 0) { | 327 while (gop_itr != gop_end && bytes_removed < total_bytes_to_free) { |
325 ++gop_itr; | 328 ++gop_itr; |
326 | 329 |
327 int gop_size = 0; | 330 size_t gop_size = 0; |
328 int next_gop_index = gop_itr == keyframe_map_.end() ? | 331 int next_gop_index = gop_itr == keyframe_map_.end() ? |
329 buffers_.size() : gop_itr->second - keyframe_map_index_base_; | 332 buffers_.size() : gop_itr->second - keyframe_map_index_base_; |
330 BufferQueue::iterator next_gop_start = buffers_.begin() + next_gop_index; | 333 BufferQueue::iterator next_gop_start = buffers_.begin() + next_gop_index; |
331 for (; buffer_itr != next_gop_start; ++buffer_itr) | 334 for (; buffer_itr != next_gop_start; ++buffer_itr) { |
335 DCHECK_GE((*buffer_itr)->data_size(), 0); | |
332 gop_size += (*buffer_itr)->data_size(); | 336 gop_size += (*buffer_itr)->data_size(); |
337 } | |
333 | 338 |
334 bytes_removed += gop_size; | 339 bytes_removed += gop_size; |
335 bytes_to_free -= gop_size; | |
336 } | 340 } |
337 if (bytes_removed > 0) { | 341 if (bytes_removed > 0) { |
338 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? | 342 *removal_end_timestamp = gop_itr == keyframe_map_.end() ? |
339 GetBufferedEndTimestamp() : gop_itr->first; | 343 GetBufferedEndTimestamp() : gop_itr->first; |
340 } | 344 } |
341 return bytes_removed; | 345 return bytes_removed; |
342 } | 346 } |
343 | 347 |
344 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { | 348 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const { |
345 if (!HasNextBufferPosition()) | 349 if (!HasNextBufferPosition()) |
(...skipping 19 matching lines...) Expand all Loading... | |
365 KeyframeMap::const_iterator last_gop = keyframe_map_.end(); | 369 KeyframeMap::const_iterator last_gop = keyframe_map_.end(); |
366 --last_gop; | 370 --last_gop; |
367 return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_; | 371 return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_; |
368 } | 372 } |
369 | 373 |
370 void SourceBufferRange::FreeBufferRange( | 374 void SourceBufferRange::FreeBufferRange( |
371 const BufferQueue::iterator& starting_point, | 375 const BufferQueue::iterator& starting_point, |
372 const BufferQueue::iterator& ending_point) { | 376 const BufferQueue::iterator& ending_point) { |
373 for (BufferQueue::iterator itr = starting_point; | 377 for (BufferQueue::iterator itr = starting_point; |
374 itr != ending_point; ++itr) { | 378 itr != ending_point; ++itr) { |
375 size_in_bytes_ -= (*itr)->data_size(); | 379 DCHECK_GE((*itr)->data_size(), 0); |
ddorwin
2015/07/20 21:23:57
Should BufferQueue also be fixed in a separate CL?
servolk
2015/07/22 19:02:11
BufferQueue is just a typedef for a collection of
| |
376 DCHECK_GE(size_in_bytes_, 0); | 380 size_t itr_data_size = static_cast<size_t>((*itr)->data_size()); |
ddorwin
2015/07/20 21:23:57
Does this value always come from internal code or
servolk
2015/07/22 19:02:11
It comes from StreamParserBuffer::data_size.
I thi
| |
381 DCHECK_GE(size_in_bytes_, itr_data_size); | |
382 size_in_bytes_ -= itr_data_size; | |
377 } | 383 } |
378 buffers_.erase(starting_point, ending_point); | 384 buffers_.erase(starting_point, ending_point); |
379 } | 385 } |
380 | 386 |
381 bool SourceBufferRange::TruncateAt( | 387 bool SourceBufferRange::TruncateAt( |
382 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { | 388 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { |
383 DCHECK(!removed_buffers || removed_buffers->empty()); | 389 DCHECK(!removed_buffers || removed_buffers->empty()); |
384 | 390 |
385 // Return if we're not deleting anything. | 391 // Return if we're not deleting anything. |
386 if (starting_point == buffers_.end()) | 392 if (starting_point == buffers_.end()) |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 } | 613 } |
608 | 614 |
609 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) | 615 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime()) |
610 continue; | 616 continue; |
611 buffers->push_back(buffer); | 617 buffers->push_back(buffer); |
612 } | 618 } |
613 return previous_size < buffers->size(); | 619 return previous_size < buffers->size(); |
614 } | 620 } |
615 | 621 |
616 } // namespace media | 622 } // namespace media |
OLD | NEW |