mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 12:02:23 +02:00
ao_wasapi: Slightly improve timer accuracy
Use QueryPerformanceCounter to improve the accuracy of IAudioClock::GetPosition. While this is mainly for "realtime correctness" (usually the delay is a single sample or less), there are cases where IAudioClock::GetPosition takes a long time to return from its call (though the documentation doesn't define what a "long time" is), so correcting its value might be important in case the documented possible delay happens.
This commit is contained in:
parent
1d096f9f1b
commit
fe03981bbc
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user