[vlc-commits] coreaudio: disable resampling when latency is too high

Thomas Guillem git at videolan.org
Mon Mar 12 18:07:25 CET 2018


vlc/vlc-3.0 | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Mar 12 16:06:48 2018 +0100| [bab4c8269e4914c381a0637bb985e8c0f1d410ae] | committer: Thomas Guillem

coreaudio: disable resampling when latency is too high

On iOS, the render callback is called by default with 1024 frames, and 4096
when the screen is OFF. 4096 frames @ 44.1Hhz is around 88ms, which is higher
than AOUT_MAX_PTS_DELAY (60ms). This caused the resampler to be started/stopped
very often when the screen was OFF due to the imprecision of 88ms from the
TimeGet callback.

To fix this issue, this commit disable the TimeGet callback when the latency is
too high.

This will also save some CPU time by disabling any synchronisation when the
screen is OFF. From my tests, high latency is only triggered by switching OFF
the display.

Fixes #18939

(cherry picked from commit f18fef325af25113875b09c8f727017febc6198a)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=bab4c8269e4914c381a0637bb985e8c0f1d410ae
---

 modules/audio_output/auhal.c            |  2 +-
 modules/audio_output/coreaudio_common.c | 23 ++++++++++++++++++++---
 modules/audio_output/coreaudio_common.h |  4 +++-
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index 226eb98adf..c8011c64d9 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -984,7 +984,7 @@ 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, p_output, i_size);
+    ca_Render(p_aout, 0, p_output, i_size);
 
     return noErr;
 }
diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c
index d434b46b1a..6444d7c8f0 100644
--- a/modules/audio_output/coreaudio_common.c
+++ b/modules/audio_output/coreaudio_common.c
@@ -50,6 +50,7 @@ ca_Open(audio_output_t *p_aout)
     atomic_init(&p_sys->i_underrun_size, 0);
     atomic_init(&p_sys->b_paused, false);
     atomic_init(&p_sys->b_do_flush, false);
+    atomic_init(&p_sys->b_highlatency, true);
     vlc_sem_init(&p_sys->flush_sem, 0);
     vlc_mutex_init(&p_sys->lock);
 
@@ -70,10 +71,17 @@ 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, uint8_t *p_output, size_t i_requested)
+ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint8_t *p_output,
+          size_t i_requested)
 {
     struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
 
+    const bool b_highlatency = CLOCK_FREQ * (uint64_t)i_nb_samples / p_sys->i_rate
+                             > AOUT_MAX_PTS_DELAY;
+
+    if (b_highlatency)
+        atomic_store(&p_sys->b_highlatency, true);
+
     bool expected = true;
     if (atomic_compare_exchange_weak(&p_sys->b_do_flush, &expected, false))
     {
@@ -109,6 +117,11 @@ ca_Render(audio_output_t *p_aout, uint8_t *p_output, size_t i_requested)
         atomic_fetch_add(&p_sys->i_underrun_size, i_requested - i_tocopy);
         memset(&p_output[i_tocopy], 0, i_requested - i_tocopy);
     }
+
+    /* Set high delay to false (re-enabling ca_Timeget) after consuming the
+     * circular buffer */
+    if (!b_highlatency)
+        atomic_store(&p_sys->b_highlatency, false);
 }
 
 int
@@ -116,6 +129,10 @@ ca_TimeGet(audio_output_t *p_aout, mtime_t *delay)
 {
     struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
 
+    /* Too high delay: TimeGet will be too imprecise */
+    if (atomic_load(&p_sys->b_highlatency))
+        return -1;
+
     int32_t i_bytes;
     TPCircularBufferTail(&p_sys->circular_buffer, &i_bytes);
 
@@ -239,6 +256,7 @@ ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
 
     atomic_store(&p_sys->i_underrun_size, 0);
     atomic_store(&p_sys->b_paused, false);
+    atomic_store(&p_sys->b_highlatency, true);
     p_sys->i_rate = fmt->i_rate;
     p_sys->i_bytes_per_frame = fmt->i_bytes_per_frame;
     p_sys->i_frame_length = fmt->i_frame_length;
@@ -346,9 +364,8 @@ RenderCallback(void *p_data, AudioUnitRenderActionFlags *ioActionFlags,
     VLC_UNUSED(ioActionFlags);
     VLC_UNUSED(inTimeStamp);
     VLC_UNUSED(inBusNumber);
-    VLC_UNUSED(inNumberFrames);
 
-    ca_Render(p_data, ioData->mBuffers[0].mData,
+    ca_Render(p_data, inNumberFrames, 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 a14ed3adae..4d7333738b 100644
--- a/modules/audio_output/coreaudio_common.h
+++ b/modules/audio_output/coreaudio_common.h
@@ -55,6 +55,7 @@ struct aout_sys_common
     atomic_uint         i_underrun_size;
     atomic_bool         b_paused;
     atomic_bool         b_do_flush;
+    atomic_bool         b_highlatency;
     vlc_sem_t           flush_sem;
     vlc_mutex_t         lock;
     int                 i_rate;
@@ -70,7 +71,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, uint8_t *p_output, size_t i_requested);
+void ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, 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