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

Unified Diff: media/filters/source_buffer_stream.cc

Issue 1349973002: Fix seeking back in the new MSE GC algorithm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR feedback Created 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/source_buffer_stream.cc
diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc
index e17a4f1c91952b64cf280a9777404e4adeec71d2..30439522c5669a5477c42b87a91dc5254a501f6b 100644
--- a/media/filters/source_buffer_stream.cc
+++ b/media/filters/source_buffer_stream.cc
@@ -34,6 +34,9 @@ const int kMaxSpliceGenerationSuccessLogs = 20;
// Limit the number of MEDIA_LOG() logs for track buffer time gaps.
const int kMaxTrackBufferGapWarningLogs = 20;
+// Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
+const int kMaxGarbageCollectAlgorithWarningLogs = 50;
+
// Helper method that returns true if |ranges| is sorted in increasing order,
// false otherwise.
bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) {
@@ -619,8 +622,13 @@ bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
// Sanity and overflow checks
if ((newDataSize > memory_limit_) ||
- (ranges_size + newDataSize < ranges_size))
+ (ranges_size + newDataSize < ranges_size)) {
+ LIMITED_MEDIA_LOG(DEBUG, media_log_, num_garbage_collect_algorithm_logs_,
+ kMaxGarbageCollectAlgorithWarningLogs)
+ << "GarbageCollectIfNeeded failed: memory_limit_=" << memory_limit_
+ << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize;
return false;
+ }
// Return if we're under or at the memory limit.
if (ranges_size + newDataSize <= memory_limit_)
@@ -628,9 +636,14 @@ bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
size_t bytes_to_free = ranges_size + newDataSize - memory_limit_;
+ // If there is a pending seek, then we should allow GC to remove data more
+ // aggressively for the upcoming append to allow seeking to proceed.
+ bool seek_pending = IsSeekPending();
+
DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC"
<< " media_time=" << media_time.InSecondsF()
<< " ranges_=" << RangesToString(ranges_)
+ << " seek_pending=" << seek_pending
<< " ranges_size=" << ranges_size
<< " newDataSize=" << newDataSize
<< " memory_limit_=" << memory_limit_
@@ -649,22 +662,59 @@ bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
<< " ranges_=" << RangesToString(ranges_);
bytes_freed += between;
- // If the last append happened before the current playback position
- // |media_time|, then JS player is probably preparing to seek back and we
- // should try to preserve all most recently appended data (which is in
- // range_for_next_append_) from being removed by GC (see crbug.com/440173)
+ // Some players start appending data at the new seek target position before
+ // actually initiating the seek operation (i.e. they try to improve seek
+ // performance by prebuffering some data at the seek target position and
+ // initiating seek once enough data is pre-buffered. In those cases we'll
+ // see that data is being appended at some new position, but there is no
+ // pending seek reported yet. In this situation we need to try preserving
+ // the most recently appended data, i.e. data belonging to the same buffered
+ // range as the most recent append.
if (range_for_next_append_ != ranges_.end()) {
DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time);
media_time = (*range_for_next_append_)->GetStartTimestamp();
}
}
+ // If there is an unsatisfied pending seek, we can safely remove all data that
+ // is earlier than seek target, then remove from the back until we reach the
+ // most recently appended GOP and then remove from the front if we still don't
+ // have enough space for the upcoming append.
+ if (bytes_freed < bytes_to_free && seek_pending) {
+ DCHECK(!ranges_.empty());
+ // All data earlier than the seek target |media_time| can be removed safely
+ size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
+ DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the"
+ << " front. ranges_=" << RangesToString(ranges_);
+ bytes_freed += front;
+
+ // If removing data earlier than |media_time| didn't free up enough space,
+ // then try deleting from the back until we reach most recently appended GOP
+ if (bytes_freed < bytes_to_free) {
+ size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
+ DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back"
+ << " ranges_=" << RangesToString(ranges_);
+ bytes_freed += back;
+ }
+
+ // If even that wasn't enough, then try greedily deleting from the front,
+ // that should allow us to remove as much data as necessary to succeed.
+ if (bytes_freed < bytes_to_free) {
+ size_t front2 = FreeBuffers(bytes_to_free - bytes_freed,
+ ranges_.back()->GetEndTimestamp(), false);
+ DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the"
+ << " front. ranges_=" << RangesToString(ranges_);
+ bytes_freed += front2;
+ }
+ DCHECK(bytes_freed >= bytes_to_free);
+ }
+
// Try removing data from the front of the SourceBuffer up to |media_time|
// position.
if (bytes_freed < bytes_to_free) {
size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
- DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the front"
- << " ranges_=" << RangesToString(ranges_);
+ DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the"
+ << " front. ranges_=" << RangesToString(ranges_);
bytes_freed += front;
}
@@ -672,7 +722,7 @@ bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
// most recent append position.
if (bytes_freed < bytes_to_free) {
size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
- DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back"
+ DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back."
<< " ranges_=" << RangesToString(ranges_);
bytes_freed += back;
}
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698