From e4aaaf69dfc4d6537cb23b2904b238601f6da2fd Mon Sep 17 00:00:00 2001 From: Kevin Mitchell Date: Sun, 23 Nov 2014 00:15:53 -0800 Subject: ao/wasapi: make get_device_delay return an error code --- audio/out/ao_wasapi.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index b328fd61b2..dd862d27b7 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -36,18 +36,19 @@ #include "osdep/timer.h" #include "osdep/io.h" -static double get_device_delay(struct wasapi_state *state) { +static HRESULT get_device_delay(struct wasapi_state *state, double *delay) { UINT64 sample_count = atomic_load(&state->sample_count); UINT64 position, qpc_position; HRESULT hr; - switch (hr = IAudioClock_GetPosition(state->pAudioClock, &position, &qpc_position)) { - case S_OK: case S_FALSE: - break; - default: - MP_ERR(state, "IAudioClock::GetPosition returned %s (0x%"PRIx32")\n", - wasapi_explain_err(hr), (uint32_t)hr); + hr = IAudioClock_GetPosition(state->pAudioClock, &position, &qpc_position); + /* GetPosition succeeded, but the result may be 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"); + hr = S_OK; } + EXIT_ON_ERROR(hr); LARGE_INTEGER qpc_count; QueryPerformanceCounter(&qpc_count); @@ -59,11 +60,15 @@ static double get_device_delay(struct wasapi_state *state) { position = position * state->format.Format.nSamplesPerSec / state->clock_frequency; double diff = sample_count - position; - double delay = diff / state->format.Format.nSamplesPerSec; + *delay = diff / state->format.Format.nSamplesPerSec; - MP_TRACE(state, "Device delay: %g samples (%g ms)\n", diff, delay * 1000); + MP_TRACE(state, "Device delay: %g samples (%g ms)\n", diff, *delay * 1000); - return delay; + return S_OK; +exit_label: + MP_ERR(state, "Error getting device delay: %s (0x%"PRIx32")\n", + wasapi_explain_err(hr), (uint32_t)hr); + return hr; } static void thread_feed(struct ao *ao) @@ -81,6 +86,9 @@ static void thread_feed(struct ao *ao) frame_count -= padding; MP_TRACE(ao, "Frame to fill: %"PRIu32". Padding: %"PRIu32"\n", frame_count, padding); } + double delay; + hr = get_device_delay(state, &delay); + EXIT_ON_ERROR(hr); BYTE *pData; hr = IAudioRenderClient_GetBuffer(state->pRenderClient, @@ -88,9 +96,10 @@ static void thread_feed(struct ao *ao) EXIT_ON_ERROR(hr); BYTE *data[1] = {pData}; + ao_read_data(ao, (void**)data, frame_count, (int64_t) ( - mp_time_us() + get_device_delay(state) * 1e6 + - frame_count * 1e6 / state->format.Format.nSamplesPerSec)); + mp_time_us() + delay * 1e6 + + frame_count * 1e6 / state->format.Format.nSamplesPerSec)); hr = IAudioRenderClient_ReleaseBuffer(state->pRenderClient, frame_count, 0); -- cgit v1.2.3