diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/out/ao_wasapi.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index fdca69c20c..39199159b3 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -121,6 +121,7 @@ typedef struct wasapi_state { IAudioClock *pAudioClock; UINT64 clock_frequency; /* scale for the "samples" returned by the clock */ UINT64 sample_count; /* the amount of samples per channel written to a GetBuffer buffer */ + LARGE_INTEGER qpc_frequency; /* frequency of windows' high resolution timer */ int opt_exclusive; int opt_list; @@ -528,6 +529,8 @@ static int init_clock(struct wasapi_state *state) { hr = IAudioClock_GetFrequency(state->pAudioClock, &state->clock_frequency); EXIT_ON_ERROR(hr); + QueryPerformanceFrequency(&state->qpc_frequency); + state->sample_count = 0; MP_VERBOSE(state, "IAudioClock::GetFrequency gave a frequency of %"PRIu64".\n", (uint64_t) state->clock_frequency); @@ -1362,19 +1365,25 @@ static int play(struct ao *ao, void **data, int samples, int flags) } static float get_device_delay(struct wasapi_state *state) { - /* where we pray that this hasn't desynced */ + /* where we pray that sample_count hasn't desynced */ mp_memory_barrier(); UINT64 sample_count = state->sample_count; - UINT64 position; + UINT64 position, qpc_position; HRESULT hr; - switch (hr = IAudioClock_GetPosition(state->pAudioClock, &position, NULL)) { + switch (hr = IAudioClock_GetPosition(state->pAudioClock, &position, &qpc_position)) { case S_OK: case S_FALSE: break; default: MP_ERR(state, "IAudioClock::GetPosition returned %s\n", explain_err(hr)); } + LARGE_INTEGER qpc_count; + QueryPerformanceCounter(&qpc_count); + UINT64 qpc_diff = (qpc_count.QuadPart * 10000000 / state->qpc_frequency.QuadPart) - qpc_position; + + position += state->clock_frequency * qpc_diff / 10000000; + /* convert position to the same base as sample_count */ position = position * state->format.Format.nSamplesPerSec / state->clock_frequency; |