Bug 1174588: P2. Properly handle removal of data within the current coded frame group. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 15 Jun 2015 15:28:42 +1000
changeset 280493 b3f78edbfbe327bd662cf298146320a14307a2aa
parent 280492 c2e4889a65a1a28511668e293430e6b666584fed
child 280494 e3004d414d5ee504e48bf527e7177ff81923f589
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1174588
milestone41.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 1174588: P2. Properly handle removal of data within the current coded frame group. r=gerald W3C bug pending.
dom/media/mediasource/TrackBuffersManager.cpp
dom/media/mediasource/TrackBuffersManager.h
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -289,31 +289,26 @@ TrackBuffersManager::FinishCodedFramePro
 
 void
 TrackBuffersManager::CompleteResetParserState()
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(!mAppendRunning);
   MSE_DEBUG("");
 
-  for (auto track : GetTracksList()) {
+  for (auto& track : GetTracksList()) {
     // 2. Unset the last decode timestamp on all track buffers.
-    track->mLastDecodeTimestamp.reset();
     // 3. Unset the last frame duration on all track buffers.
-    track->mLastFrameDuration.reset();
     // 4. Unset the highest end timestamp on all track buffers.
-    track->mHighestEndTimestamp.reset();
     // 5. Set the need random access point flag on all track buffers to true.
-    track->mNeedRandomAccessPoint = true;
+    track->ResetAppendState();
 
     // if we have been aborted, we may have pending frames that we are going
     // to discard now.
     track->mQueuedSamples.Clear();
-    track->mLongestFrameDuration.reset();
-    track->mNextInsertionIndex.reset();
   }
   // 6. Remove all bytes from the input buffer.
   mIncomingBuffers.Clear();
   mInputBuffer = nullptr;
   if (mCurrentInputBuffer) {
     mCurrentInputBuffer->EvictAll();
     mCurrentInputBuffer = new SourceBufferResource(mType);
   }
@@ -453,16 +448,19 @@ TrackBuffersManager::CodedFrameRemoval(T
     if (end < track->mBufferedRanges.GetEnd()) {
       for (auto& frame : track->mBuffers.LastElement()) {
         if (frame->mKeyframe && frame->mTime >= end.ToMicroseconds()) {
           removeEndTimestamp = TimeUnit::FromMicroseconds(frame->mTime);
           break;
         }
       }
     }
+
+    bool removeCurrentCodedFrameGroup = false;
+
     // 3. Remove all media data, from this track buffer, that contain starting
     // timestamps greater than or equal to start and less than the remove end timestamp.
     TimeInterval removedInterval;
     Maybe<uint32_t> firstRemovedIndex;
     TrackBuffer& data = track->mBuffers.LastElement();
     for (uint32_t i = 0; i < data.Length();) {
       const auto& frame = data[i];
       if (frame->mTime >= start.ToMicroseconds() &&
@@ -474,19 +472,21 @@ TrackBuffersManager::CodedFrameRemoval(T
           firstRemovedIndex = Some(i);
         } else {
           removedInterval = removedInterval.Span(
             TimeInterval(TimeUnit::FromMicroseconds(frame->mTime),
                          TimeUnit::FromMicroseconds(frame->mTime + frame->mDuration)));
         }
         track->mSizeBuffer -= sizeof(*frame) + frame->mSize;
         data.RemoveElementAt(i);
-        MOZ_ASSERT(track->mNextInsertionIndex.isNothing() ||
-                   track->mNextInsertionIndex.ref() != i);
-        if (track->mNextInsertionIndex.isSome() &&
+        removeCurrentCodedFrameGroup |=
+          track->mNextInsertionIndex.isSome() &&
+          track->mNextInsertionIndex.ref() == i;
+        if (!removeCurrentCodedFrameGroup &&
+            track->mNextInsertionIndex.isSome() &&
             track->mNextInsertionIndex.ref() > i) {
           track->mNextInsertionIndex.ref()--;
         }
       } else {
         i++;
       }
     }
     // 4. Remove decoding dependencies of the coded frames removed in the previous step:
@@ -500,29 +500,34 @@ TrackBuffersManager::CodedFrameRemoval(T
           break;
         }
         removedInterval = removedInterval.Span(
           TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
                        TimeUnit::FromMicroseconds(sample->GetEndTime())));
         track->mSizeBuffer -= sizeof(*sample) + sample->mSize;
       }
       data.RemoveElementsAt(start, end - start);
-      MOZ_ASSERT(track->mNextInsertionIndex.isNothing() ||
-                 track->mNextInsertionIndex.ref() <= start ||
-                 track->mNextInsertionIndex.ref() >= end);
-      if (track->mNextInsertionIndex.isSome() &&
+      removeCurrentCodedFrameGroup |=
+        track->mNextInsertionIndex.isSome() &&
+        track->mNextInsertionIndex.ref() >= start &&
+        track->mNextInsertionIndex.ref() < end;
+      if (!removeCurrentCodedFrameGroup &&
+          track->mNextInsertionIndex.isSome() &&
           track->mNextInsertionIndex.ref() >= end) {
         track->mNextInsertionIndex.ref() -= end - start;
       }
 
       MSE_DEBUG("Removing undecodable frames from:%u (frames:%d) ([%f, %f))",
                 start, end - start,
                 removedInterval.mStart.ToSeconds(), removedInterval.mEnd.ToSeconds());
       track->mBufferedRanges -= removedInterval;
       dataRemoved = true;
+      if (removeCurrentCodedFrameGroup) {
+        track->ResetAppendState();
+      }
     }
 
     // 5. If this object is in activeSourceBuffers, the current playback position
     // is greater than or equal to start and less than the remove end timestamp,
     // and HTMLMediaElement.readyState is greater than HAVE_METADATA, then set the
     // HTMLMediaElement.readyState attribute to HAVE_METADATA and stall playback.
     // This will be done by the MDSM during playback.
     // TODO properly, so it works even if paused.
@@ -1254,26 +1259,20 @@ TrackBuffersManager::ProcessFrame(MediaR
     }
     // 1b. If mode equals "sequence":
     if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) {
       // Set group start timestamp equal to the group end timestamp.
       mGroupStartTimestamp = Some(mGroupEndTimestamp);
     }
     for (auto& track : tracks) {
       // 2. Unset the last decode timestamp on all track buffers.
-      track->mLastDecodeTimestamp.reset();
       // 3. Unset the last frame duration on all track buffers.
-      track->mLastFrameDuration.reset();
       // 4. Unset the highest end timestamp on all track buffers.
-      track->mHighestEndTimestamp.reset();
       // 5. Set the need random access point flag on all track buffers to true.
-      track->mNeedRandomAccessPoint = true;
-
-      track->mLongestFrameDuration.reset();
-      track->mNextInsertionIndex.reset();
+      track->ResetAppendState();
     }
 
     MSE_DEBUG("Discontinuity detected. Restarting process");
     // 6. Jump to the Loop Top step above to restart processing of the current coded frame.
     return true;
   }
 
   // 7. Let frame end timestamp equal the sum of presentation timestamp and frame duration.
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -220,16 +220,27 @@ private:
     // occupied by the coded frames currently stored in the track buffer.
     TimeIntervals mBufferedRanges;
     // Byte size of all samples contained in this track buffer.
     uint32_t mSizeBuffer;
     // TrackInfo of the first metadata received.
     nsRefPtr<SharedTrackInfo> mInfo;
     // TrackInfo of the last metadata parsed (updated with each init segment.
     nsRefPtr<SharedTrackInfo> mLastInfo;
+
+    void ResetAppendState()
+    {
+      mLastDecodeTimestamp.reset();
+      mLastFrameDuration.reset();
+      mHighestEndTimestamp.reset();
+      mNeedRandomAccessPoint = true;
+
+      mLongestFrameDuration.reset();
+      mNextInsertionIndex.reset();
+    }
   };
 
   bool ProcessFrame(MediaRawData* aSample, TrackData& aTrackData);
   void RejectProcessing(nsresult aRejectValue, const char* aName);
   void ResolveProcessing(bool aResolveValue, const char* aName);
   MediaPromiseRequestHolder<CodedFrameProcessingPromise> mProcessingRequest;
   MediaPromiseHolder<CodedFrameProcessingPromise> mProcessingPromise;