Bug 1307546 - Give VideoSink a minimum update interval. r=jwwang,a=lizzard
authorChris Pearce <cpearce@mozilla.com>
Mon, 07 Nov 2016 16:21:58 +1300
changeset 358736 ea8a661310c1a210f9a09daed46186271cc54991
parent 358735 efcc8dbc5c3904c92b50c1f475dd110bc9ac197a
child 358737 94d52b7d3d048a05f67f2c3c1736e4f1bdf5eee3
push id1324
push usermtabara@mozilla.com
push dateMon, 16 Jan 2017 13:07:44 +0000
treeherdermozilla-release@a01c49833940 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang, lizzard
bugs1307546
milestone51.0a2
Bug 1307546 - Give VideoSink a minimum update interval. r=jwwang,a=lizzard 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,21 +19,19 @@ extern LazyLogModule gMediaDecoderLog;
 #define VSINK_LOG(...)   MOZ_LOG(gMediaDecoderLog, LogLevel::Debug,   (FMT(__VA_ARGS__)))
 #define VSINK_LOG_V(...) MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(__VA_ARGS__)))
 #define DUMP_LOG(...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(FMT(__VA_ARGS__)).get(), nullptr, nullptr, -1)
 
 using namespace mozilla::layers;
 
 namespace media {
 
-// For badly muxed files, if we try to set a timeout to discard expired
-// frames, but the start time of the next frame is less than the clock time,
-// we instead just set a timeout FAILOVER_UPDATE_INTERVAL_US in the future,
-// and run UpdateRenderedVideoFrames() then.
-static const int64_t FAILOVER_UPDATE_INTERVAL_US = 1000000 / 30;
+// 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)
@@ -442,18 +440,17 @@ 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 = (nextFrameTime > clockTime) ? (nextFrameTime - clockTime)
-                                              : FAILOVER_UPDATE_INTERVAL_US;
+  int64_t delta = std::max<int64_t>((nextFrameTime - clockTime), MIN_UPDATE_INTERVAL_US);
   TimeStamp target = nowTime + TimeDuration::FromMicroseconds(
      delta / mAudioSink->GetPlaybackParams().mPlaybackRate);
 
   RefPtr<VideoSink> self = this;
   mUpdateScheduler.Ensure(target, [self] () {
     self->UpdateRenderedVideoFramesByTimer();
   }, [self] () {
     self->UpdateRenderedVideoFramesByTimer();