Bug 1258922: [MSE] P2. Do not go over gap when attempting to find the next key frame. r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 05 May 2016 15:36:32 +1000
changeset 364218 8eac2aa70cc5a2f865db354123871097127e61db
parent 364217 c1bab0e789f52717ee981eb1f8e7a81fc531b12b
child 364219 657f9487efd8e3e441a7dea533e54536c0b8e926
push id17385
push userbmo:jyavenard@mozilla.com
push dateFri, 06 May 2016 06:40:44 +0000
reviewersgerald
bugs1258922
milestone49.0a1
Bug 1258922: [MSE] P2. Do not go over gap when attempting to find the next key frame. r?gerald MozReview-Commit-ID: EtK34PdzN4a
dom/media/mediasource/MediaSourceDemuxer.cpp
dom/media/mediasource/TrackBuffersManager.cpp
dom/media/mediasource/TrackBuffersManager.h
--- a/dom/media/mediasource/MediaSourceDemuxer.cpp
+++ b/dom/media/mediasource/MediaSourceDemuxer.cpp
@@ -332,17 +332,18 @@ MediaSourceTrackDemuxer::Reset()
   nsCOMPtr<nsIRunnable> task =
     NS_NewRunnableFunction([self] () {
       self->mNextSample.reset();
       self->mReset = true;
       self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
       {
         MonitorAutoLock mon(self->mMonitor);
         self->mNextRandomAccessPoint =
-          self->mManager->GetNextRandomAccessPoint(self->mType);
+          self->mManager->GetNextRandomAccessPoint(self->mType,
+                                                   MediaSourceDemuxer::EOS_FUZZ);
       }
     });
   mParent->GetTaskQueue()->Dispatch(task.forget());
 }
 
 nsresult
 MediaSourceTrackDemuxer::GetNextRandomAccessPoint(media::TimeUnit* aTime)
 {
@@ -405,17 +406,18 @@ MediaSourceTrackDemuxer::DoSeek(media::T
     mManager->GetSample(mType,
                         media::TimeUnit(),
                         error);
   MOZ_ASSERT(!error && sample);
   mNextSample = Some(sample);
   mReset = false;
   {
     MonitorAutoLock mon(mMonitor);
-    mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
+    mNextRandomAccessPoint =
+      mManager->GetNextRandomAccessPoint(mType, MediaSourceDemuxer::EOS_FUZZ);
   }
   return SeekPromise::CreateAndResolve(seekTime, __func__);
 }
 
 RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
 MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
 {
   if (mReset) {
@@ -446,17 +448,18 @@ MediaSourceTrackDemuxer::DoGetSamples(in
         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);
+    mNextRandomAccessPoint =
+      mManager->GetNextRandomAccessPoint(mType, MediaSourceDemuxer::EOS_FUZZ);
   }
   return SamplesPromise::CreateAndResolve(samples, __func__);
 }
 
 RefPtr<MediaSourceTrackDemuxer::SkipAccessPointPromise>
 MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(media::TimeUnit aTimeThreadshold)
 {
   bool found;
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -2064,30 +2064,39 @@ TrackBuffersManager::GetSample(TrackInfo
 
   MSE_DEBUG("Couldn't find sample (pts:%lld dts:%lld)",
              trackData.mNextSampleTime.ToMicroseconds(),
             trackData.mNextSampleTimecode.ToMicroseconds());
   return nullptr;
 }
 
 TimeUnit
-TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack)
+TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
+                                              const TimeUnit& aFuzz)
 {
   auto& trackData = GetTracksData(aTrack);
   MOZ_ASSERT(trackData.mNextGetSampleIndex.isSome());
   const TrackBuffersManager::TrackBuffer& track = GetTrackBuffer(aTrack);
 
   uint32_t i = trackData.mNextGetSampleIndex.ref();
+  TimeUnit nextSampleTimecode = trackData.mNextSampleTimecode;
+
   for (; i < track.Length(); i++) {
     const RefPtr<MediaRawData>& sample = track[i];
+    if (sample->mTimecode > (nextSampleTimecode + aFuzz).ToMicroseconds()) {
+      // Gap is too big. End of Stream or Waiting for Data.
+      break;
+    }
     if (sample->mKeyframe) {
       return TimeUnit::FromMicroseconds(sample->mTime);
     }
+    nextSampleTimecode =
+      TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
   }
-  return media::TimeUnit::FromInfinity();
+  return TimeUnit::FromInfinity();
 }
 
 void
 TrackBuffersManager::TrackData::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
 {
   for (TrackBuffer& buffer : mBuffers) {
     for (MediaRawData* data : buffer) {
       aSizes->mByteSize += data->SizeOfIncludingThis(aSizes->mMallocSizeOf);
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -140,17 +140,18 @@ public:
                        const media::TimeUnit& aTime,
                        const media::TimeUnit& aFuzz);
   uint32_t SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
                                        const media::TimeUnit& aTimeThreadshold,
                                        bool& aFound);
   already_AddRefed<MediaRawData> GetSample(TrackInfo::TrackType aTrack,
                                            const media::TimeUnit& aFuzz,
                                            bool& aError);
-  media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack);
+  media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
+                                           const media::TimeUnit& aFuzz);
 
   void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes);
 
 private:
   typedef MozPromise<bool, nsresult, /* IsExclusive = */ true> CodedFrameProcessingPromise;
 
   // for MediaSourceDemuxer::GetMozDebugReaderData
   friend class MediaSourceDemuxer;