Bug 1259916: [MSE] P3. Simplify eviction calculation logic. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 28 Mar 2016 00:58:37 +1100
changeset 290692 bcd0f253bb32a6d1db5235dd03ab5996b6e0efbf
parent 290691 732f589f694e3a5af43dacf868523bde606f5e62
child 290693 9ea30db3cc3ad403f9463daa33c12db524760088
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1259916
milestone48.0a1
Bug 1259916: [MSE] P3. Simplify eviction calculation logic. r=gerald Also, remove no longer used code and update comments to properly reflect the current algorithms used. MozReview-Commit-ID: GwsGC70xM85
dom/media/mediasource/SourceBuffer.cpp
dom/media/mediasource/TrackBuffersManager.cpp
dom/media/mediasource/TrackBuffersManager.h
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -503,35 +503,26 @@ SourceBuffer::PrepareAppend(const uint8_
     return nullptr;
   }
 
   if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
     mMediaSource->SetReadyState(MediaSourceReadyState::Open);
   }
 
   // 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.
+  // number of bytes then data is evicted.
   // TODO: Drive evictions off memory pressure notifications.
   // TODO: Consider a global eviction threshold  rather than per TrackBuffer.
-  TimeUnit newBufferStartTime;
-  // Attempt to evict the amount of data we are about to add by lowering the
-  // threshold.
+  // Give a chance to the TrackBuffersManager to evict some data if needed.
   Result evicted =
     mTrackBuffersManager->EvictData(TimeUnit::FromSeconds(mMediaSource->GetDecoder()->GetCurrentTime()),
-                                    aLength, &newBufferStartTime);
+                                    aLength);
 
   // See if we have enough free space to append our new data.
-  // As we can only evict once we have playable data, we must give a chance
-  // to the DASH player to provide a complete media segment.
-  if (aLength > mTrackBuffersManager->EvictionThreshold() ||
-      evicted == Result::BUFFER_FULL) {
+  if (evicted == Result::BUFFER_FULL) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return nullptr;
   }
 
   RefPtr<MediaByteBuffer> data = new MediaByteBuffer();
   if (!data->AppendElements(aData, aLength, fallible)) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return nullptr;
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -294,24 +294,25 @@ TrackBuffersManager::RangeRemoval(TimeUn
   mEnded = false;
 
   return InvokeAsync(GetTaskQueue(), this, __func__,
                      &TrackBuffersManager::CodedFrameRemovalWithPromise,
                      TimeInterval(aStart, aEnd));
 }
 
 TrackBuffersManager::EvictDataResult
-TrackBuffersManager::EvictData(TimeUnit aPlaybackTime,
-                               int64_t aThresholdReduct,
-                               TimeUnit* aBufferStartTime)
+TrackBuffersManager::EvictData(const TimeUnit& aPlaybackTime, int64_t aSize)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  const int64_t toEvict = GetSize() -
-    std::max(EvictionThreshold() - aThresholdReduct, aThresholdReduct);
+  if (aSize > EvictionThreshold()) {
+    // We're adding more data than we can hold.
+    return EvictDataResult::BUFFER_FULL;
+  }
+  const int64_t toEvict = GetSize() + aSize - EvictionThreshold();
 
   MSE_DEBUG("buffered=%lldkb, eviction threshold=%ukb, evict=%lldkb",
             GetSize() / 1024, EvictionThreshold() / 1024, toEvict / 1024);
 
   if (toEvict <= 0) {
     return EvictDataResult::NO_DATA_EVICTED;
   }
   if (toEvict <= 512*1024) {
@@ -364,17 +365,17 @@ TrackBuffersManager::Buffered()
     }
     // 3. Let new intersection ranges equal the intersection between the intersection ranges and the track ranges.
     intersection.Intersection(*trackRanges);
   }
   return intersection;
 }
 
 int64_t
-TrackBuffersManager::GetSize()
+TrackBuffersManager::GetSize() const
 {
   return mSizeSourceBuffer;
 }
 
 void
 TrackBuffersManager::Ended()
 {
   mEnded = true;
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -100,32 +100,29 @@ public:
   // 3.5.2 Reset Parser State
   void ResetParserState(SourceBufferAttributes& aAttributes);
 
   // Queue a task to run the MSE range removal algorithm.
   // http://w3c.github.io/media-source/#sourcebuffer-coded-frame-removal
   RefPtr<RangeRemovalPromise> RangeRemoval(media::TimeUnit aStart,
                                              media::TimeUnit aEnd);
 
-  // Evicts data up to aPlaybackTime. aThreshold is used to
-  // bound the data being evicted. It will not evict more than aThreshold
-  // bytes. aBufferStartTime contains the new start time of the data after the
-  // eviction.
-  EvictDataResult
-  EvictData(media::TimeUnit aPlaybackTime,
-            int64_t aThresholdReduct,
-            media::TimeUnit* aBufferStartTime);
+  // Schedule data eviction if necessary as the next call to AppendData will
+  // add aSize bytes.
+  // Eviction is done in two steps, first remove data up to aPlaybackTime
+  // and if still more space is needed remove from the end.
+  EvictDataResult EvictData(const media::TimeUnit& aPlaybackTime, int64_t aSize);
 
   // Returns the buffered range currently managed.
   // This may be called on any thread.
   // Buffered must conform to http://w3c.github.io/media-source/index.html#widl-SourceBuffer-buffered
   media::TimeIntervals Buffered();
 
   // Return the size of the data managed by this SourceBufferContentManager.
-  int64_t GetSize();
+  int64_t GetSize() const;
 
   // Indicate that the MediaSource parent object got into "ended" state.
   void Ended();
 
   // The parent SourceBuffer is about to be destroyed.
   void Detach();
 
   int64_t EvictionThreshold() const;