Bug 1002994 - Remove array of old decoders from SourceBuffer, just keep a reference to the current decoder. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Mon, 28 Apr 2014 23:12:00 +1200
changeset 181083 acea3d22d5b0615b1995141b32e10bfa6f414bb4
parent 181082 6e01f4a0818114c5352383286bddb4ba76d85fc7
child 181084 b7be54db9ede942479967add1cda702624cc7384
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerscajbir
bugs1002994
milestone32.0a1
Bug 1002994 - Remove array of old decoders from SourceBuffer, just keep a reference to the current decoder. r=cajbir
content/media/mediasource/SourceBuffer.cpp
content/media/mediasource/SourceBuffer.h
--- a/content/media/mediasource/SourceBuffer.cpp
+++ b/content/media/mediasource/SourceBuffer.cpp
@@ -193,22 +193,18 @@ SourceBuffer::SetTimestampOffset(double 
 already_AddRefed<TimeRanges>
 SourceBuffer::GetBuffered(ErrorResult& aRv)
 {
   if (!IsAttached()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
   nsRefPtr<TimeRanges> ranges = new TimeRanges();
-  for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
-    nsRefPtr<TimeRanges> r = new TimeRanges();
-    mDecoders[i]->GetBuffered(r);
-    if (r->Length() > 0) {
-      ranges->Add(r->GetStartTime(), r->GetEndTime());
-    }
+  if (mDecoder) {
+    mDecoder->GetBuffered(ranges);
   }
   ranges->Normalize();
   return ranges.forget();
 }
 
 void
 SourceBuffer::SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv)
 {
@@ -265,20 +261,20 @@ SourceBuffer::Abort(ErrorResult& aRv)
   if (mUpdating) {
     // TODO: Abort segment parser loop, buffer append, and stream append loop algorithms.
     AbortUpdating();
   }
   // TODO: Run reset parser algorithm.
   mAppendWindowStart = 0;
   mAppendWindowEnd = PositiveInfinity<double>();
 
-  MSE_DEBUG("%p Abort: Discarding decoders.", this);
-  if (mCurrentDecoder) {
-    mCurrentDecoder->GetResource()->Ended();
-    mCurrentDecoder = nullptr;
+  MSE_DEBUG("%p Abort: Discarding decoder.", this);
+  if (mDecoder) {
+    mDecoder->GetResource()->Ended();
+    mDecoder = nullptr;
   }
 }
 
 void
 SourceBuffer::Remove(double aStart, double aEnd, ErrorResult& aRv)
 {
   MSE_DEBUG("%p Remove(Start=%f End=%f)", this, aStart, aEnd);
   if (!IsAttached() || mUpdating ||
@@ -295,26 +291,25 @@ SourceBuffer::Remove(double aStart, doub
   /// TODO: Run coded frame removal algorithm asynchronously (would call StopUpdating()).
   StopUpdating();
 }
 
 void
 SourceBuffer::Detach()
 {
   Ended();
-  mDecoders.Clear();
-  mCurrentDecoder = nullptr;
+  mDecoder = nullptr;
   mMediaSource = nullptr;
 }
 
 void
 SourceBuffer::Ended()
 {
-  for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
-    mDecoders[i]->GetResource()->Ended();
+  if (mDecoder) {
+    mDecoder->GetResource()->Ended();
   }
 }
 
 SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
   : DOMEventTargetHelper(aMediaSource->GetParentObject())
   , mMediaSource(aMediaSource)
   , mType(aType)
   , mAppendWindowStart(0)
@@ -336,18 +331,18 @@ already_AddRefed<SourceBuffer>
 SourceBuffer::Create(MediaSource* aMediaSource, const nsACString& aType)
 {
   nsRefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(aMediaSource, aType);
   return sourceBuffer.forget();
 }
 
 SourceBuffer::~SourceBuffer()
 {
-  for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
-    mDecoders[i]->GetResource()->Ended();
+  if (mDecoder) {
+    mDecoder->GetResource()->Ended();
   }
 }
 
 MediaSource*
 SourceBuffer::GetParentObject() const
 {
   return mMediaSource;
 }
@@ -376,21 +371,17 @@ SourceBuffer::QueueAsyncSimpleEvent(cons
 bool
 SourceBuffer::InitNewDecoder()
 {
   MediaSourceDecoder* parentDecoder = mMediaSource->GetDecoder();
   nsRefPtr<SubBufferDecoder> decoder = parentDecoder->CreateSubDecoder(mType);
   if (!decoder) {
     return false;
   }
-  mDecoders.AppendElement(decoder);
-  // XXX: At this point, we really want to push through any remaining
-  // processing for the old decoder and discard it, rather than hanging on
-  // to all of them in mDecoders.
-  mCurrentDecoder = decoder;
+  mDecoder = decoder;
   return true;
 }
 
 void
 SourceBuffer::StartUpdating()
 {
   MOZ_ASSERT(!mUpdating);
   mUpdating = true;
@@ -425,39 +416,39 @@ SourceBuffer::AppendData(const uint8_t* 
   }
   if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
     mMediaSource->SetReadyState(MediaSourceReadyState::Open);
   }
   // TODO: Run coded frame eviction algorithm.
   // TODO: Test buffer full flag.
   StartUpdating();
   // TODO: Run buffer append algorithm asynchronously (would call StopUpdating()).
-  if (mParser->IsInitSegmentPresent(aData, aLength) || !mCurrentDecoder) {
-    MSE_DEBUG("%p AppendBuffer: New initialization segment, switching decoders.", this);
-    if (mCurrentDecoder) {
-      mCurrentDecoder->GetResource()->Ended();
+  if (!mDecoder || mParser->IsInitSegmentPresent(aData, aLength)) {
+    MSE_DEBUG("%p AppendBuffer: New initialization segment, creating decoder.", this);
+    if (mDecoder) {
+      mDecoder->GetResource()->Ended();
     }
     if (!InitNewDecoder()) {
       aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
       return;
     }
   }
   // XXX: For future reference: NDA call must run on the main thread.
-  mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
-                                     aLength,
-                                     mCurrentDecoder->GetResource()->GetLength());
-  mCurrentDecoder->GetResource()->AppendData(aData, aLength);
+  mDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
+                              aLength,
+                              mDecoder->GetResource()->GetLength());
+  mDecoder->GetResource()->AppendData(aData, aLength);
 
   // 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 SourceBuffer's it knows
   // about.
   const int evict_threshold = 1000000;
-  bool evicted = mCurrentDecoder->GetResource()->EvictData(evict_threshold);
+  bool evicted = mDecoder->GetResource()->EvictData(evict_threshold);
   if (evicted) {
     double start = 0.0;
     double end = 0.0;
     GetBufferedStartEndTime(&start, &end);
 
     // We notify that we've evicted from the time range 0 through to
     // the current start point.
     mMediaSource->NotifyEvicted(0.0, start);
@@ -480,24 +471,25 @@ SourceBuffer::GetBufferedStartEndTime(do
   }
   *aStart = ranges->Start(0, dummy);
   *aEnd = ranges->End(ranges->Length() - 1, dummy);
 }
 
 void
 SourceBuffer::Evict(double aStart, double aEnd)
 {
-  for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
-    // Need to map time to byte offset then evict
-    int64_t end = mDecoders[i]->ConvertToByteOffset(aEnd);
-    if (end <= 0) {
-      NS_WARNING("SourceBuffer::Evict failed");
-      continue;
-    }
-    mDecoders[i]->GetResource()->EvictBefore(end);
+  if (!mDecoder) {
+    return;
+  }
+  // Need to map time to byte offset then evict
+  int64_t end = mDecoder->ConvertToByteOffset(aEnd);
+  if (end > 0) {
+    mDecoder->GetResource()->EvictBefore(end);
+  } else {
+    NS_WARNING("SourceBuffer::Evict failed");
   }
 }
 
 bool
 SourceBuffer::ContainsTime(double aTime)
 {
   ErrorResult dummy;
   nsRefPtr<TimeRanges> ranges = GetBuffered(dummy);
--- a/content/media/mediasource/SourceBuffer.h
+++ b/content/media/mediasource/SourceBuffer.h
@@ -135,20 +135,17 @@ private:
   void GetBufferedStartEndTime(double* aStart, double* aEnd);
 
   nsRefPtr<MediaSource> mMediaSource;
 
   const nsAutoCString mType;
 
   nsAutoPtr<ContainerParser> mParser;
 
-  // XXX: We only want to keep the current decoder alive, but need a way to
-  // query @buffered for everything this SourceBuffer is responsible for.
-  nsTArray<nsRefPtr<SubBufferDecoder>> mDecoders;
-  nsRefPtr<SubBufferDecoder> mCurrentDecoder;
+  nsRefPtr<SubBufferDecoder> mDecoder;
 
   double mAppendWindowStart;
   double mAppendWindowEnd;
 
   double mTimestampOffset;
 
   SourceBufferAppendMode mAppendMode;
   bool mUpdating;