[vlc-commits] coreaudio: finer audio delay
Thomas Guillem
git at videolan.org
Wed Mar 14 14:50:50 CET 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Wed Mar 14 14:49:30 2018 +0100| [feaa3e792b259099771987635f5cdc8f56d776af] | committer: Thomas Guillem
coreaudio: finer audio delay
This is a partial revert of f18fef325af25113875b09c8f727017febc6198a
This commit fixes the delay imprecision that was depending on the number of
frames asked by the render callback. This also fixes audio glitches (due to
flush/resampling) when this number of frames was changed (when the screen is
OFF for example).
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=feaa3e792b259099771987635f5cdc8f56d776af
---
modules/audio_output/auhal.c | 5 ++++-
modules/audio_output/coreaudio_common.c | 37 ++++++++++++++++++++++++---------
modules/audio_output/coreaudio_common.h | 7 ++++---
3 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index d221e08ce3..1306542cfd 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -983,7 +983,10 @@ RenderCallbackSPDIF(AudioDeviceID inDevice, const AudioTimeStamp * inNow,
uint8_t *p_output = outOutputData->mBuffers[p_sys->i_stream_index].mData;
size_t i_size = outOutputData->mBuffers[p_sys->i_stream_index].mDataByteSize;
- ca_Render(p_aout, 0, p_output, i_size);
+ uint64_t i_host_time = (inNow->mFlags & kAudioTimeStampHostTimeValid)
+ ? inNow->mHostTime : 0;
+
+ ca_Render(p_aout, 0, i_host_time, p_output, i_size);
return noErr;
}
diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c
index 1dd80812c8..da1ba1a8c9 100644
--- a/modules/audio_output/coreaudio_common.c
+++ b/modules/audio_output/coreaudio_common.c
@@ -26,6 +26,7 @@
#import <CoreAudio/CoreAudioTypes.h>
#import <dlfcn.h>
+#import <mach/mach_time.h>
static struct
{
@@ -33,6 +34,8 @@ static struct
void (*unlock)(os_unfair_lock *lock);
} unfair_lock;
+static mach_timebase_info_data_t tinfo;
+
static inline uint64_t
BytesToFrames(struct aout_sys_common *p_sys, size_t i_bytes)
{
@@ -66,6 +69,9 @@ ca_init_once(void)
unfair_lock.unlock = dlsym(RTLD_DEFAULT, "os_unfair_lock_unlock");
if (!unfair_lock.unlock)
unfair_lock.lock = NULL;
+
+ if (mach_timebase_info(&tinfo) != KERN_SUCCESS)
+ tinfo.numer = tinfo.denom = 0;
}
static void
@@ -131,15 +137,15 @@ ca_Close(audio_output_t *p_aout)
/* Called from render callbacks. No lock, wait, and IO here */
void
-ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint8_t *p_output,
- size_t i_requested)
+ca_Render(audio_output_t *p_aout, uint32_t i_frames, uint64_t i_host_time,
+ uint8_t *p_output, size_t i_requested)
{
struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
lock_lock(p_sys);
- p_sys->b_highlatency = CLOCK_FREQ * (uint64_t)i_nb_samples / p_sys->i_rate
- > AOUT_MAX_PTS_DELAY;
+ p_sys->i_render_host_time = i_host_time;
+ p_sys->i_render_frames = i_frames;
if (p_sys->b_do_flush)
{
@@ -201,14 +207,19 @@ ca_TimeGet(audio_output_t *p_aout, mtime_t *delay)
struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
lock_lock(p_sys);
- if (p_sys->b_highlatency)
+
+ if (tinfo.denom == 0 || p_sys->i_render_host_time == 0)
{
lock_unlock(p_sys);
return -1;
}
- int64_t i_frames = BytesToFrames(p_sys, p_sys->i_out_size);
- *delay = FramesToUs(p_sys, i_frames) + p_sys->i_dev_latency_us;
+ const uint64_t i_render_time_us = p_sys->i_render_host_time
+ * tinfo.numer / tinfo.denom / 1000;
+
+ const int64_t i_out_frames = BytesToFrames(p_sys, p_sys->i_out_size);
+ *delay = FramesToUs(p_sys, i_out_frames + p_sys->i_render_frames)
+ + p_sys->i_dev_latency_us + i_render_time_us - mdate();
lock_unlock(p_sys);
return 0;
@@ -249,10 +260,12 @@ ca_Flush(audio_output_t *p_aout, bool wait)
p_sys->b_do_flush = true;
lock_unlock(p_sys);
vlc_sem_wait(&p_sys->flush_sem);
- return;
+ lock_lock(p_sys);
}
}
+ p_sys->i_render_host_time = 0;
+ p_sys->i_render_frames = 0;
lock_unlock(p_sys);
}
@@ -347,7 +360,8 @@ ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
p_sys->i_underrun_size = 0;
p_sys->b_paused = false;
- p_sys->b_highlatency = true;
+ p_sys->i_render_host_time = 0;
+ p_sys->i_render_frames = 0;
p_sys->i_rate = fmt->i_rate;
p_sys->i_bytes_per_frame = fmt->i_bytes_per_frame;
@@ -460,7 +474,10 @@ RenderCallback(void *p_data, AudioUnitRenderActionFlags *ioActionFlags,
VLC_UNUSED(inTimeStamp);
VLC_UNUSED(inBusNumber);
- ca_Render(p_data, inNumberFrames, ioData->mBuffers[0].mData,
+ uint64_t i_host_time = (inTimeStamp->mFlags & kAudioTimeStampHostTimeValid)
+ ? inTimeStamp->mHostTime : 0;
+
+ ca_Render(p_data, inNumberFrames, i_host_time, ioData->mBuffers[0].mData,
ioData->mBuffers[0].mDataByteSize);
return noErr;
diff --git a/modules/audio_output/coreaudio_common.h b/modules/audio_output/coreaudio_common.h
index d78b1f43ae..eaf21e7621 100644
--- a/modules/audio_output/coreaudio_common.h
+++ b/modules/audio_output/coreaudio_common.h
@@ -52,12 +52,13 @@ struct aout_sys_common
size_t i_underrun_size;
bool b_paused;
bool b_do_flush;
- bool b_highlatency;
size_t i_out_max_size;
size_t i_out_size;
block_t *p_out_chain;
block_t **pp_out_last;
+ uint64_t i_render_host_time;
+ uint32_t i_render_frames;
vlc_sem_t flush_sem;
@@ -83,8 +84,8 @@ void ca_Open(audio_output_t *p_aout);
void ca_Close(audio_output_t *p_aout);
-void ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint8_t *p_output,
- size_t i_requested);
+void ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint64_t i_host_time,
+ uint8_t *p_output, size_t i_requested);
int ca_TimeGet(audio_output_t *p_aout, mtime_t *delay);
More information about the vlc-commits
mailing list