Skip to content

Commit

Permalink
Bug 1307546 - Ensure we don't set timers with negative intervals in t…
Browse files Browse the repository at this point in the history
…o update A/V sync. r=jya

Our logic to do A/V sync sets a timer to drop expired frames based on the
start time of the next frame in the queue. If the frames in the queue are
badly muxed and don't have monotonically increasing start times, we can
end up setting a timer with a negative interval. This causes us to reevaluate
the frames in the VideoSink's queue immediately, set the same timer again,
and so we end up hot-looping.

This is a simple low-risk fix that detects when we're about to set a negative
interval timer, and instead sets the timer 1/30th of a second in the future.

This fix is deliberately low risk, such that it's suitable for uplift. I have
an idea how to do this better, but the lower risk this is most suitable for
uplift.

MozReview-Commit-ID: CDOqJJodx4l
  • Loading branch information
Chris Pearce committed Nov 4, 2016
1 parent bea7409 commit 5b3f815
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion dom/media/mediasink/VideoSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ 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;

VideoSink::VideoSink(AbstractThread* aThread,
MediaSink* aAudioSink,
MediaQueue<MediaData>& aVideoQueue,
Expand Down Expand Up @@ -441,8 +447,10 @@ VideoSink::UpdateRenderedVideoFrames()
}

int64_t nextFrameTime = frames[1]->mTime;
int64_t delta = (nextFrameTime > clockTime) ? (nextFrameTime - clockTime)
: FAILOVER_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] () {
Expand Down

0 comments on commit 5b3f815

Please sign in to comment.