1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-23 23:32:26 +00:00

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.
This commit is contained in:
Stefano Pigozzi 2014-07-02 22:47:54 +02:00
parent 703de5d84e
commit a6a4cd2c88

View File

@ -15,6 +15,8 @@
* with mpv. If not, see <http://www.gnu.org/licenses/>. * with mpv. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <CoreAudio/HostTime.h>
#include "config.h" #include "config.h"
#include "ao.h" #include "ao.h"
#include "internal.h" #include "internal.h"
@ -38,13 +40,29 @@ struct priv {
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap); 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, static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
const AudioTimeStamp *ts, UInt32 bus, const AudioTimeStamp *ts, UInt32 bus,
UInt32 frames, AudioBufferList *buffer_list) UInt32 frames, AudioBufferList *buffer_list)
{ {
struct ao *ao = ctx; struct ao *ao = ctx;
AudioBuffer buf = buffer_list->mBuffers[0]; 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; return noErr;
} }