Bug 1262727: [webm] Ensure first frame returned after seek is a keyframe. r=kinetik
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 07 Apr 2016 17:40:16 +1000
changeset 292549 bfc6effa82c927220624909dee8bd4f989e38f2a
parent 292548 98aa2df1a69fed6d725ff45446838a063869112f
child 292550 713fb70e2d8b66859d87a157810a74b2de620db1
push id30162
push usercbook@mozilla.com
push dateMon, 11 Apr 2016 09:46:31 +0000
treeherdermozilla-central@e847cfcb315f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1262727
milestone48.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 1262727: [webm] Ensure first frame returned after seek is a keyframe. r=kinetik Same after a reset or the first frame ever returned by the demuxer. MozReview-Commit-ID: 6b7XlIk5GE4
dom/media/webm/WebMDemuxer.cpp
dom/media/webm/WebMDemuxer.h
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -809,16 +809,17 @@ bool WebMDemuxer::GetOffsetForTime(uint6
 
 
 //WebMTrackDemuxer
 WebMTrackDemuxer::WebMTrackDemuxer(WebMDemuxer* aParent,
                                    TrackInfo::TrackType aType,
                                    uint32_t aTrackNumber)
   : mParent(aParent)
   , mType(aType)
+  , mNeedKeyframe(true)
 {
   mInfo = mParent->GetTrackInfo(aType, aTrackNumber);
   MOZ_ASSERT(mInfo);
 }
 
 WebMTrackDemuxer::~WebMTrackDemuxer()
 {
   mSamples.Reset();
@@ -835,16 +836,17 @@ WebMTrackDemuxer::Seek(media::TimeUnit a
 {
   // Seeks to aTime. Upon success, SeekPromise will be resolved with the
   // actual time seeked to. Typically the random access point time
 
   media::TimeUnit seekTime = aTime;
   mSamples.Reset();
   mParent->SeekInternal(aTime);
   mParent->GetNextPacket(mType, &mSamples);
+  mNeedKeyframe = true;
 
   // Check what time we actually seeked to.
   if (mSamples.GetSize() > 0) {
     const RefPtr<MediaRawData>& sample = mSamples.First();
     seekTime = media::TimeUnit::FromMicroseconds(sample->mTime);
   }
   SetNextKeyFrameTime();
 
@@ -870,16 +872,20 @@ WebMTrackDemuxer::GetSamples(int32_t aNu
     return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
   }
 
   while (aNumSamples) {
     RefPtr<MediaRawData> sample(NextSample());
     if (!sample) {
       break;
     }
+    if (mNeedKeyframe && !sample->mKeyframe) {
+      continue;
+    }
+    mNeedKeyframe = false;
     samples->mSamples.AppendElement(sample);
     aNumSamples--;
   }
 
   if (samples->mSamples.IsEmpty()) {
     return SamplesPromise::CreateAndReject(DemuxerFailureReason::END_OF_STREAM, __func__);
   } else {
     UpdateSamples(samples->mSamples);
@@ -946,16 +952,17 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
   }
 }
 
 void
 WebMTrackDemuxer::Reset()
 {
   mSamples.Reset();
   media::TimeIntervals buffered = GetBuffered();
+  mNeedKeyframe = true;
   if (buffered.Length()) {
     WEBM_DEBUG("Seek to start point: %f", buffered.Start(0).ToSeconds());
     mParent->SeekInternal(buffered.Start(0));
     SetNextKeyFrameTime();
   } else {
     mNextKeyframeTime.reset();
   }
 }
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -237,16 +237,17 @@ private:
   ~WebMTrackDemuxer();
   void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
   void SetNextKeyFrameTime();
   RefPtr<MediaRawData> NextSample ();
   RefPtr<WebMDemuxer> mParent;
   TrackInfo::TrackType mType;
   UniquePtr<TrackInfo> mInfo;
   Maybe<media::TimeUnit> mNextKeyframeTime;
+  bool mNeedKeyframe;
 
   // Queued samples extracted by the demuxer, but not yet returned.
   MediaRawDataQueue mSamples;
 };
 
 } // namespace mozilla
 
 #endif