Bug 866561 - Enable high precision timers on Windows when playing video. r=kinetik
authorChris Pearce <cpearce@mozilla.com>
Fri, 03 May 2013 12:39:19 +1200
changeset 130709 9b75691bf6368ef9063d593732e52fc68d8126ff
parent 130708 11bbf55bbad1c7d05f3e5d03c5a62e84feb79fcb
child 130710 2b56dbd338cf54d8ac13676bf7269a18029c83e4
push id1579
push userphilringnalda@gmail.com
push dateSat, 04 May 2013 04:38:04 +0000
treeherderfx-team@a56432a42a41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs866561
milestone23.0a1
Bug 866561 - Enable high precision timers on Windows when playing video. r=kinetik
content/media/MediaDecoderStateMachine.cpp
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -1,13 +1,19 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
+#ifdef XP_WIN
+// Include Windows headers required for enabling high precision timers.
+#include "Windows.h"
+#include "Mmsystem.h"
+#endif
+ 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/StandardInteger.h"
 #include "mozilla/Util.h"
 
 #include "MediaDecoderStateMachine.h"
 #include <limits>
 #include "AudioStream.h"
 #include "nsTArray.h"
@@ -416,16 +422,24 @@ MediaDecoderStateMachine::MediaDecoderSt
   // of at least 4.
   mAmpleVideoFrames = Preferences::GetUint("media.video-queue.default-size", 3);
 #else
   mAmpleVideoFrames = Preferences::GetUint("media.video-queue.default-size", 10);
 #endif
   if (mAmpleVideoFrames < 2) {
     mAmpleVideoFrames = 2;
   }
+#ifdef XP_WIN
+  // Ensure high precision timers are enabled on Windows, otherwise the state
+  // machine thread isn't woken up at reliable intervals to set the next frame,
+  // and we drop frames while painting. Note that multiple calls to this
+  // function per-process is OK, provided each call is matched by a corresponding
+  // timeEndPeriod() call.
+  timeBeginPeriod(1);
+#endif
 }
 
 MediaDecoderStateMachine::~MediaDecoderStateMachine()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   MOZ_COUNT_DTOR(MediaDecoderStateMachine);
   NS_ASSERTION(!mPendingWakeDecoder.get(),
                "WakeDecoder should have been revoked already");
@@ -434,16 +448,19 @@ MediaDecoderStateMachine::~MediaDecoderS
   NS_ASSERTION(!mRequestedNewDecodeThread,
     "Should not have (or flagged) a pending request for a new decode thread");
   if (mTimer)
     mTimer->Cancel();
   mTimer = nullptr;
   mReader = nullptr;
  
   StateMachineTracker::Instance().CleanupGlobalStateMachine();
+#ifdef XP_WIN
+  timeEndPeriod(1);
+#endif
 }
 
 bool MediaDecoderStateMachine::HasFutureAudio() const {
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   NS_ASSERTION(HasAudio(), "Should only call HasFutureAudio() when we have audio");
   // We've got audio ready to play if:
   // 1. We've not completed playback of audio, and
   // 2. we either have more than the threshold of decoded audio available, or