Bug 1065235 - Apply eviction to all decoders owned by TrackBuffer and make EvictData threshold apply per-TrackBuffer rather than per-decoder. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Tue, 09 Sep 2014 21:12:00 +1200
changeset 205583 1baee6918ab32361d01e891fedbbc90fc22dcb75
parent 205582 a68c9d18ffa5a540c8b91e4ed77c094fe636ed8d
child 205584 7cb9cd1191769b83e40f2f499a68dc50e825b008
push id27498
push userkwierso@gmail.com
push dateWed, 17 Sep 2014 00:06:56 +0000
treeherdermozilla-central@8252eae8278c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscajbir
bugs1065235
milestone35.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 1065235 - Apply eviction to all decoders owned by TrackBuffer and make EvictData threshold apply per-TrackBuffer rather than per-decoder. r=cajbir
content/media/mediasource/ResourceQueue.h
content/media/mediasource/SourceBuffer.cpp
content/media/mediasource/SourceBufferResource.cpp
content/media/mediasource/SourceBufferResource.h
content/media/mediasource/TrackBuffer.cpp
--- a/content/media/mediasource/ResourceQueue.h
+++ b/content/media/mediasource/ResourceQueue.h
@@ -98,30 +98,29 @@ public:
   }
 
   void AppendItem(const uint8_t* aData, uint32_t aLength) {
     mLogicalLength += aLength;
     Push(new ResourceItem(aData, aLength));
   }
 
   // Evict data in queue if the total queue size is greater than
