diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c index d221e08ce33cb501977de3a8456851512eefa505..1306542cfdff869e28cedd46027ce53901ebf11e 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 1dd80812c89590b8d901de8a618c6a9505889211..da1ba1a8c9e6ebdd8041b38694c55e25fa2a82ab 100644 --- a/modules/audio_output/coreaudio_common.c +++ b/modules/audio_output/coreaudio_common.c @@ -26,6 +26,7 @@ #import #import +#import 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 d78b1f43aeb4c67301fe13482ce111838af329a9..eaf21e7621d481a6a14473c334fdac42c2a82c10 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);