Bug 1199879: [MSE] Use latest demux end time to detect discontinuities. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sat, 29 Aug 2015 17:34:08 +1000
changeset 259967 cec04b5766f9a46d02fd0234ad88973b105b613e
parent 259966 ae64d16898395607093db2e2dd667b6544cb1f55
child 259968 3f5637c65b9a922b880929bc20fbfaa6bece6f13
push id29296
push userryanvm@gmail.com
push dateSun, 30 Aug 2015 19:45:10 +0000
treeherdermozilla-central@2ad5077d86ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1199879
milestone43.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 1199879: [MSE] Use latest demux end time to detect discontinuities. r=gerald The ContainerParser doesn't always return an accurate end time.
dom/media/mediasource/TrackBuffersManager.cpp
dom/media/mediasource/TrackBuffersManager.h
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -707,19 +707,16 @@ TrackBuffersManager::SegmentParserLoop()
         if (newData || !mParser->MediaSegmentRange().IsNull()) {
           if (mPendingInputBuffer) {
             // We now have a complete media segment header. We can resume parsing
             // the data.
             AppendDataToCurrentInputBuffer(mPendingInputBuffer);
             mPendingInputBuffer = nullptr;
           }
           mNewMediaSegmentStarted = false;
-          if (newData) {
-            mLastParsedEndTime = Some(TimeUnit::FromMicroseconds(end));
-          }
         } else {
           // We don't have any data to demux yet, stash aside the data.
           // This also handles the case:
           // 2. If the input buffer does not contain a complete media segment header yet, then jump to the need more data step below.
           if (!mPendingInputBuffer) {
             mPendingInputBuffer = mInputBuffer;
           } else {
             mPendingInputBuffer->AppendElements(*mInputBuffer);
@@ -867,18 +864,16 @@ TrackBuffersManager::OnDemuxerResetDone(
   if (mPendingInputBuffer) {
     // We had a partial media segment header stashed aside.
     // Reparse its content so we can continue parsing the current input buffer.
     int64_t start, end;
     mParser->ParseStartAndEndTimestamps(mPendingInputBuffer, start, end);
     mProcessedInput += mPendingInputBuffer->Length();
   }
 
-  mLastParsedEndTime.reset();
-
   SegmentParserLoop();
 }
 
 void
 TrackBuffersManager::AppendDataToCurrentInputBuffer(MediaByteBuffer* aData)
 {
   MOZ_ASSERT(mCurrentInputBuffer);
   int64_t offset = mCurrentInputBuffer->GetLength();
@@ -1313,16 +1308,19 @@ TrackBuffersManager::CompleteCodedFrameP
   }
 
   // 5. If the input buffer does not contain a complete media segment, then jump to the need more data step below.
   if (mParser->MediaSegmentRange().IsNull()) {
     ResolveProcessing(true, __func__);
     return;
   }
 
+  mLastParsedEndTime = Some(std::max(mAudioTracks.mLastParsedEndTime,
+                                     mVideoTracks.mLastParsedEndTime));
+
   // 6. Remove the media segment bytes from the beginning of the input buffer.
   // Clear our demuxer from any already processed data.
   // As we have handled a complete media segment, it is safe to evict all data
   // from the resource.
   mCurrentInputBuffer->EvictAll();
   mInputDemuxer->NotifyDataRemoved();
   RecreateParser(true);
 
@@ -1392,26 +1390,36 @@ TrackBuffersManager::ProcessFrames(Track
   TrackBuffer samples; // array that will contain the frames to be added
                        // to our track buffer.
 
   // We assume that no frames are contiguous within a media segment and as such
   // don't need to check for discontinuity except for the first frame and should
   // a frame be ignored due to the target window.
   bool needDiscontinuityCheck = true;
 
+  if (aSamples.Length()) {
+    aTrackData.mLastParsedEndTime = TimeUnit();
+  }
+
   for (auto& sample : aSamples) {
     SAMPLE_DEBUG("Processing %s frame(pts:%lld end:%lld, dts:%lld, duration:%lld, "
                "kf:%d)",
                aTrackData.mInfo->mMimeType.get(),
                sample->mTime,
                sample->GetEndTime(),
                sample->mTimecode,
                sample->mDuration,
                sample->mKeyframe);
 
+    const TimeUnit sampleEndTime =
+      TimeUnit::FromMicroseconds(sample->GetEndTime());
+    if (sampleEndTime > aTrackData.mLastParsedEndTime) {
+      aTrackData.mLastParsedEndTime = sampleEndTime;
+    }
+
     // We perform step 10 right away as we can't do anything should a keyframe
     // be needed until we have one.
 
     // 10. If the need random access point flag on track buffer equals true, then run the following steps:
     if (trackBuffer.mNeedRandomAccessPoint) {
       // 1. If the coded frame is not a random access point, then drop the coded frame and jump to the top of the loop to start processing the next coded frame.
       if (!sample->mKeyframe) {
         continue;
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -235,16 +235,19 @@ private:
     // Need random access point flag variable that keeps track of whether the
     // track buffer is waiting for a random access point coded frame.
     // The variable is initially set to true to indicate that random access
     // point coded frame is needed before anything can be added to the track
     // buffer.
     bool mNeedRandomAccessPoint;
     nsRefPtr<MediaTrackDemuxer> mDemuxer;
     MozPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest;
+    // Highest end timestamp of the last media segment demuxed.
+    media::TimeUnit mLastParsedEndTime;
+
     // If set, position where the next contiguous frame will be inserted.
     // If a discontinuity is detected, it will be unset and recalculated upon
     // the next insertion.
     Maybe<size_t> mNextInsertionIndex;
     // Samples just demuxed, but not yet parsed.
     TrackBuffer mQueuedSamples;
     // We only manage a single track of each type at this time.
     nsTArray<TrackBuffer> mBuffers;