From 9163bdc38a69f36310303f8d491f0d6279d1a2f5 Mon Sep 17 00:00:00 2001 From: Kevin Mitchell Date: Sat, 2 Jan 2016 08:10:52 -0800 Subject: 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 --- audio/out/ao_wasapi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'audio/out/ao_wasapi.c') 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 #include #include +#include #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); -- cgit v1.2.3