Bug 1108917 - Part 1: Attempt to evict data from decoders in start-time order. r=ajones, a=sledru
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 11 Dec 2014 10:49:54 +1300
changeset 242750 72f6dba74653a0c2b3e85aa59aff2a12637afcec
parent 242749 e2febcf7a58686f939be01784d162fedb99c2a46
child 242751 d64cfe41fa7499cf0b6583141f964e250aab4852
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajones, sledru
bugs1108917
milestone36.0a2
Bug 1108917 - Part 1: Attempt to evict data from decoders in start-time order. r=ajones, a=sledru
dom/media/mediasource/TrackBuffer.cpp
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -196,39 +196,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)
 {