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 5afa68835a
This commit is contained in:
Kevin Mitchell 2016-01-02 08:10:52 -08:00
parent d5f29a3c36
commit 9163bdc38a
1 changed files with 12 additions and 6 deletions

View File

@ -26,6 +26,7 @@
#include <endpointvolume.h> #include <endpointvolume.h>
#include <mmdeviceapi.h> #include <mmdeviceapi.h>
#include <avrt.h> #include <avrt.h>
#include <libavutil/mathematics.h>
#include "audio/out/ao_wasapi.h" #include "audio/out/ao_wasapi.h"
#include "audio/out/ao_wasapi_utils.h" #include "audio/out/ao_wasapi_utils.h"
@ -34,7 +35,7 @@
#include "osdep/timer.h" #include "osdep/timer.h"
#include "osdep/io.h" #include "osdep/io.h"
// naive av_rescale for unsigned
static UINT64 uint64_scale(UINT64 x, UINT64 num, UINT64 den) static UINT64 uint64_scale(UINT64 x, UINT64 num, UINT64 den)
{ {
return (x / den) * num 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 // inaccurate due to the length of the call
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370889%28v=vs.85%29.aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/dd370889%28v=vs.85%29.aspx
if (hr == S_FALSE) { if (hr == S_FALSE) {
MP_DBG(state, "Possibly inaccurate device position.\n"); MP_VERBOSE(state, "Possibly inaccurate device position.\n");
hr = S_OK; hr = S_OK;
} }
EXIT_ON_ERROR(hr); 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. . . // This should normally be very small (<1 us), but just in case. . .
LARGE_INTEGER qpc; LARGE_INTEGER qpc;
QueryPerformanceCounter(&qpc); QueryPerformanceCounter(&qpc);
// apparently, we're supposed to allow the qpc scale to overflow to be INT64 qpc_diff = av_rescale(qpc.QuadPart, 10000000, state->qpc_frequency.QuadPart)
// comparable to qpc_position (100ns units), so don't do anything fancy
INT64 qpc_diff = qpc.QuadPart * 10000000 / state->qpc_frequency.QuadPart
- qpc_position; - 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); MP_TRACE(state, "Device delay: %g us\n", *delay_us);