Bug 1108917 - Part 1: Attempt to evict data from decoders in start-time order. r=ajones
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 11 Dec 2014 10:49:54 +1300
changeset 245081 0f9b7c71ba3d45c3c671290c822512a2328ddc04
parent 245080 0fe752f786b3d17655046195b37312c39d446a56
child 245082 beec11f1ceed6b8debc2b61b87825c49c3e96aad
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajones
bugs1108917
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1108917 - Part 1: Attempt to evict data from decoders in start-time order. r=ajones
dom/media/mediasource/TrackBuffer.cpp
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -197,39 +197,72 @@ TrackBuffer::AppendDataToCurrentResource
   mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
                                      aLength, appendOffset);
   mParentDecoder->NotifyBytesDownloaded();
   mParentDecoder->NotifyTimeRangesChanged();
 
   return true;
 }
 
+class DecoderSorter
+{
+public:
+  bool LessThan(SourceBufferDecoder* aFirst, SourceBufferDecoder* aSecond) const
+  {
+    nsRefPtr<dom::TimeRanges> first = new dom::TimeRanges();
+    aFirst->GetBuffered(first);
+
+    nsRefPtr<dom::TimeRanges> second = new dom::TimeRanges();
+    aSecond->GetBuffered(second);
+
+    return first->GetStartTime() < second->GetStartTime();
+  }
+
+  bool Equals(SourceBufferDecoder* aFirst, SourceBufferDecoder* aSecond) const
+  {
+    nsRefPtr<dom::TimeRanges> first = new dom::TimeRanges();
+    aFirst->GetBuffered(first);
+
+    nsRefPtr<dom::TimeRanges> second = new dom::TimeRanges();
+    aSecond->GetBuffered(second);
+
+    return first->GetStartTime() == second->GetStartTime();
+  }
+};
+
 bool
 TrackBuffer::EvictData(uint32_t aThreshold)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
 
   int64_t totalSize = 0;
   for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
     totalSize += mDecoders[i]->GetResource()->GetSize();
   }
 
   int64_t toEvict = totalSize - aThreshold;
   if (toEvict <= 0) {
     return false;
   }
 
-  for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) {
+  nsTArray<SourceBufferDecoder*> decoders;
+  decoders.AppendElements(mInitializedDecoders);
+  decoders.Sort(DecoderSorter());
+
+  for (uint32_t i = 0; i < decoders.Length(); ++i) {
     MSE_DEBUG("TrackBuffer(%p)::EvictData decoder=%u threshold=%u toEvict=%lld",
               this, i, aThreshold, toEvict);
-    toEvict -= mInitializedDecoders[i]->GetResource()->EvictData(toEvict);
-    if (!mInitializedDecoders[i]->GetResource()->GetSize() &&
-        mInitializedDecoders[i] != mCurrentDecoder) {
-      RemoveDecoder(mInitializedDecoders[i]);
+    toEvict -= decoders[i]->GetResource()->EvictData(toEvict);
+    if (!decoders[i]->GetResource()->GetSize() &&
+        decoders[i] != mCurrentDecoder) {
+      RemoveDecoder(decoders[i]);
+    }
+    if (toEvict <= 0 || decoders[i] == mCurrentDecoder) {
+      break;
     }
   }
   return toEvict < (totalSize - aThreshold);
 }
 
 void
 TrackBuffer::EvictBefore(double aTime)
 {