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 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 | 599 |
600 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { | 600 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { |
601 for (BufferQueue::const_iterator itr = buffers.begin(); | 601 for (BufferQueue::const_iterator itr = buffers.begin(); |
602 itr != buffers.end(); ++itr) { | 602 itr != buffers.end(); ++itr) { |
603 (*itr)->SetConfigId(append_config_index_); | 603 (*itr)->SetConfigId(append_config_index_); |
604 } | 604 } |
605 } | 605 } |
606 | 606 |
607 void SourceBufferStream::GarbageCollectIfNeeded() { | 607 void SourceBufferStream::GarbageCollectIfNeeded() { |
608 // Compute size of |ranges_|. | 608 // Compute size of |ranges_|. |
609 int ranges_size = 0; | 609 size_t ranges_size = 0; |
610 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) | 610 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) |
611 ranges_size += (*itr)->size_in_bytes(); | 611 ranges_size += (*itr)->size_in_bytes(); |
612 | 612 |
613 // Return if we're under or at the memory limit. | 613 // Return if we're under or at the memory limit. |
614 if (ranges_size <= memory_limit_) | 614 if (ranges_size <= memory_limit_) |
615 return; | 615 return; |
616 | 616 |
617 int bytes_to_free = ranges_size - memory_limit_; | 617 size_t bytes_to_free = ranges_size - memory_limit_; |
618 | 618 |
619 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC" | 619 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC" |
620 << " ranges_size=" << ranges_size | 620 << " ranges_size=" << ranges_size |
621 << " ranges_=" << RangesToString(ranges_) | 621 << " ranges_=" << RangesToString(ranges_) |
622 << " memory_limit_=" << memory_limit_; | 622 << " memory_limit_=" << memory_limit_; |
623 | 623 |
624 // Begin deleting after the last appended buffer. | 624 // Begin deleting after the last appended buffer. |
625 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); | 625 size_t bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); |
626 | 626 |
627 // Begin deleting from the front. | 627 // Begin deleting from the front. |
628 if (bytes_to_free - bytes_freed > 0) | 628 if (bytes_freed < bytes_to_free) |
629 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); | 629 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); |
630 | 630 |
631 // Begin deleting from the back. | 631 // Begin deleting from the back. |
632 if (bytes_to_free - bytes_freed > 0) | 632 if (bytes_freed < bytes_to_free) |
633 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, true); | 633 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, true); |
634 | 634 |
635 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": After GC" | 635 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": After GC" |
636 << " bytes_freed=" << bytes_freed | 636 << " bytes_freed=" << bytes_freed |
637 << " ranges_=" << RangesToString(ranges_); | 637 << " ranges_=" << RangesToString(ranges_); |
638 } | 638 } |
639 | 639 |
640 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) { | 640 size_t SourceBufferStream::FreeBuffersAfterLastAppended( |
641 size_t total_bytes_to_free) { | |
641 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 642 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
642 if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() || | 643 if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() || |
643 next_buffer_timestamp == kNoDecodeTimestamp() || | 644 next_buffer_timestamp == kNoDecodeTimestamp() || |
644 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { | 645 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { |
645 return 0; | 646 return 0; |
646 } | 647 } |
647 | 648 |
648 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; | 649 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; |
649 if (last_appended_buffer_is_keyframe_) | 650 if (last_appended_buffer_is_keyframe_) |
650 remove_range_start += GetMaxInterbufferDistance(); | 651 remove_range_start += GetMaxInterbufferDistance(); |
651 | 652 |
652 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( | 653 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( |
653 remove_range_start); | 654 remove_range_start); |
654 if (remove_range_start_keyframe != kNoDecodeTimestamp()) | 655 if (remove_range_start_keyframe != kNoDecodeTimestamp()) |
655 remove_range_start = remove_range_start_keyframe; | 656 remove_range_start = remove_range_start_keyframe; |
656 if (remove_range_start >= next_buffer_timestamp) | 657 if (remove_range_start >= next_buffer_timestamp) |
657 return 0; | 658 return 0; |
658 | 659 |
659 DecodeTimestamp remove_range_end; | 660 DecodeTimestamp remove_range_end; |
660 int bytes_freed = GetRemovalRange( | 661 size_t bytes_freed = GetRemovalRange(remove_range_start, |
661 remove_range_start, next_buffer_timestamp, total_bytes_to_free, | 662 next_buffer_timestamp, |
662 &remove_range_end); | 663 total_bytes_to_free, |
664 &remove_range_end); | |
663 if (bytes_freed > 0) { | 665 if (bytes_freed > 0) { |
664 Remove(remove_range_start.ToPresentationTime(), | 666 Remove(remove_range_start.ToPresentationTime(), |
665 remove_range_end.ToPresentationTime(), | 667 remove_range_end.ToPresentationTime(), |
666 next_buffer_timestamp.ToPresentationTime()); | 668 next_buffer_timestamp.ToPresentationTime()); |
667 } | 669 } |
668 | 670 |
669 return bytes_freed; | 671 return bytes_freed; |
670 } | 672 } |
671 | 673 |
672 int SourceBufferStream::GetRemovalRange( | 674 size_t SourceBufferStream::GetRemovalRange( |
673 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, | 675 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, |
674 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { | 676 size_t total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { |
675 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF(); | 677 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF(); |
676 DCHECK(start_timestamp < end_timestamp) | 678 DCHECK(start_timestamp < end_timestamp) |
677 << "start " << start_timestamp.InSecondsF() | 679 << "start " << start_timestamp.InSecondsF() |
678 << ", end " << end_timestamp.InSecondsF(); | 680 << ", end " << end_timestamp.InSecondsF(); |
679 | 681 |
680 int bytes_to_free = total_bytes_to_free; | 682 size_t bytes_freed = 0; |
681 int bytes_freed = 0; | |
682 | 683 |
683 for (RangeList::iterator itr = ranges_.begin(); | 684 for (RangeList::iterator itr = ranges_.begin(); |
684 itr != ranges_.end() && bytes_to_free > 0; ++itr) { | 685 itr != ranges_.end() && bytes_freed < total_bytes_to_free; ++itr) { |
685 SourceBufferRange* range = *itr; | 686 SourceBufferRange* range = *itr; |
686 if (range->GetStartTimestamp() >= end_timestamp) | 687 if (range->GetStartTimestamp() >= end_timestamp) |
687 break; | 688 break; |
688 if (range->GetEndTimestamp() < start_timestamp) | 689 if (range->GetEndTimestamp() < start_timestamp) |
689 continue; | 690 continue; |
690 | 691 |
691 int bytes_removed = range->GetRemovalGOP( | 692 size_t bytes_to_free = total_bytes_to_free - bytes_freed; |
wolenetz
2015/07/20 19:29:43
This new variable is unused. Remove this line?
servolk
2015/07/22 19:02:11
No, it's passed into GetRemovalGOP (see the next l
wolenetz
2015/07/22 20:54:40
Acknowledged.
| |
693 size_t bytes_removed = range->GetRemovalGOP( | |
692 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); | 694 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); |
693 bytes_to_free -= bytes_removed; | |
694 bytes_freed += bytes_removed; | 695 bytes_freed += bytes_removed; |
695 } | 696 } |
696 return bytes_freed; | 697 return bytes_freed; |
697 } | 698 } |
698 | 699 |
699 int SourceBufferStream::FreeBuffers(int total_bytes_to_free, | 700 size_t SourceBufferStream::FreeBuffers(size_t total_bytes_to_free, |
700 bool reverse_direction) { | 701 bool reverse_direction) { |
701 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", | 702 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", |
702 "total bytes to free", total_bytes_to_free, | 703 "total bytes to free", total_bytes_to_free, |
703 "reverse direction", reverse_direction); | 704 "reverse direction", reverse_direction); |
704 | 705 |
705 DCHECK_GT(total_bytes_to_free, 0); | 706 DCHECK_GT(total_bytes_to_free, 0u); |
706 int bytes_to_free = total_bytes_to_free; | 707 size_t bytes_freed = 0; |
707 int bytes_freed = 0; | |
708 | 708 |
709 // This range will save the last GOP appended to |range_for_next_append_| | 709 // This range will save the last GOP appended to |range_for_next_append_| |
710 // if the buffers surrounding it get deleted during garbage collection. | 710 // if the buffers surrounding it get deleted during garbage collection. |
711 SourceBufferRange* new_range_for_append = NULL; | 711 SourceBufferRange* new_range_for_append = NULL; |
712 | 712 |
713 while (!ranges_.empty() && bytes_to_free > 0) { | 713 while (!ranges_.empty() && bytes_freed < total_bytes_to_free) { |
714 SourceBufferRange* current_range = NULL; | 714 SourceBufferRange* current_range = NULL; |
715 BufferQueue buffers; | 715 BufferQueue buffers; |
716 int bytes_deleted = 0; | 716 size_t bytes_deleted = 0; |
717 | 717 |
718 if (reverse_direction) { | 718 if (reverse_direction) { |
719 current_range = ranges_.back(); | 719 current_range = ranges_.back(); |
720 if (current_range->LastGOPContainsNextBufferPosition()) { | 720 if (current_range->LastGOPContainsNextBufferPosition()) { |
721 DCHECK_EQ(current_range, selected_range_); | 721 DCHECK_EQ(current_range, selected_range_); |
722 break; | 722 break; |
723 } | 723 } |
724 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); | 724 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); |
725 } else { | 725 } else { |
726 current_range = ranges_.front(); | 726 current_range = ranges_.front(); |
(...skipping 10 matching lines...) Expand all Loading... | |
737 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp()); | 737 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp()); |
738 DCHECK(!new_range_for_append); | 738 DCHECK(!new_range_for_append); |
739 // Create a new range containing these buffers. | 739 // Create a new range containing these buffers. |
740 new_range_for_append = new SourceBufferRange( | 740 new_range_for_append = new SourceBufferRange( |
741 TypeToGapPolicy(GetType()), | 741 TypeToGapPolicy(GetType()), |
742 buffers, kNoDecodeTimestamp(), | 742 buffers, kNoDecodeTimestamp(), |
743 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, | 743 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
744 base::Unretained(this))); | 744 base::Unretained(this))); |
745 range_for_next_append_ = ranges_.end(); | 745 range_for_next_append_ = ranges_.end(); |
746 } else { | 746 } else { |
747 bytes_to_free -= bytes_deleted; | |
748 bytes_freed += bytes_deleted; | 747 bytes_freed += bytes_deleted; |
749 } | 748 } |
750 | 749 |
751 if (current_range->size_in_bytes() == 0) { | 750 if (current_range->size_in_bytes() == 0) { |
752 DCHECK_NE(current_range, selected_range_); | 751 DCHECK_NE(current_range, selected_range_); |
753 DCHECK(range_for_next_append_ == ranges_.end() || | 752 DCHECK(range_for_next_append_ == ranges_.end() || |
754 *range_for_next_append_ != current_range); | 753 *range_for_next_append_ != current_range); |
755 delete current_range; | 754 delete current_range; |
756 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); | 755 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); |
757 } | 756 } |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1253 const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() { | 1252 const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() { |
1254 return text_track_config_; | 1253 return text_track_config_; |
1255 } | 1254 } |
1256 | 1255 |
1257 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { | 1256 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { |
1258 if (max_interbuffer_distance_ == kNoTimestamp()) | 1257 if (max_interbuffer_distance_ == kNoTimestamp()) |
1259 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); | 1258 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs); |
1260 return max_interbuffer_distance_; | 1259 return max_interbuffer_distance_; |
1261 } | 1260 } |
1262 | 1261 |
1262 void SourceBufferStream::SetMemoryLimit(size_t memory_limit) { | |
1263 memory_limit_ = memory_limit; | |
1264 } | |
1265 | |
1263 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { | 1266 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
1264 DCHECK(!audio_configs_.empty()); | 1267 DCHECK(!audio_configs_.empty()); |
1265 DCHECK(video_configs_.empty()); | 1268 DCHECK(video_configs_.empty()); |
1266 DVLOG(3) << "UpdateAudioConfig."; | 1269 DVLOG(3) << "UpdateAudioConfig."; |
1267 | 1270 |
1268 if (audio_configs_[0].codec() != config.codec()) { | 1271 if (audio_configs_[0].codec() != config.codec()) { |
1269 MEDIA_LOG(ERROR, log_cb_) << "Audio codec changes not allowed."; | 1272 MEDIA_LOG(ERROR, log_cb_) << "Audio codec changes not allowed."; |
1270 return false; | 1273 return false; |
1271 } | 1274 } |
1272 | 1275 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1600 return false; | 1603 return false; |
1601 | 1604 |
1602 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1605 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1603 splice_buffers_index_ = 0; | 1606 splice_buffers_index_ = 0; |
1604 pending_buffer_.swap(*out_buffer); | 1607 pending_buffer_.swap(*out_buffer); |
1605 pending_buffers_complete_ = false; | 1608 pending_buffers_complete_ = false; |
1606 return true; | 1609 return true; |
1607 } | 1610 } |
1608 | 1611 |
1609 } // namespace media | 1612 } // namespace media |
OLD | NEW |