Bug 1295630 - Provide a way for A/V sync to be ruined, so talos can test compositor throughput by painting expired frames. r?mattwoodrow
In
bug 1258870 I changed the media code so that we dropped all late video
frames. Without this, our A/V sync was broken when the decode was struggling
to keep up, and we weren't reporting dropped frames when the decode couldn't
keep up, and so players couldn't adapt to a bitrate which the decode could keep
up on.
However, dropping all late frames broke talos tests which relied on the old
behaviour of us rendering video frames that were late. So this patch adds a
pref to cause the frame dropping code to not drop the last frame in the
queue, so there will always be something for the compositor to composit. This
means talos will once again be able to test how fast it can composit frames
that aren't supposed to be drawn.
The pref is media.ruin-av-sync.enabled.
It defaults to false.
MozReview-Commit-ID: J3VvpzoDRmI
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -87,16 +87,19 @@ private:
// This is where DECL_MEDIA_PREF for each of the preferences should go.
// AudioSink
DECL_MEDIA_PREF("accessibility.monoaudio.enable", MonoAudio, bool, false);
DECL_MEDIA_PREF("media.resampling.enabled", AudioSinkResampling, bool, false);
DECL_MEDIA_PREF("media.resampling.rate", AudioSinkResampleRate, uint32_t, 48000);
DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, true);
+ // VideoSink
+ DECL_MEDIA_PREF("media.ruin-av-sync.enabled", RuinAvSync, bool, false);
+
// PlatformDecoderModule
DECL_MEDIA_PREF("media.apple.forcevda", AppleForceVDA, bool, false);
DECL_MEDIA_PREF("media.gmp.insecure.allow", GMPAllowInsecure, bool, false);
DECL_MEDIA_PREF("media.gmp.async-shutdown-timeout", GMPAsyncShutdownTimeout, uint32_t, GMP_DEFAULT_ASYNC_SHUTDOWN_TIMEOUT);
DECL_MEDIA_PREF("media.eme.enabled", EMEEnabled, bool, false);
DECL_MEDIA_PREF("media.use-blank-decoder", PDMUseBlankDecoder, bool, false);
#ifdef MOZ_GONK_MEDIACODEC
DECL_MEDIA_PREF("media.gonk.enabled", PDMGonkDecoderEnabled, bool, true);
--- a/dom/media/mediasink/VideoSink.cpp
+++ b/dom/media/mediasink/VideoSink.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaQueue.h"
#include "VideoSink.h"
+#include "MediaPrefs.h"
namespace mozilla {
extern LazyLogModule gMediaDecoderLog;
#define VSINK_LOG(msg, ...) \
MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, \
("VideoSink=%p " msg, this, ##__VA_ARGS__))
#define VSINK_LOG_V(msg, ...) \
@@ -32,16 +33,17 @@ VideoSink::VideoSink(AbstractThread* aTh
, mVideoQueue(aVideoQueue)
, mContainer(aContainer)
, mProducerID(ImageContainer::AllocateProducerID())
, mFrameStats(aFrameStats)
, mVideoFrameEndTime(-1)
, mHasVideo(false)
, mUpdateScheduler(aThread)
, mVideoQueueSendToCompositorSize(aVQueueSentToCompositerSize)
+ , mMinVideoQueueSize(MediaPrefs::RuinAvSync() ? 1 : 0)
{
MOZ_ASSERT(mAudioSink, "AudioSink should exist.");
}
VideoSink::~VideoSink()
{
}
@@ -389,17 +391,17 @@ VideoSink::UpdateRenderedVideoFrames()
// Get the current playback position.
TimeStamp nowTime;
const int64_t clockTime = mAudioSink->GetPosition(&nowTime);
NS_ASSERTION(clockTime >= 0, "Should have positive clock time.");
// Skip frames up to the playback position.
int64_t lastDisplayedFrameEndTime = 0;
- while (VideoQueue().GetSize() > 0 &&
+ while (VideoQueue().GetSize() > mMinVideoQueueSize &&
clockTime > VideoQueue().PeekFront()->GetEndTime()) {
RefPtr<MediaData> frame = VideoQueue().PopFront();
if (frame->As<VideoData>()->mSentToCompositor) {
lastDisplayedFrameEndTime = frame->GetEndTime();
mFrameStats.NotifyPresentedFrame();
} else {
mFrameStats.NotifyDecodedFrames({ 0, 0, 1 });
VSINK_LOG_V("discarding video frame mTime=%lld clock_time=%lld",
--- a/dom/media/mediasink/VideoSink.h
+++ b/dom/media/mediasink/VideoSink.h
@@ -134,14 +134,23 @@ private:
bool mHasVideo;
// Used to trigger another update of rendered frames in next round.
DelayedScheduler mUpdateScheduler;
// Max frame number sent to compositor at a time.
// Based on the pref value obtained in MDSM.
const uint32_t mVideoQueueSendToCompositorSize;
+
+ // Talos tests for the compositor require at least one frame in the
+ // video queue so that the compositor has something to composit during
+ // the talos test when the decode is stressed. We have a minimum size
+ // on the video queue in order to facilitate this talos test.
+ // Note: Normal playback should not have a queue size of more than 0,
+ // otherwise A/V sync will be ruined! *Only* make this non-zero for
+ // testing purposes.
+ const uint32_t mMinVideoQueueSize;
};
} // namespace media
} // namespace mozilla
#endif