OLD | NEW |
---|---|
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/bind.h" |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 : log_cb_(log_cb), | 293 : log_cb_(log_cb), |
294 current_config_index_(0), | 294 current_config_index_(0), |
295 append_config_index_(0), | 295 append_config_index_(0), |
296 seek_pending_(false), | 296 seek_pending_(false), |
297 seek_buffer_timestamp_(kNoTimestamp()), | 297 seek_buffer_timestamp_(kNoTimestamp()), |
298 selected_range_(NULL), | 298 selected_range_(NULL), |
299 media_segment_start_time_(kNoTimestamp()), | 299 media_segment_start_time_(kNoTimestamp()), |
300 range_for_next_append_(ranges_.end()), | 300 range_for_next_append_(ranges_.end()), |
301 new_media_segment_(false), | 301 new_media_segment_(false), |
302 last_appended_buffer_timestamp_(kNoTimestamp()), | 302 last_appended_buffer_timestamp_(kNoTimestamp()), |
303 last_appended_buffer_is_keyframe_(false), | |
303 last_output_buffer_timestamp_(kNoTimestamp()), | 304 last_output_buffer_timestamp_(kNoTimestamp()), |
304 max_interbuffer_distance_(kNoTimestamp()), | 305 max_interbuffer_distance_(kNoTimestamp()), |
305 memory_limit_(kDefaultAudioMemoryLimit), | 306 memory_limit_(kDefaultAudioMemoryLimit), |
306 config_change_pending_(false) { | 307 config_change_pending_(false) { |
307 DCHECK(audio_config.IsValidConfig()); | 308 DCHECK(audio_config.IsValidConfig()); |
308 audio_configs_.push_back(new AudioDecoderConfig()); | 309 audio_configs_.push_back(new AudioDecoderConfig()); |
309 audio_configs_.back()->CopyFrom(audio_config); | 310 audio_configs_.back()->CopyFrom(audio_config); |
310 } | 311 } |
311 | 312 |
312 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, | 313 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config, |
313 const LogCB& log_cb) | 314 const LogCB& log_cb) |
314 : log_cb_(log_cb), | 315 : log_cb_(log_cb), |
315 current_config_index_(0), | 316 current_config_index_(0), |
316 append_config_index_(0), | 317 append_config_index_(0), |
317 seek_pending_(false), | 318 seek_pending_(false), |
318 seek_buffer_timestamp_(kNoTimestamp()), | 319 seek_buffer_timestamp_(kNoTimestamp()), |
319 selected_range_(NULL), | 320 selected_range_(NULL), |
320 media_segment_start_time_(kNoTimestamp()), | 321 media_segment_start_time_(kNoTimestamp()), |
321 range_for_next_append_(ranges_.end()), | 322 range_for_next_append_(ranges_.end()), |
322 new_media_segment_(false), | 323 new_media_segment_(false), |
323 last_appended_buffer_timestamp_(kNoTimestamp()), | 324 last_appended_buffer_timestamp_(kNoTimestamp()), |
325 last_appended_buffer_is_keyframe_(false), | |
324 last_output_buffer_timestamp_(kNoTimestamp()), | 326 last_output_buffer_timestamp_(kNoTimestamp()), |
325 max_interbuffer_distance_(kNoTimestamp()), | 327 max_interbuffer_distance_(kNoTimestamp()), |
326 memory_limit_(kDefaultVideoMemoryLimit), | 328 memory_limit_(kDefaultVideoMemoryLimit), |
327 config_change_pending_(false) { | 329 config_change_pending_(false) { |
328 DCHECK(video_config.IsValidConfig()); | 330 DCHECK(video_config.IsValidConfig()); |
329 video_configs_.push_back(new VideoDecoderConfig()); | 331 video_configs_.push_back(new VideoDecoderConfig()); |
330 video_configs_.back()->CopyFrom(video_config); | 332 video_configs_.back()->CopyFrom(video_config); |
331 } | 333 } |
332 | 334 |
333 SourceBufferStream::~SourceBufferStream() { | 335 SourceBufferStream::~SourceBufferStream() { |
(...skipping 13 matching lines...) Expand all Loading... | |
347 | 349 |
348 RangeList::iterator last_range = range_for_next_append_; | 350 RangeList::iterator last_range = range_for_next_append_; |
349 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 351 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
350 | 352 |
351 // Only reset |last_appended_buffer_timestamp_| if this new media segment is | 353 // Only reset |last_appended_buffer_timestamp_| if this new media segment is |
352 // not adjacent to the previous media segment appended to the stream. | 354 // not adjacent to the previous media segment appended to the stream. |
353 if (range_for_next_append_ == ranges_.end() || | 355 if (range_for_next_append_ == ranges_.end() || |
354 !AreAdjacentInSequence(last_appended_buffer_timestamp_, | 356 !AreAdjacentInSequence(last_appended_buffer_timestamp_, |
355 media_segment_start_time)) { | 357 media_segment_start_time)) { |
356 last_appended_buffer_timestamp_ = kNoTimestamp(); | 358 last_appended_buffer_timestamp_ = kNoTimestamp(); |
359 last_appended_buffer_is_keyframe_ = false; | |
357 } else { | 360 } else { |
358 DCHECK(last_range == range_for_next_append_); | 361 DCHECK(last_range == range_for_next_append_); |
359 } | 362 } |
360 } | 363 } |
361 | 364 |
362 bool SourceBufferStream::Append( | 365 bool SourceBufferStream::Append( |
363 const SourceBufferStream::BufferQueue& buffers) { | 366 const SourceBufferStream::BufferQueue& buffers) { |
364 TRACE_EVENT2("mse", "SourceBufferStream::Append", | 367 TRACE_EVENT2("mse", "SourceBufferStream::Append", |
365 "stream type", GetStreamTypeName(), | 368 "stream type", GetStreamTypeName(), |
366 "buffers to append", buffers.size()); | 369 "buffers to append", buffers.size()); |
367 | 370 |
368 DCHECK(!buffers.empty()); | 371 DCHECK(!buffers.empty()); |
369 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 372 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
370 | 373 |
371 // New media segments must begin with a keyframe. | 374 // New media segments must begin with a keyframe. |
372 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { | 375 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { |
373 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe."; | 376 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe."; |
374 return false; | 377 return false; |
375 } | 378 } |
376 | 379 |
377 // Buffers within a media segment should be monotonically increasing. | 380 // Buffers within a media segment should be monotonically increasing. |
378 if (!IsMonotonicallyIncreasing(buffers)) { | 381 if (!IsMonotonicallyIncreasing(buffers)) |
379 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; | |
380 return false; | 382 return false; |
381 } | |
382 | 383 |
383 if (media_segment_start_time_ < base::TimeDelta() || | 384 if (media_segment_start_time_ < base::TimeDelta() || |
384 buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { | 385 buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) { |
385 MEDIA_LOG(log_cb_) | 386 MEDIA_LOG(log_cb_) |
386 << "Cannot append a media segment with negative timestamps."; | 387 << "Cannot append a media segment with negative timestamps."; |
387 return false; | 388 return false; |
388 } | 389 } |
389 | 390 |
390 UpdateMaxInterbufferDistance(buffers); | 391 UpdateMaxInterbufferDistance(buffers); |
391 SetConfigIds(buffers); | 392 SetConfigIds(buffers); |
392 | 393 |
393 // Save a snapshot of stream state before range modifications are made. | 394 // Save a snapshot of stream state before range modifications are made. |
394 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); | 395 base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp(); |
395 BufferQueue deleted_buffers; | 396 BufferQueue deleted_buffers; |
396 | 397 |
397 RangeList::iterator range_for_new_buffers = range_for_next_append_; | 398 RangeList::iterator range_for_new_buffers = range_for_next_append_; |
398 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 399 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
399 // create a new range with |buffers|. | 400 // create a new range with |buffers|. |
400 if (range_for_new_buffers != ranges_.end()) { | 401 if (range_for_new_buffers != ranges_.end()) { |
401 InsertIntoExistingRange(range_for_new_buffers, buffers, &deleted_buffers); | 402 if (!InsertIntoExistingRange(range_for_new_buffers, buffers, |
403 &deleted_buffers)) { | |
404 return false; | |
405 } | |
402 } else { | 406 } else { |
403 DCHECK(new_media_segment_); | 407 DCHECK(new_media_segment_); |
404 range_for_new_buffers = | 408 range_for_new_buffers = |
405 AddToRanges(new SourceBufferRange( | 409 AddToRanges(new SourceBufferRange( |
406 buffers, media_segment_start_time_, | 410 buffers, media_segment_start_time_, |
407 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, | 411 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
408 base::Unretained(this)))); | 412 base::Unretained(this)))); |
409 } | 413 } |
410 | 414 |
411 range_for_next_append_ = range_for_new_buffers; | 415 range_for_next_append_ = range_for_new_buffers; |
412 new_media_segment_ = false; | 416 new_media_segment_ = false; |
413 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 417 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
418 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); | |
414 | 419 |
415 // Resolve overlaps. | 420 // Resolve overlaps. |
416 ResolveCompleteOverlaps(range_for_new_buffers, &deleted_buffers); | 421 ResolveCompleteOverlaps(range_for_new_buffers, &deleted_buffers); |
417 ResolveEndOverlap(range_for_new_buffers, &deleted_buffers); | 422 ResolveEndOverlap(range_for_new_buffers, &deleted_buffers); |
418 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); | 423 MergeWithAdjacentRangeIfNecessary(range_for_new_buffers); |
419 | 424 |
420 // Seek to try to fulfill a previous call to Seek(). | 425 // Seek to try to fulfill a previous call to Seek(). |
421 if (seek_pending_) { | 426 if (seek_pending_) { |
422 DCHECK(!selected_range_); | 427 DCHECK(!selected_range_); |
423 DCHECK(deleted_buffers.empty()); | 428 DCHECK(deleted_buffers.empty()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 base::TimeDelta beginning_of_buffered = | 475 base::TimeDelta beginning_of_buffered = |
471 ranges_.front()->GetStartTimestamp(); | 476 ranges_.front()->GetStartTimestamp(); |
472 return (seek_timestamp <= beginning_of_buffered && | 477 return (seek_timestamp <= beginning_of_buffered && |
473 beginning_of_buffered < kSeekToStartFudgeRoom()); | 478 beginning_of_buffered < kSeekToStartFudgeRoom()); |
474 } | 479 } |
475 | 480 |
476 bool SourceBufferStream::IsMonotonicallyIncreasing( | 481 bool SourceBufferStream::IsMonotonicallyIncreasing( |
477 const BufferQueue& buffers) const { | 482 const BufferQueue& buffers) const { |
478 DCHECK(!buffers.empty()); | 483 DCHECK(!buffers.empty()); |
479 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; | 484 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; |
485 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | |
480 for (BufferQueue::const_iterator itr = buffers.begin(); | 486 for (BufferQueue::const_iterator itr = buffers.begin(); |
481 itr != buffers.end(); ++itr) { | 487 itr != buffers.end(); ++itr) { |
482 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); | 488 base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp(); |
489 bool current_is_keyframe = (*itr)->IsKeyframe(); | |
483 DCHECK(current_timestamp != kNoTimestamp()); | 490 DCHECK(current_timestamp != kNoTimestamp()); |
484 | 491 |
485 if (prev_timestamp != kNoTimestamp() && current_timestamp < prev_timestamp) | 492 if (prev_timestamp != kNoTimestamp()) { |
486 return false; | 493 if (current_timestamp < prev_timestamp) { |
494 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; | |
495 return false; | |
496 } | |
497 | |
498 if (current_timestamp == prev_timestamp && | |
499 (current_is_keyframe || prev_is_keyframe)) { | |
500 MEDIA_LOG(log_cb_) << "Invalid alt-ref frame construct detected at " | |
501 << current_timestamp.InSecondsF(); | |
502 return false; | |
503 } | |
504 } | |
487 | 505 |
488 prev_timestamp = current_timestamp; | 506 prev_timestamp = current_timestamp; |
507 prev_is_keyframe = current_is_keyframe; | |
489 } | 508 } |
490 return true; | 509 return true; |
491 } | 510 } |
492 | 511 |
493 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { | 512 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const { |
494 for (RangeList::const_iterator itr = ranges_.begin(); | 513 for (RangeList::const_iterator itr = ranges_.begin(); |
495 itr != ranges_.end(); ++itr) { | 514 itr != ranges_.end(); ++itr) { |
496 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) | 515 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_) |
497 return false; | 516 return false; |
498 } | 517 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 if (range_for_next_append_ != ranges_.begin()) { | 640 if (range_for_next_append_ != ranges_.begin()) { |
622 RangeList::iterator range_before_next = range_for_next_append_; | 641 RangeList::iterator range_before_next = range_for_next_append_; |
623 --range_before_next; | 642 --range_before_next; |
624 MergeWithAdjacentRangeIfNecessary(range_before_next); | 643 MergeWithAdjacentRangeIfNecessary(range_before_next); |
625 } | 644 } |
626 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); | 645 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); |
627 } | 646 } |
628 return bytes_freed; | 647 return bytes_freed; |
629 } | 648 } |
630 | 649 |
631 void SourceBufferStream::InsertIntoExistingRange( | 650 bool SourceBufferStream::InsertIntoExistingRange( |
632 const RangeList::iterator& range_for_new_buffers_itr, | 651 const RangeList::iterator& range_for_new_buffers_itr, |
633 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { | 652 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) { |
634 DCHECK(deleted_buffers); | 653 DCHECK(deleted_buffers); |
635 | 654 |
636 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 655 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
637 | 656 |
638 bool temporarily_select_range = false; | 657 bool temporarily_select_range = false; |
639 if (!track_buffer_.empty()) { | 658 if (!track_buffer_.empty()) { |
640 base::TimeDelta tb_timestamp = track_buffer_.back()->GetDecodeTimestamp(); | 659 base::TimeDelta tb_timestamp = track_buffer_.back()->GetDecodeTimestamp(); |
641 base::TimeDelta seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp); | 660 base::TimeDelta seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp); |
642 if (seek_timestamp != kNoTimestamp() && | 661 if (seek_timestamp != kNoTimestamp() && |
643 seek_timestamp < new_buffers.front()->GetDecodeTimestamp() && | 662 seek_timestamp < new_buffers.front()->GetDecodeTimestamp() && |
644 range_for_new_buffers->BelongsToRange(seek_timestamp)) { | 663 range_for_new_buffers->BelongsToRange(seek_timestamp)) { |
645 DCHECK(tb_timestamp < seek_timestamp); | 664 DCHECK(tb_timestamp < seek_timestamp); |
646 DCHECK(!selected_range_); | 665 DCHECK(!selected_range_); |
647 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); | 666 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); |
648 | 667 |
649 // If there are GOPs between the end of the track buffer and the | 668 // If there are GOPs between the end of the track buffer and the |
650 // beginning of the new buffers, then temporarily seek the range | 669 // beginning of the new buffers, then temporarily seek the range |
651 // so that the buffers between these two times will be deposited in | 670 // so that the buffers between these two times will be deposited in |
652 // |deleted_buffers| as if they were part of the current playback | 671 // |deleted_buffers| as if they were part of the current playback |
653 // position. | 672 // position. |
654 // TODO(acolwell): Figure out a more elegant way to do this. | 673 // TODO(acolwell): Figure out a more elegant way to do this. |
655 SeekAndSetSelectedRange(range_for_new_buffers, seek_timestamp); | 674 SeekAndSetSelectedRange(range_for_new_buffers, seek_timestamp); |
656 temporarily_select_range = true; | 675 temporarily_select_range = true; |
657 } | 676 } |
658 } | 677 } |
659 | 678 |
660 if (last_appended_buffer_timestamp_ != kNoTimestamp()) { | 679 base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_; |
680 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | |
681 base::TimeDelta next_timestamp = new_buffers.front()->GetDecodeTimestamp(); | |
682 bool next_is_keyframe = new_buffers.front()->IsKeyframe(); | |
683 | |
684 if (prev_timestamp != kNoTimestamp() && prev_timestamp != next_timestamp) { | |
661 // Clean up the old buffers between the last appended buffer and the | 685 // Clean up the old buffers between the last appended buffer and the |
662 // beginning of |new_buffers|. | 686 // beginning of |new_buffers|. |
663 DeleteBetween( | 687 DeleteBetween( |
664 range_for_new_buffers_itr, last_appended_buffer_timestamp_, | 688 range_for_new_buffers_itr, prev_timestamp, next_timestamp, true, |
665 new_buffers.front()->GetDecodeTimestamp(), true, | |
666 deleted_buffers); | 689 deleted_buffers); |
667 } | 690 } |
668 | 691 |
692 // Check for invalid alt-ref frame constructs. | |
scherkus (not reviewing)
2013/03/11 23:21:50
want to format this to use a bullet list / indent
acolwell GONE FROM CHROMIUM
2013/03/12 03:22:50
Done.
| |
693 // A keyframe followed by a non-keyframe or | |
694 // a non-keyframe followed by a keyframe that is not | |
695 // the first frame of a media segment are errors. | |
696 if (prev_timestamp == next_timestamp && | |
697 ((prev_is_keyframe && !next_is_keyframe) || | |
698 (!new_media_segment_ && next_is_keyframe))) { | |
699 MEDIA_LOG(log_cb_) << "Invalid alt-ref frame construct detected at time " | |
700 << prev_timestamp.InSecondsF(); | |
701 return false; | |
702 } | |
703 | |
669 // If we cannot append the |new_buffers| to the end of the existing range, | 704 // If we cannot append the |new_buffers| to the end of the existing range, |
670 // this is either a start overlap or an middle overlap. Delete the buffers | 705 // this is either a start overlap or an middle overlap. Delete the buffers |
scherkus (not reviewing)
2013/03/11 23:21:50
s/or an middle/or a middle/
acolwell GONE FROM CHROMIUM
2013/03/12 03:22:50
Done.
| |
671 // that |new_buffers| overlaps. | 706 // that |new_buffers| overlaps. |
672 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { | 707 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { |
708 // Make the delete range exclusive if we are dealing with an alt-ref | |
709 // situation so that the buffer with the same timestamp that is already | |
710 // stored in |*range_for_new_buffers_itr| doesn't get deleted. | |
711 bool is_exclusive = prev_timestamp == next_timestamp && | |
712 !prev_is_keyframe && !next_is_keyframe; | |
713 | |
673 DeleteBetween( | 714 DeleteBetween( |
674 range_for_new_buffers_itr, new_buffers.front()->GetDecodeTimestamp(), | 715 range_for_new_buffers_itr, new_buffers.front()->GetDecodeTimestamp(), |
675 new_buffers.back()->GetDecodeTimestamp(), false, | 716 new_buffers.back()->GetDecodeTimestamp(), is_exclusive, |
676 deleted_buffers); | 717 deleted_buffers); |
677 } | 718 } |
678 | 719 |
679 // Restore the range seek state if necessary. | 720 // Restore the range seek state if necessary. |
680 if (temporarily_select_range) | 721 if (temporarily_select_range) |
681 SetSelectedRange(NULL); | 722 SetSelectedRange(NULL); |
682 | 723 |
683 range_for_new_buffers->AppendBuffersToEnd(new_buffers); | 724 range_for_new_buffers->AppendBuffersToEnd(new_buffers); |
725 return true; | |
684 } | 726 } |
685 | 727 |
686 void SourceBufferStream::DeleteBetween( | 728 void SourceBufferStream::DeleteBetween( |
687 const RangeList::iterator& range_itr, base::TimeDelta start_timestamp, | 729 const RangeList::iterator& range_itr, base::TimeDelta start_timestamp, |
688 base::TimeDelta end_timestamp, bool is_range_exclusive, | 730 base::TimeDelta end_timestamp, bool is_range_exclusive, |
689 BufferQueue* deleted_buffers) { | 731 BufferQueue* deleted_buffers) { |
690 SourceBufferRange* new_next_range = | 732 SourceBufferRange* new_next_range = |
691 (*range_itr)->SplitRange(end_timestamp, is_range_exclusive); | 733 (*range_itr)->SplitRange(end_timestamp, is_range_exclusive); |
692 | 734 |
693 // Insert the |new_next_range| into |ranges_| after |range|. | 735 // Insert the |new_next_range| into |ranges_| after |range|. |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1250 media_segment_start_time_(media_segment_start_time), | 1292 media_segment_start_time_(media_segment_start_time), |
1251 interbuffer_distance_cb_(interbuffer_distance_cb), | 1293 interbuffer_distance_cb_(interbuffer_distance_cb), |
1252 size_in_bytes_(0) { | 1294 size_in_bytes_(0) { |
1253 DCHECK(!new_buffers.empty()); | 1295 DCHECK(!new_buffers.empty()); |
1254 DCHECK(new_buffers.front()->IsKeyframe()); | 1296 DCHECK(new_buffers.front()->IsKeyframe()); |
1255 DCHECK(!interbuffer_distance_cb.is_null()); | 1297 DCHECK(!interbuffer_distance_cb.is_null()); |
1256 AppendBuffersToEnd(new_buffers); | 1298 AppendBuffersToEnd(new_buffers); |
1257 } | 1299 } |
1258 | 1300 |
1259 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { | 1301 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) { |
1302 DCHECK(buffers_.empty() || | |
1303 buffers_.back()->GetDecodeTimestamp() <= | |
1304 new_buffers.front()->GetDecodeTimestamp()); | |
1305 | |
1260 for (BufferQueue::const_iterator itr = new_buffers.begin(); | 1306 for (BufferQueue::const_iterator itr = new_buffers.begin(); |
1261 itr != new_buffers.end(); ++itr) { | 1307 itr != new_buffers.end(); ++itr) { |
1262 DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp()); | 1308 DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp()); |
1263 buffers_.push_back(*itr); | 1309 buffers_.push_back(*itr); |
1264 size_in_bytes_ += (*itr)->GetDataSize(); | 1310 size_in_bytes_ += (*itr)->GetDataSize(); |
1265 | 1311 |
1266 if ((*itr)->IsKeyframe()) { | 1312 if ((*itr)->IsKeyframe()) { |
1267 keyframe_map_.insert( | 1313 keyframe_map_.insert( |
1268 std::make_pair((*itr)->GetDecodeTimestamp(), | 1314 std::make_pair((*itr)->GetDecodeTimestamp(), |
1269 buffers_.size() - 1 + keyframe_map_index_base_)); | 1315 buffers_.size() - 1 + keyframe_map_index_base_)); |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1685 return ComputeFudgeRoom(GetApproximateDuration()); | 1731 return ComputeFudgeRoom(GetApproximateDuration()); |
1686 } | 1732 } |
1687 | 1733 |
1688 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1734 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
1689 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1735 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
1690 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1736 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
1691 return max_interbuffer_distance; | 1737 return max_interbuffer_distance; |
1692 } | 1738 } |
1693 | 1739 |
1694 } // namespace media | 1740 } // namespace media |
OLD | NEW |