From a6a4cd2c889d1cb2d2d6779102c5430fdc1c437c Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 2 Jul 2014 22:47:54 +0200 Subject: [PATCH] ao_coreaudio: report latency more correctly Previous code was completly wrong. This still doesn't report the device latency, but we report the buffer latency (as before the AO refactoring) and the AudioUnit's latency (this is a new 'feature'). Apparently we can also report the device actual latency and we should also calculate the actual sample rate of the audio device instead of using the nominal sample rate, but I'll leave this for a later commit. --- audio/out/ao_coreaudio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 59846cd605..b2d78aa872 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -15,6 +15,8 @@ * with mpv. If not, see . */ +#include + #include "config.h" #include "ao.h" #include "internal.h" @@ -38,13 +40,29 @@ struct priv { bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, struct mp_chmap *chmap); +static int64_t ca_get_latency(const AudioTimeStamp *ts) +{ + uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime); + uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + + if (now > out) + return 0; + + return (out - now) * 1e-3; +} + static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags, const AudioTimeStamp *ts, UInt32 bus, UInt32 frames, AudioBufferList *buffer_list) { struct ao *ao = ctx; AudioBuffer buf = buffer_list->mBuffers[0]; - ao_read_data(ao, &buf.mData, frames, ts->mSampleTime); + + const int64_t playback_us = frames / (float) ao->samplerate * 1e6; + const int64_t latency_us = ca_get_latency(ts); + + const int64_t end = mp_time_us() + playback_us + latency_us; + ao_read_data(ao, &buf.mData, frames, end); return noErr; }