summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi.c
diff options
context:
space:
mode:
authorKevin Mitchell <kevmitch@gmail.com>2016-01-02 08:10:52 -0800
committerKevin Mitchell <kevmitch@gmail.com>2016-01-02 08:10:52 -0800
commit9163bdc38a69f36310303f8d491f0d6279d1a2f5 (patch)
treebbd3d619d10a3ce7f3c9845294aced0249c8785b /audio/out/ao_wasapi.c
parentd5f29a3c363582336755f9a46d41b89ddf174ed4 (diff)
downloadmpv-9163bdc38a69f36310303f8d491f0d6279d1a2f5.tar.bz2
mpv-9163bdc38a69f36310303f8d491f0d6279d1a2f5.tar.xz
ao_wasapi: fix delay calculation again
Apparently it's only wine where the qpc_position returned by IAudioClock_GetPosition can be overflowed. So actually do the rescaling correctly, but throw away the result if it looks unreasonable. this fixes a regression in 5afa68835ade9f21f9c709f791319bf9d2e35265
Diffstat (limited to 'audio/out/ao_wasapi.c')
-rw-r--r--audio/out/ao_wasapi.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 8e21bb3260..faea556157 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -26,6 +26,7 @@
#include <endpointvolume.h>
#include <mmdeviceapi.h>
#include <avrt.h>
+#include <libavutil/mathematics.h>
#include "audio/out/ao_wasapi.h"
#include "audio/out/ao_wasapi_utils.h"
@@ -34,7 +35,7 @@
#include "osdep/timer.h"
#include "osdep/io.h"
-
+// naive av_rescale for unsigned
static UINT64 uint64_scale(UINT64 x, UINT64 num, UINT64 den)
{
return (x / den) * num
@@ -52,7 +53,7 @@ static HRESULT get_device_delay(struct wasapi_state *state, double *delay_us) {
// inaccurate due to the length of the call
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370889%28v=vs.85%29.aspx
if (hr == S_FALSE) {
- MP_DBG(state, "Possibly inaccurate device position.\n");
+ MP_VERBOSE(state, "Possibly inaccurate device position.\n");
hr = S_OK;
}
EXIT_ON_ERROR(hr);
@@ -68,11 +69,16 @@ static HRESULT get_device_delay(struct wasapi_state *state, double *delay_us) {
// This should normally be very small (<1 us), but just in case. . .
LARGE_INTEGER qpc;
QueryPerformanceCounter(&qpc);
- // apparently, we're supposed to allow the qpc scale to overflow to be
- // comparable to qpc_position (100ns units), so don't do anything fancy
- INT64 qpc_diff = qpc.QuadPart * 10000000 / state->qpc_frequency.QuadPart
+ INT64 qpc_diff = av_rescale(qpc.QuadPart, 10000000, state->qpc_frequency.QuadPart)
- qpc_position;
- *delay_us -= qpc_diff / 10.0; // convert to us
+ // ignore the above calculation if it yeilds more than 10 seconds (due to
+ // possible overflow inside IAudioClock_GetPosition)
+ if (qpc_diff < 10 * 10000000) {
+ *delay_us -= qpc_diff / 10.0; // convert to us
+ } else {
+ MP_VERBOSE(state, "Insane qpc delay correction of %g seconds. "
+ "Ignoring it.\n", qpc_diff / 10000000.0);
+ }
MP_TRACE(state, "Device delay: %g us\n", *delay_us);