Bug 1229987: [MSE] P1. Ensure next random access point properly calculated after seek. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sun, 06 Dec 2015 08:51:34 -0800
changeset 276910 1efca40406f1
parent 276909 d5cd24a0cf59
child 276911 cb3d56df0a47
push id29810
push usercbook@mozilla.com
push dateFri, 18 Dec 2015 14:24:54 +0000
treeherdermozilla-central@c5cb194cc9cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1229987
milestone46.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 1229987: [MSE] P1. Ensure next random access point properly calculated after seek. r=gerald When seeking, the next keyframe time would always be set to the seek time (as the next sample to be retrieved would be a keyframe). This could lead to the next key frame logic to be activated too aggressively.
dom/media/mediasource/MediaSourceDemuxer.cpp
dom/media/mediasource/MediaSourceDemuxer.h
--- a/dom/media/mediasource/MediaSourceDemuxer.cpp
+++ b/dom/media/mediasource/MediaSourceDemuxer.cpp
@@ -290,17 +290,17 @@ MediaSourceDemuxer::GetMozDebugReaderDat
 
 MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
                                                  TrackInfo::TrackType aType,
                                                  TrackBuffersManager* aManager)
   : mParent(aParent)
   , mManager(aManager)
   , mType(aType)
   , mMonitor("MediaSourceTrackDemuxer")
-  , mLastSeek(Some(TimeUnit()))
+  , mReset(true)
 {
 }
 
 UniquePtr<TrackInfo>
 MediaSourceTrackDemuxer::GetInfo() const
 {
   return mParent->GetTrackInfo(mType)->Clone();
 }
@@ -323,17 +323,18 @@ MediaSourceTrackDemuxer::GetSamples(int3
 
 void
 MediaSourceTrackDemuxer::Reset()
 {
   MOZ_ASSERT(mParent, "Called after BreackCycle()");
   RefPtr<MediaSourceTrackDemuxer> self = this;
   nsCOMPtr<nsIRunnable> task =
     NS_NewRunnableFunction([self] () {
-      self->mLastSeek = Some(TimeUnit());
+      self->mNextSample.reset();
+      self->mReset = true;
       self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
       {
         MonitorAutoLock mon(self->mMonitor);
         self->mNextRandomAccessPoint =
           self->mManager->GetNextRandomAccessPoint(self->mType);
       }
     });
   mParent->GetTaskQueue()->Dispatch(task.forget());
@@ -375,59 +376,68 @@ MediaSourceTrackDemuxer::BreakCycles()
 
 RefPtr<MediaSourceTrackDemuxer::SeekPromise>
 MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
 {
   TimeIntervals buffered = mManager->Buffered(mType);
   buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
 
   if (!buffered.Contains(aTime)) {
-    mLastSeek = Some(aTime);
     // We don't have the data to seek to.
     return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
                                         __func__);
   }
   TimeUnit seekTime =
     mManager->Seek(mType, aTime, MediaSourceDemuxer::EOS_FUZZ);
+  bool error;
+  RefPtr<MediaRawData> sample =
+    mManager->GetSample(mType,
+                        media::TimeUnit(),
+                        error);
+  MOZ_ASSERT(!error && sample);
+  mNextSample = Some(sample);
+  mReset = false;
   {
     MonitorAutoLock mon(mMonitor);
     mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
   }
-  mLastSeek = Some(aTime);
   return SeekPromise::CreateAndResolve(seekTime, __func__);
 }
 
 RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
 MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
 {
-  if (mLastSeek) {
+  if (mReset) {
     // If a seek (or reset) was recently performed, we ensure that the data
     // we are about to retrieve is still available.
     TimeIntervals buffered = mManager->Buffered(mType);
     buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
 
-    if (!buffered.Contains(mLastSeek.ref())) {
+    if (!buffered.Contains(TimeUnit::FromMicroseconds(0))) {
       return SamplesPromise::CreateAndReject(
         mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
                               DemuxerFailureReason::WAITING_FOR_DATA, __func__);
     }
-    mLastSeek.reset();
+    mReset = false;
   }
-  bool error;
-  RefPtr<MediaRawData> sample =
-    mManager->GetSample(mType,
-                        MediaSourceDemuxer::EOS_FUZZ,
-                        error);
-  if (!sample) {
-    if (error) {
-      return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
+  bool error = false;
+  RefPtr<MediaRawData> sample;
+  if (mNextSample) {
+    sample = mNextSample.ref();
+    mNextSample.reset();
+  } else {
+    sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, error);
+    if (!sample) {
+      if (error) {
+        return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
+      }
+      return SamplesPromise::CreateAndReject(
+        mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
+                              DemuxerFailureReason::WAITING_FOR_DATA, __func__);
     }
-    return SamplesPromise::CreateAndReject(
-      mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
-                            DemuxerFailureReason::WAITING_FOR_DATA, __func__);
   }
   RefPtr<SamplesHolder> samples = new SamplesHolder;
   samples->mSamples.AppendElement(sample);
   if (mNextRandomAccessPoint.ToMicroseconds() <= sample->mTime) {
     MonitorAutoLock mon(mMonitor);
     mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
   }
   return SamplesPromise::CreateAndResolve(samples, __func__);
--- a/dom/media/mediasource/MediaSourceDemuxer.h
+++ b/dom/media/mediasource/MediaSourceDemuxer.h
@@ -124,14 +124,17 @@ private:
   media::TimeUnit GetNextRandomAccessPoint();
 
   RefPtr<MediaSourceDemuxer> mParent;
   RefPtr<TrackBuffersManager> mManager;
   TrackInfo::TrackType mType;
   // Monitor protecting members below accessed from multiple threads.
   Monitor mMonitor;
   media::TimeUnit mNextRandomAccessPoint;
-  Maybe<media::TimeUnit> mLastSeek;
+  Maybe<RefPtr<MediaRawData>> mNextSample;
+  // Set to true following a reset. Ensure that the next sample demuxed
+  // is available at position 0.
+  bool mReset;
 };
 
 } // namespace mozilla
 
 #endif