[vlc-commits] wasapi: do not assume mdate() returns the performance counter

Rémi Denis-Courmont git at videolan.org
Mon Sep 3 13:36:34 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Sep  3 14:34:13 2012 +0300| [eb7da3f02bc22f8f14c3d6cfa95b271e356de7be] | committer: Rémi Denis-Courmont

wasapi: do not assume mdate() returns the performance counter

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=eb7da3f02bc22f8f14c3d6cfa95b271e356de7be
---

 modules/audio_output/wasapi.c |   38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
index 8eeda67..73e9de0 100644
--- a/modules/audio_output/wasapi.c
+++ b/modules/audio_output/wasapi.c
@@ -26,6 +26,7 @@
 #define COBJMACROS
 #define CONST_VTABLE
 
+#include <stdlib.h>
 #include <assert.h>
 #include <audioclient.h>
 #include <audiopolicy.h>
@@ -55,6 +56,36 @@ vlc_module_begin()
     set_callbacks(Open, Close)
 vlc_module_end()
 
+static LARGE_INTEGER freq; /* performance counters frequency */
+
+BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID); /* avoid warning */
+
+BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
+{
+    (void) dll;
+    (void) reserved;
+
+    switch (reason)
+    {
+        case DLL_PROCESS_ATTACH:
+            if (!QueryPerformanceFrequency(&freq))
+                return FALSE;
+            break;
+    }
+    return TRUE;
+}
+
+static UINT64 GetQPC(void)
+{
+    LARGE_INTEGER counter;
+
+    if (!QueryPerformanceCounter(&counter))
+        abort();
+
+    lldiv_t d = lldiv(counter.QuadPart, freq.QuadPart);
+    return (d.quot * 10000000) + ((d.rem * 10000000) / freq.QuadPart);
+}
+
 static int TryEnter(vlc_object_t *obj)
 {
     HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
@@ -107,12 +138,13 @@ static void Play(audio_output_t *aout, block_t *block, mtime_t *restrict drift)
     {
         UINT64 pos, qpcpos;
 
-        /* NOTE: this assumes mdate() uses QPC() (which it currently does). */
         hr = IAudioClock_GetPosition(sys->clock, &pos, &qpcpos);
         if (SUCCEEDED(hr))
         {
-            qpcpos = (qpcpos + 5) / 10; /* 100ns -> 1µs */
-            *drift = mdate() - qpcpos;
+            qpcpos = GetQPC() - qpcpos;
+            static_assert((10000000 % CLOCK_FREQ) == 0,
+                          "Frequency conversion broken");
+            *drift = qpcpos / (10000000 / CLOCK_FREQ);
         }
         else
             msg_Warn(aout, "cannot get position (error 0x%lx)", hr);



More information about the vlc-commits mailing list