Bug 1295630 - Provide a way for A/V sync to be ruined, so talos can test compositor throughput by painting expired frames. r=mattwoodrow, a=ritu
authorChris Pearce <cpearce@mozilla.com>
Fri, 19 Aug 2016 21:34:42 +1200
changeset 350216 7852ac7e74faf5a637189437ce0a9a7f39e6292c
parent 350215 3c621f8c782957aeda376304afe884139b7ee49a
child 350217 94326655773401f7bb034d8fca8bf607319fe76b
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, ritu
bugs1295630, 1258870
milestone50.0a2
Bug 1295630 - Provide a way for A/V sync to be ruined, so talos can test compositor throughput by painting expired frames. r=mattwoodrow, a=ritu 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
dom/media/MediaPrefs.h
dom/media/mediasink/VideoSink.cpp
dom/media/mediasink/VideoSink.h
--- 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