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
--- 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();
});
}