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

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

Issue 10879056: Support setting an explicit duration on MediaSource objects (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: response to CR Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // deleted, and deletes the |keyframe_map_| entries for the buffers that 76 // deleted, and deletes the |keyframe_map_| entries for the buffers that
77 // were removed. 77 // were removed.
78 // |deleted_buffers| contains the buffers that were deleted from this range, 78 // |deleted_buffers| contains the buffers that were deleted from this range,
79 // starting at the buffer that had been at |next_buffer_index_|. 79 // starting at the buffer that had been at |next_buffer_index_|.
80 // Returns true if the |next_buffer_index_| is reset. Note that this method 80 // Returns true if the |next_buffer_index_| is reset. Note that this method
81 // may return true even if it does not add any buffers to |deleted_buffers|. 81 // may return true even if it does not add any buffers to |deleted_buffers|.
82 // This indicates that the range had not buffered |next_buffer_index_|, but 82 // This indicates that the range had not buffered |next_buffer_index_|, but
83 // a buffer at that position would have been deleted. 83 // a buffer at that position would have been deleted.
84 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer, 84 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer,
85 BufferQueue* deleted_buffers); 85 BufferQueue* deleted_buffers);
86 bool TruncateAt(base::TimeDelta timestamp);
86 // Deletes all buffers in range. 87 // Deletes all buffers in range.
87 bool DeleteAll(BufferQueue* deleted_buffers); 88 bool DeleteAll(BufferQueue* deleted_buffers);
88 89
89 // Attempts to free |bytes| data from the range, preferring to delete at the 90 // Attempts to free |bytes| data from the range, preferring to delete at the
90 // beginning of the range. Deletes data in GOPS at a time so that the range 91 // beginning of the range. Deletes data in GOPS at a time so that the range
91 // always begins with a keyframe. Returns the number of bytes freed. 92 // always begins with a keyframe. Returns the number of bytes freed.
92 int FreeFromStart(int bytes); 93 int FreeFromStart(int bytes);
93 94
94 // Attempts to free |bytes| data from the range, preferring to delete at the 95 // Attempts to free |bytes| data from the range, preferring to delete at the
95 // end of the range. Returns the number of bytes freed. 96 // end of the range. Returns the number of bytes freed.
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 409 }
409 } 410 }
410 411
411 GarbageCollectIfNeeded(); 412 GarbageCollectIfNeeded();
412 413
413 DCHECK(IsRangeListSorted(ranges_)); 414 DCHECK(IsRangeListSorted(ranges_));
414 DCHECK(OnlySelectedRangeIsSeeked()); 415 DCHECK(OnlySelectedRangeIsSeeked());
415 return true; 416 return true;
416 } 417 }
417 418
419 void SourceBufferStream::ResetSeekState() {
420 SetSelectedRange(NULL);
421 track_buffer_.clear();
422 config_change_pending_ = false;
423 }
424
418 bool SourceBufferStream::ShouldSeekToStartOfBuffered( 425 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
419 base::TimeDelta seek_timestamp) const { 426 base::TimeDelta seek_timestamp) const {
420 if (ranges_.empty()) 427 if (ranges_.empty())
421 return false; 428 return false;
422 base::TimeDelta beginning_of_buffered = 429 base::TimeDelta beginning_of_buffered =
423 ranges_.front()->GetStartTimestamp(); 430 ranges_.front()->GetStartTimestamp();
424 return (seek_timestamp <= beginning_of_buffered && 431 return (seek_timestamp <= beginning_of_buffered &&
425 beginning_of_buffered < kSeekToStartFudgeRoom()); 432 beginning_of_buffered < kSeekToStartFudgeRoom());
426 } 433 }
427 434
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 if (transfer_current_position) 721 if (transfer_current_position)
715 SetSelectedRange(range_with_new_buffers); 722 SetSelectedRange(range_with_new_buffers);
716 723
717 delete *next_range_itr; 724 delete *next_range_itr;
718 ranges_.erase(next_range_itr); 725 ranges_.erase(next_range_itr);
719 } 726 }
720 } 727 }
721 728
722 void SourceBufferStream::Seek(base::TimeDelta timestamp) { 729 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
723 DCHECK(timestamp >= base::TimeDelta()); 730 DCHECK(timestamp >= base::TimeDelta());
724 SetSelectedRange(NULL); 731 ResetSeekState();
725 track_buffer_.clear();
726 config_change_pending_ = false;
727 732
728 if (ShouldSeekToStartOfBuffered(timestamp)) { 733 if (ShouldSeekToStartOfBuffered(timestamp)) {
729 SetSelectedRange(ranges_.front()); 734 SetSelectedRange(ranges_.front());
730 ranges_.front()->SeekToStart(); 735 ranges_.front()->SeekToStart();
731 seek_pending_ = false; 736 seek_pending_ = false;
732 return; 737 return;
733 } 738 }
734 739
735 seek_buffer_timestamp_ = timestamp; 740 seek_buffer_timestamp_ = timestamp;
736 seek_pending_ = true; 741 seek_pending_ = true;
737 742
738 RangeList::iterator itr = ranges_.end(); 743 RangeList::iterator itr = ranges_.end();
739 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { 744 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
740 if ((*itr)->CanSeekTo(timestamp)) 745 if ((*itr)->CanSeekTo(timestamp))
741 break; 746 break;
742 } 747 }
743 748
744 if (itr == ranges_.end()) 749 if (itr == ranges_.end())
745 return; 750 return;
746 751
747 SetSelectedRange(*itr); 752 SetSelectedRange(*itr);
748 selected_range_->Seek(timestamp); 753 selected_range_->Seek(timestamp);
749 seek_pending_ = false; 754 seek_pending_ = false;
750 } 755 }
751 756
752 bool SourceBufferStream::IsSeekPending() const { 757 bool SourceBufferStream::IsSeekPending() const {
753 return seek_pending_; 758 return seek_pending_;
754 } 759 }
755 760
761 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
762 RangeList::iterator itr = ranges_.end();
763 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
764 if ((*itr)->GetEndTimestamp() > duration)
765 break;
766 }
767 if (itr == ranges_.end())
768 return;
769
770 // Need to partially truncate this range.
771 if ((*itr)->GetStartTimestamp() < duration) {
772 bool deleted_seek_point = (*itr)->TruncateAt(duration);
773 if (deleted_seek_point)
774 ResetSeekState();
775 ++itr;
776 }
777
778 // Delete all ranges that begin after |duration|.
779 while (itr != ranges_.end()) {
780 // If we're about to delete the selected range, also reset the seek state.
781 DCHECK((*itr)->GetStartTimestamp() >= duration);
782 if (*itr== selected_range_)
783 ResetSeekState();
784 delete *itr;
785 itr = ranges_.erase(itr);
786 }
787 }
788
756 SourceBufferStream::Status SourceBufferStream::GetNextBuffer( 789 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
757 scoped_refptr<StreamParserBuffer>* out_buffer) { 790 scoped_refptr<StreamParserBuffer>* out_buffer) {
758 CHECK(!config_change_pending_); 791 CHECK(!config_change_pending_);
759 792
760 if (!track_buffer_.empty()) { 793 if (!track_buffer_.empty()) {
761 if (track_buffer_.front()->GetConfigId() != current_config_index_) { 794 if (track_buffer_.front()->GetConfigId() != current_config_index_) {
762 config_change_pending_ = true; 795 config_change_pending_ = true;
763 return kConfigChange; 796 return kConfigChange;
764 } 797 }
765 798
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 (result == keyframe_map_.end() || result->first != timestamp)) { 1115 (result == keyframe_map_.end() || result->first != timestamp)) {
1083 --result; 1116 --result;
1084 } 1117 }
1085 return result; 1118 return result;
1086 } 1119 }
1087 1120
1088 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { 1121 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
1089 return TruncateAt(buffers_.begin(), removed_buffers); 1122 return TruncateAt(buffers_.begin(), removed_buffers);
1090 } 1123 }
1091 1124
1125 bool SourceBufferRange::TruncateAt(base::TimeDelta timestamp) {
1126 // Need to make a dummy buffer with timestamp |timestamp| in order to search
1127 // the |buffers_| container.
1128 scoped_refptr<StreamParserBuffer> dummy_buffer =
1129 StreamParserBuffer::CopyFrom(NULL, 0, false);
1130 dummy_buffer->SetDecodeTimestamp(timestamp);
1131 return TruncateAt(dummy_buffer, NULL);
1132 }
1133
1092 bool SourceBufferRange::TruncateAt( 1134 bool SourceBufferRange::TruncateAt(
1093 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { 1135 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) {
1094 // Find the place in |buffers_| where we will begin deleting data. 1136 // Find the place in |buffers_| where we will begin deleting data.
1095 BufferQueue::iterator starting_point = 1137 BufferQueue::iterator starting_point =
1096 std::lower_bound(buffers_.begin(), buffers_.end(), 1138 std::lower_bound(buffers_.begin(), buffers_.end(),
1097 buffer, 1139 buffer,
1098 BufferComparator); 1140 BufferComparator);
1099 return TruncateAt(starting_point, removed_buffers); 1141 return TruncateAt(starting_point, removed_buffers);
1100 } 1142 }
1101 1143
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 for (BufferQueue::iterator itr = starting_point; 1245 for (BufferQueue::iterator itr = starting_point;
1204 itr != ending_point; ++itr) { 1246 itr != ending_point; ++itr) {
1205 size_in_bytes_ -= (*itr)->GetDataSize(); 1247 size_in_bytes_ -= (*itr)->GetDataSize();
1206 DCHECK_GE(size_in_bytes_, 0); 1248 DCHECK_GE(size_in_bytes_, 0);
1207 } 1249 }
1208 buffers_.erase(starting_point, ending_point); 1250 buffers_.erase(starting_point, ending_point);
1209 } 1251 }
1210 1252
1211 bool SourceBufferRange::TruncateAt( 1253 bool SourceBufferRange::TruncateAt(
1212 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) { 1254 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) {
1213 DCHECK(removed_buffers); 1255 DCHECK(!removed_buffers || removed_buffers->empty());
1214 DCHECK(removed_buffers->empty());
1215 1256
1216 // Return if we're not deleting anything. 1257 // Return if we're not deleting anything.
1217 if (starting_point == buffers_.end()) 1258 if (starting_point == buffers_.end())
1218 return false; 1259 return false;
1219 1260
1220 // Reset the next buffer index if we will be deleting the buffer that's next 1261 // Reset the next buffer index if we will be deleting the buffer that's next
1221 // in sequence. 1262 // in sequence.
1222 bool removed_next_buffer = false; 1263 bool removed_next_buffer = false;
1223 if (HasNextBufferPosition()) { 1264 if (HasNextBufferPosition()) {
1224 base::TimeDelta next_buffer_timestamp = GetNextTimestamp(); 1265 base::TimeDelta next_buffer_timestamp = GetNextTimestamp();
1225 if (next_buffer_timestamp == kNoTimestamp() || 1266 if (next_buffer_timestamp == kNoTimestamp() ||
1226 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) { 1267 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) {
1227 if (HasNextBuffer()) { 1268 if (HasNextBuffer() && removed_buffers) {
1228 int starting_offset = starting_point - buffers_.begin(); 1269 int starting_offset = starting_point - buffers_.begin();
1229 int next_buffer_offset = next_buffer_index_ - starting_offset; 1270 int next_buffer_offset = next_buffer_index_ - starting_offset;
1230 DCHECK_GE(next_buffer_offset, 0); 1271 DCHECK_GE(next_buffer_offset, 0);
1231 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end()); 1272 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end());
1232 removed_buffers->swap(saved); 1273 removed_buffers->swap(saved);
1233 } 1274 }
1234 ResetNextBufferPosition(); 1275 ResetNextBufferPosition();
1235 removed_next_buffer = true; 1276 removed_next_buffer = true;
1236 } 1277 }
1237 } 1278 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 return 2 * GetApproximateDuration(); 1415 return 2 * GetApproximateDuration();
1375 } 1416 }
1376 1417
1377 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { 1418 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
1378 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); 1419 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
1379 DCHECK(max_interbuffer_distance != kNoTimestamp()); 1420 DCHECK(max_interbuffer_distance != kNoTimestamp());
1380 return max_interbuffer_distance; 1421 return max_interbuffer_distance;
1381 } 1422 }
1382 1423
1383 } // namespace media 1424 } // 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