-  // aThreshold past the offset. Returns true if some data was
-  // actually evicted.
-  bool Evict(uint64_t aOffset, uint32_t aThreshold) {
-    bool evicted = false;
+  // aThreshold past the offset. Returns amount evicted.
+  uint32_t Evict(uint64_t aOffset, uint32_t aThreshold) {
+    uint32_t evicted = 0;
     while (GetLength() - mOffset > aThreshold) {
       ResourceItem* item = ResourceAt(0);
       if (item->mData.Length() + mOffset > aOffset) {
         break;
       }
       mOffset += item->mData.Length();
+      evicted += item->mData.Length();
       SBR_DEBUGV("ResourceQueue(%p)::Evict(%llu, %u) removed chunk length=%u",
                  this, aOffset, aThreshold, item->mData.Length());
       delete PopFront();
-      evicted = true;
     }
     return evicted;
   }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
     // Calculate the size of the internal deque.
     size_t size = nsDeque::SizeOfExcludingThis(aMallocSizeOf);
 
--- a/content/media/mediasource/SourceBuffer.cpp
+++ b/content/media/mediasource/SourceBuffer.cpp
@@ -654,16 +654,17 @@ SourceBuffer::AppendData(const uint8_t* 
 
   // Eviction uses a byte threshold. If the buffer is greater than the
   // number of bytes then data is evicted. The time range for this
   // eviction is reported back to the media source. It will then
   // evict data before that range across all SourceBuffers it knows
   // about.
   // TODO: Make the eviction threshold smaller for audio-only streams.
   // TODO: Drive evictions off memory pressure notifications.
+  // TODO: Consider a global eviction threshold  rather than per TrackBuffer.
   const uint32_t evict_threshold = 75 * (1 << 20);
   bool evicted = mTrackBuffer->EvictData(evict_threshold);
   if (evicted) {
     MSE_DEBUG("SourceBuffer(%p)::AppendData Evict; current buffered start=%f",
               this, GetBufferedStart());
 
     // We notify that we've evicted from the time range 0 through to
     // the current start point.
--- a/content/media/mediasource/SourceBufferResource.cpp
+++ b/content/media/mediasource/SourceBufferResource.cpp
@@ -142,17 +142,17 @@ SourceBufferResource::ReadFromCache(char
             this, aBuffer, aOffset, aCount);
   ReentrantMonitorAutoEnter mon(mMonitor);
   int64_t oldOffset = mOffset;
   nsresult rv = ReadAt(aOffset, aBuffer, aCount, nullptr);
   mOffset = oldOffset;
   return rv;
 }
 
-bool
+uint32_t
 SourceBufferResource::EvictData(uint32_t aThreshold)
 {
   SBR_DEBUG("SourceBufferResource(%p)::EvictData(aThreshold=%u)", this, aThreshold);
   ReentrantMonitorAutoEnter mon(mMonitor);
   return mInputBuffer.Evict(mOffset, aThreshold);
 }
 
 void
--- a/content/media/mediasource/SourceBufferResource.h
+++ b/content/media/mediasource/SourceBufferResource.h
@@ -60,16 +60,17 @@ public:
   virtual void StartSeekingForMetadata() MOZ_OVERRIDE { UNIMPLEMENTED(); }
   virtual void EndSeekingForMetadata() MOZ_OVERRIDE { UNIMPLEMENTED(); }
   virtual int64_t Tell() MOZ_OVERRIDE { return mOffset; }
   virtual void Pin() MOZ_OVERRIDE { UNIMPLEMENTED(); }
   virtual void Unpin() MOZ_OVERRIDE { UNIMPLEMENTED(); }
   virtual double GetDownloadRate(bool* aIsReliable) MOZ_OVERRIDE { UNIMPLEMENTED(); *aIsReliable = false; return 0; }
   virtual int64_t GetLength() MOZ_OVERRIDE { return mInputBuffer.GetLength(); }
   virtual int64_t GetNextCachedData(int64_t aOffset) MOZ_OVERRIDE {
+    ReentrantMonitorAutoEnter mon(mMonitor);
     MOZ_ASSERT(aOffset >= 0);
     if (uint64_t(aOffset) < mInputBuffer.GetOffset()) {
       return mInputBuffer.GetOffset();
     } else if (aOffset == GetLength()) {
       return -1;
     }
     return aOffset;
   }
@@ -78,16 +79,17 @@ public:
   virtual bool IsSuspendedByCache() MOZ_OVERRIDE { UNIMPLEMENTED(); return false; }
   virtual bool IsSuspended() MOZ_OVERRIDE { UNIMPLEMENTED(); return false; }
   virtual nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) MOZ_OVERRIDE;
   virtual bool IsTransportSeekable() MOZ_OVERRIDE { UNIMPLEMENTED(); return true; }
   virtual nsresult Open(nsIStreamListener** aStreamListener) MOZ_OVERRIDE { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
 
   virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) MOZ_OVERRIDE
   {
+    ReentrantMonitorAutoEnter mon(mMonitor);
     if (mInputBuffer.GetLength()) {
       aRanges.AppendElement(MediaByteRange(mInputBuffer.GetOffset(),
                                            mInputBuffer.GetLength()));
     }
     return NS_OK;
   }
 
   virtual const nsCString& GetContentType() const MOZ_OVERRIDE { return mType; }
@@ -109,22 +111,28 @@ public:
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   // Used by SourceBuffer.
   void AppendData(const uint8_t* aData, uint32_t aLength);
   void Ended();
   // Remove data from resource if it holds more than the threshold
-  // number of bytes. Returns true if some data was evicted.
-  bool EvictData(uint32_t aThreshold);
+  // number of bytes. Returns amount evicted.
+  uint32_t EvictData(uint32_t aThreshold);
 
   // Remove data from resource before the given offset.
   void EvictBefore(uint64_t aOffset);
 
+  // Returns the amount of data currently retained by this resource.
+  int64_t GetSize() {
+    ReentrantMonitorAutoEnter mon(mMonitor);
+    return mInputBuffer.GetLength() - mInputBuffer.GetOffset();
+  }
+
 #if defined(DEBUG)
   void Dump(const char* aPath) {
     mInputBuffer.Dump(aPath);
   }
 #endif
 
 private:
   ~SourceBufferResource();
--- a/content/media/mediasource/TrackBuffer.cpp
+++ b/content/media/mediasource/TrackBuffer.cpp
@@ -119,30 +119,46 @@ TrackBuffer::AppendData(const uint8_t* a
 
   return true;
 }
 
 bool
 TrackBuffer::EvictData(uint32_t aThreshold)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  // XXX Call EvictData on mDecoders?
-  return mCurrentDecoder->GetResource()->EvictData(aThreshold);
+
+  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 < mDecoders.Length(); ++i) {
+    MSE_DEBUG("TrackBuffer(%p)::EvictData decoder=%u threshold=%u toEvict=%lld",
+              this, i, aThreshold, toEvict);
+    toEvict -= mDecoders[i]->GetResource()->EvictData(toEvict);
+  }
+  return toEvict < (totalSize - aThreshold);
 }
 
 void
 TrackBuffer::EvictBefore(double aTime)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  // XXX Call EvictBefore on mDecoders?
-  int64_t endOffset = mCurrentDecoder->ConvertToByteOffset(aTime);
-  if (endOffset > 0) {
-    mCurrentDecoder->GetResource()->EvictBefore(endOffset);
+  for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
+    int64_t endOffset = mDecoders[i]->ConvertToByteOffset(aTime);
+    if (endOffset > 0) {
+      MSE_DEBUG("TrackBuffer(%p)::EvictBefore decoder=%u offset=%lld", this, i, endOffset);
+      mDecoders[i]->GetResource()->EvictBefore(endOffset);
+    }
   }
-  MSE_DEBUG("TrackBuffer(%p)::EvictBefore offset=%lld", this, endOffset);
 }
 
 double
 TrackBuffer::Buffered(dom::TimeRanges* aRanges)
 {
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
   MOZ_ASSERT(NS_IsMainThread());