Bug 1375922 - don't send frames to the compositor if the 1st one is a future frame. r=cpearce

A/V sync will be broken for the compositor will render the 1st frame
immediately without considering its timestamp.

MozReview-Commit-ID: 6j7GLccrFcX

--HG--
extra : rebase_source : 924a2404d8d944262d1f8744794a072c051ac556
extra : source : 1e254ff8491084b66dfebbb2e1be03790c95ed11
This commit is contained in:
JW Wang 2017-07-03 11:51:39 +08:00
Родитель 2aa281e7d2
Коммит 147505b83d
1 изменённых файлов: 27 добавлений и 3 удалений

Просмотреть файл

@ -307,10 +307,34 @@ void
VideoSink::TryUpdateRenderedVideoFrames()
{
AssertOwnerThread();
if (!mUpdateScheduler.IsScheduled() && VideoQueue().GetSize() >= 1 &&
mAudioSink->IsPlaying()) {
UpdateRenderedVideoFrames();
if (mUpdateScheduler.IsScheduled() || !mAudioSink->IsPlaying()) {
return;
}
RefPtr<VideoData> v = VideoQueue().PeekFront();
if (!v) {
// No frames to render.
return;
}
TimeStamp nowTime;
const TimeUnit clockTime = mAudioSink->GetPosition(&nowTime);
if (clockTime >= v->mTime) {
// Time to render this frame.
UpdateRenderedVideoFrames();
return;
}
// If we send this future frame to the compositor now, it will be rendered
// immediately and break A/V sync. Instead, we schedule a timer to send it
// later.
int64_t delta = (v->mTime - clockTime).ToMicroseconds() /
mAudioSink->GetPlaybackParams().mPlaybackRate;
TimeStamp target = nowTime + TimeDuration::FromMicroseconds(delta);
RefPtr<VideoSink> self = this;
mUpdateScheduler.Ensure(
target,
[self]() { self->UpdateRenderedVideoFramesByTimer(); },
[self]() { self->UpdateRenderedVideoFramesByTimer(); });
}
void