summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2014-07-03 19:05:22 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2014-07-03 20:05:15 +0200
commit97f6d7f4ec255f126d76fb6d3bc0d60f0e23f7b6 (patch)
tree49c0a74286b990a823bb30ed9f937809757c69be
parent29b047da6fd504329117c680cd8fd4ff53f587c8 (diff)
downloadmpv-97f6d7f4ec255f126d76fb6d3bc0d60f0e23f7b6.tar.bz2
mpv-97f6d7f4ec255f126d76fb6d3bc0d60f0e23f7b6.tar.xz
ao_coreaudio: report hardware latency to ao_read_data
Commit a6a4cd2c88 added reporting of playout latency, this commit also adds support for reporting hardware and constant audio unit latency.
-rw-r--r--audio/out/ao_coreaudio.c45
-rw-r--r--audio/out/ao_coreaudio_properties.h1
2 files changed, 43 insertions, 3 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index b2d78aa872..7e5b3377c4 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -32,6 +32,8 @@ struct priv {
AudioDeviceID device;
AudioUnit audio_unit;
+ uint64_t hw_latency_us;
+
// options
int opt_device_id;
int opt_list;
@@ -40,6 +42,41 @@ struct priv {
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap);
+static int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
+{
+ return frames / (float) ao->samplerate * 1e6;
+}
+
+static int64_t ca_get_hardware_latency(struct ao *ao) {
+ struct priv *p = ao->priv;
+
+ double audiounit_latency_sec = 0.0;
+ uint32_t size = sizeof(audiounit_latency_sec);
+ OSStatus err = AudioUnitGetProperty(
+ p->audio_unit,
+ kAudioUnitProperty_Latency,
+ kAudioUnitScope_Global,
+ 0,
+ &audiounit_latency_sec,
+ &size);
+ CHECK_CA_ERROR("cannot get audio unit latency");
+
+ uint32_t frames = 0;
+ err = CA_GET_O(p->device, kAudioDevicePropertyLatency, &frames);
+ CHECK_CA_ERROR("cannot get device latency");
+
+ uint64_t audiounit_latency_us = audiounit_latency_sec * 1e6;
+ uint64_t device_latency_us = ca_frames_to_us(ao, frames);
+
+ MP_VERBOSE(ao, "audiounit latency [us]: %lld\n", audiounit_latency_us);
+ MP_VERBOSE(ao, "device latency [us]: %lld\n", device_latency_us);
+
+ return audiounit_latency_us + device_latency_us;
+
+coreaudio_error:
+ return 0;
+}
+
static int64_t ca_get_latency(const AudioTimeStamp *ts)
{
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
@@ -56,12 +93,12 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
UInt32 frames, AudioBufferList *buffer_list)
{
struct ao *ao = ctx;
+ struct priv *p = ao->priv;
AudioBuffer buf = buffer_list->mBuffers[0];
- const int64_t playback_us = frames / (float) ao->samplerate * 1e6;
- const int64_t latency_us = ca_get_latency(ts);
+ int64_t end = mp_time_us();
+ end += p->hw_latency_us + ca_get_latency(ts) + ca_frames_to_us(ao, frames);
- const int64_t end = mp_time_us() + playback_us + latency_us;
ao_read_data(ao, &buf.mData, frames, end);
return noErr;
}
@@ -219,6 +256,8 @@ static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd)
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"can't link audio unit to selected device");
+ p->hw_latency_us = ca_get_hardware_latency(ao);
+
AURenderCallbackStruct render_cb = (AURenderCallbackStruct) {
.inputProc = render_cb_lpcm,
.inputProcRefCon = ao,
diff --git a/audio/out/ao_coreaudio_properties.h b/audio/out/ao_coreaudio_properties.h
index e48b75871e..8a41944746 100644
--- a/audio/out/ao_coreaudio_properties.h
+++ b/audio/out/ao_coreaudio_properties.h
@@ -37,6 +37,7 @@ OSStatus ca_set(AudioObjectID id, ca_scope scope, ca_sel selector,
#define CA_GET(id, sel, data) ca_get(id, CA_GLOBAL, sel, sizeof(*(data)), data)
#define CA_SET(id, sel, data) ca_set(id, CA_GLOBAL, sel, sizeof(*(data)), data)
+#define CA_GET_O(id, sel, data) ca_get(id, CA_OUTPUT, sel, sizeof(*(data)), data)
OSStatus ca_get_ary(AudioObjectID id, ca_scope scope, ca_sel selector,
uint32_t element_size, void **data, size_t *elements);