Bug 1307546 - Give VideoSink a minimum update interval. r?jwwang draft
authorChris Pearce <cpearce@mozilla.com>
Mon, 07 Nov 2016 16:21:58 +1300
changeset 434961 21046b40a4e3b0666e2e965c3feae879af392aaa
parent 434959 23a49e0512799cf8b723caa1d21df43caa721e04
child 536178 7bce3cd0710e59cd8fcdd1b18ccf7ddfadc18c4f
push id34893
push usercpearce@mozilla.com
push dateMon, 07 Nov 2016 20:30:17 +0000
reviewersjwwang
bugs1307546
milestone52.0a1
Bug 1307546 - Give VideoSink a minimum update interval. r?jwwang Without this, we can end up with very short, or even negative, update intervals, meaning we unnecessarily use CPU when we can't actually advance the playback position. MozReview-Commit-ID: 6H32uVCyCll
dom/media/mediasink/VideoSink.cpp
--- a/dom/media/mediasink/VideoSink.cpp
+++ b/dom/media/mediasink/VideoSink.cpp
@@ -19,16 +19,20 @@ extern LazyLogModule gMediaDecoderLog;
 #define VSINK_LOG(x, ...)   MOZ_LOG(gMediaDecoderLog, LogLevel::Debug,   (FMT(x, ##__VA_ARGS__)))
 #define VSINK_LOG_V(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(x, ##__VA_ARGS__)))
 #define DUMP_LOG(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(FMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
 
 using namespace mozilla::layers;
 
 namespace media {
 
+// Minimum update frequency is 1/120th of a second, i.e. half the
+// duration of a 60-fps frame.
+static const int64_t MIN_UPDATE_INTERVAL_US = 1000000 / (60 * 2);
+
 VideoSink::VideoSink(AbstractThread* aThread,
                      MediaSink* aAudioSink,
                      MediaQueue<MediaData>& aVideoQueue,
                      VideoFrameContainer* aContainer,
                      FrameStatistics& aFrameStats,
                      uint32_t aVQueueSentToCompositerSize)
   : mOwnerThread(aThread)
   , mAudioSink(aAudioSink)
@@ -436,18 +440,19 @@ VideoSink::UpdateRenderedVideoFrames()
   // we will run render loops again upon incoming frames.
   nsTArray<RefPtr<MediaData>> frames;
   VideoQueue().GetFirstElements(2, &frames);
   if (frames.Length() < 2) {
     return;
   }
 
   int64_t nextFrameTime = frames[1]->mTime;
+  int64_t delta = std::max<int64_t>((nextFrameTime - clockTime), MIN_UPDATE_INTERVAL_US);
   TimeStamp target = nowTime + TimeDuration::FromMicroseconds(
-    (nextFrameTime - clockTime) / mAudioSink->GetPlaybackParams().mPlaybackRate);
+     delta / mAudioSink->GetPlaybackParams().mPlaybackRate);
 
   RefPtr<VideoSink> self = this;
   mUpdateScheduler.Ensure(target, [self] () {
     self->UpdateRenderedVideoFramesByTimer();
   }, [self] () {
     self->UpdateRenderedVideoFramesByTimer();
   });
 }