[vlc-commits] coreaudio: handle latency and circular size in ca_Initialize

Thomas Guillem git at videolan.org
Thu Mar 2 18:16:53 CET 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Mar  2 10:49:25 2017 +0100| [d76ab8640025a5795eb70264329799fce1cbbde2] | committer: Thomas Guillem

coreaudio: handle latency and circular size in ca_Initialize

The maximum latency changed from 2 seconds to 1 second.

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

 modules/audio_output/audiounit_ios.m    |  8 +++-----
 modules/audio_output/auhal.c            | 31 +++++++++++------------------
 modules/audio_output/coreaudio_common.c | 35 +++++++++++++++++++++++----------
 modules/audio_output/coreaudio_common.h | 11 +++--------
 4 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/modules/audio_output/audiounit_ios.m b/modules/audio_output/audiounit_ios.m
index f85bd1e..b392816 100644
--- a/modules/audio_output/audiounit_ios.m
+++ b/modules/audio_output/audiounit_ios.m
@@ -367,7 +367,8 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
 
     /* TODO: Do passthrough if dev_type allows it */
 
-    ret = au_Initialize(p_aout, p_sys->au_unit, fmt, layout);
+    ret = au_Initialize(p_aout, p_sys->au_unit, fmt, layout,
+                        [p_sys->avInstance outputLatency] * CLOCK_FREQ);
     if (ret != VLC_SUCCESS)
         goto error;
 
@@ -382,8 +383,6 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
         goto error;
     }
 
-    p_sys->c.i_latency_us = [p_sys->avInstance outputLatency] * CLOCK_FREQ;
-
     if (p_sys->b_muted)
         Pause(p_aout, true, 0);
 
@@ -394,8 +393,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     free(layout);
     p_aout->mute_set  = MuteSet;
     p_aout->pause = Pause;
-    msg_Dbg(p_aout, "analog AudioUnit output successfully opened "
-            "(latency: %lld us)", p_sys->c.i_latency_us);
+    msg_Dbg(p_aout, "analog AudioUnit output successfully opened");
     return VLC_SUCCESS;
 
 error:
diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c
index 28e6eb9..5965652 100644
--- a/modules/audio_output/auhal.c
+++ b/modules/audio_output/auhal.c
@@ -934,7 +934,8 @@ RenderCallbackSPDIF(AudioDeviceID inDevice, const AudioTimeStamp * inNow,
  * StartAnalog: open and setup a HAL AudioUnit to do PCM audio output
  */
 static int
-StartAnalog(audio_output_t *p_aout, audio_sample_format_t *fmt)
+StartAnalog(audio_output_t *p_aout, audio_sample_format_t *fmt,
+            mtime_t i_latency_us)
 {
     struct aout_sys_t           *p_sys = p_aout->sys;
     OSStatus                    err = noErr;
@@ -985,7 +986,7 @@ StartAnalog(audio_output_t *p_aout, audio_sample_format_t *fmt)
 
     /* Do the last VLC aout setups */
     fmt->i_format = VLC_CODEC_FL32;
-    int ret = au_Initialize(p_aout, p_sys->au_unit, fmt, layout);
+    int ret = au_Initialize(p_aout, p_sys->au_unit, fmt, layout, i_latency_us);
     if (ret != VLC_SUCCESS)
         goto error;
 
@@ -1014,7 +1015,8 @@ error:
  * StartSPDIF: Setup an encoded digital stream (SPDIF) output
  */
 static int
-StartSPDIF(audio_output_t * p_aout, audio_sample_format_t *fmt)
+StartSPDIF(audio_output_t * p_aout, audio_sample_format_t *fmt,
+           mtime_t i_latency_us)
 {
     struct aout_sys_t *p_sys = p_aout->sys;
     int ret;
@@ -1262,7 +1264,7 @@ StartSPDIF(audio_output_t * p_aout, audio_sample_format_t *fmt)
         return VLC_EGENERIC;
     }
 
-    ret = ca_Initialize(p_aout, fmt, 200 * AOUT_SPDIF_SIZE);
+    ret = ca_Initialize(p_aout, fmt, i_latency_us);
     if (ret != VLC_SUCCESS)
     {
         AudioDeviceDestroyIOProcID(p_sys->i_selected_dev, p_sys->i_procID);
@@ -1396,7 +1398,6 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     p_sys->i_stream_index = -1;
     p_sys->b_revert = false;
     p_sys->b_changed_mixing = false;
-    p_sys->c.i_latency_samples = 0;
 
     vlc_mutex_lock(&p_sys->selected_device_lock);
     p_sys->i_selected_dev = p_sys->i_new_selected_dev;
@@ -1468,24 +1469,16 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
                       kAudioObjectPropertyScopeGlobal);
 
     /* get device latency */
-    AO_GET1PROP(p_sys->i_selected_dev, UInt32, &p_sys->c.i_latency_samples,
+    UInt32 i_latency_samples;
+    AO_GET1PROP(p_sys->i_selected_dev, UInt32, &i_latency_samples,
                 kAudioDevicePropertyLatency, kAudioObjectPropertyScopeOutput);
-    float f_latency_in_sec = (float)p_sys->c.i_latency_samples
-                           / (float)fmt->i_rate;
-    msg_Dbg(p_aout, "Current device has a latency of %u frames (%f sec)",
-            p_sys->c.i_latency_samples, f_latency_in_sec);
-
-    /* Ignore long Airplay latency as this is not correctly working yet */
-    if (f_latency_in_sec > 0.5f)
-    {
-        msg_Info(p_aout, "Ignore high latency as it causes problems currently.");
-        p_sys->c.i_latency_samples = 0;
-    }
+    fprintf(stderr, "i_latency_samples: %u\n", i_latency_samples);
+    mtime_t i_latency_us = i_latency_samples * CLOCK_FREQ / fmt->i_rate;
 
     /* Check for Digital mode or Analog output mode */
     if (AOUT_FMT_SPDIF (fmt))
     {
-        if (StartSPDIF (p_aout, fmt) == VLC_SUCCESS)
+        if (StartSPDIF (p_aout, fmt, i_latency_us) == VLC_SUCCESS)
         {
             msg_Dbg(p_aout, "digital output successfully opened");
             return VLC_SUCCESS;
@@ -1493,7 +1486,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     }
     else
     {
-        if (StartAnalog(p_aout, fmt) == VLC_SUCCESS)
+        if (StartAnalog(p_aout, fmt, i_latency_us) == VLC_SUCCESS)
         {
             msg_Dbg(p_aout, "analog output successfully opened");
             return VLC_SUCCESS;
diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c
index 4bff750..edbc3d7 100644
--- a/modules/audio_output/coreaudio_common.c
+++ b/modules/audio_output/coreaudio_common.c
@@ -85,9 +85,10 @@ ca_TimeGet(audio_output_t *p_aout, mtime_t *delay)
     int32_t i_bytes;
     TPCircularBufferTail(&p_sys->circular_buffer, &i_bytes);
 
-    int64_t i_frames = BytesToFrames(p_sys, i_bytes) + p_sys->i_latency_samples;
-    *delay = FramesToUs(p_sys, i_frames) + p_sys->i_latency_us;
+    int64_t i_frames = BytesToFrames(p_sys, i_bytes);
+    *delay = FramesToUs(p_sys, i_frames) + p_sys->i_dev_latency_us;
 
+msg_Err(p_aout, "ca_TimeGet: %lld (latency: %lld us)\n", *delay, p_sys->i_dev_latency_us);
     return 0;
 }
 
@@ -179,14 +180,10 @@ ca_Play(audio_output_t * p_aout, block_t * p_block)
 
 int
 ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
-              size_t i_audio_buffer_size)
+              mtime_t i_dev_latency_us)
 {
     struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
 
-    /* setup circular buffer */
-    if (!TPCircularBufferInit(&p_sys->circular_buffer, i_audio_buffer_size))
-        return VLC_EGENERIC;
-
     atomic_init(&p_sys->i_underrun_size, 0);
     atomic_init(&p_sys->b_paused, false);
 
@@ -195,6 +192,25 @@ ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
     p_sys->i_frame_length = fmt->i_frame_length;
     p_sys->chans_to_reorder = 0;
 
+    i_dev_latency_us = 1000000;
+    msg_Dbg(p_aout, "Current device has a latency of %lld us",
+            i_dev_latency_us);
+
+    /* TODO VLC can't handle latency higher than 1 seconds */
+    if (i_dev_latency_us > 1000000)
+    {
+        i_dev_latency_us = 1000000;
+        msg_Warn(p_aout, "VLC can't handle this device latency, lowering it to "
+                 "%lld", i_dev_latency_us);
+    }
+    p_sys->i_dev_latency_us = i_dev_latency_us;
+
+    /* setup circular buffer */
+    const size_t i_audiobuffer_size = AOUT_MAX_ADVANCE_TIME * fmt->i_rate *
+        fmt->i_bytes_per_frame / p_sys->i_frame_length / CLOCK_FREQ;
+    if (!TPCircularBufferInit(&p_sys->circular_buffer, i_audiobuffer_size))
+        return VLC_EGENERIC;
+
     p_aout->play = ca_Play;
     p_aout->pause = ca_Pause;
     p_aout->flush = ca_Flush;
@@ -611,7 +627,7 @@ SetupInputLayout(audio_output_t *p_aout, const audio_sample_format_t *fmt,
 
 int
 au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
-              const AudioChannelLayout *outlayout)
+              const AudioChannelLayout *outlayout, mtime_t i_dev_latency_us)
 {
     assert(fmt->i_format == VLC_CODEC_FL32);
 
@@ -698,8 +714,7 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
         return VLC_EGENERIC;
     }
 
-    ret = ca_Initialize(p_aout, fmt, AOUT_MAX_ADVANCE_TIME / CLOCK_FREQ *
-                        fmt->i_rate * fmt->i_bytes_per_frame);
+    ret = ca_Initialize(p_aout, fmt, i_dev_latency_us);
     if (ret != VLC_SUCCESS)
     {
         AudioUnitUninitialize(au);
diff --git a/modules/audio_output/coreaudio_common.h b/modules/audio_output/coreaudio_common.h
index 330bd64..10c275b 100644
--- a/modules/audio_output/coreaudio_common.h
+++ b/modules/audio_output/coreaudio_common.h
@@ -55,13 +55,8 @@ struct aout_sys_common
     unsigned int        i_frame_length;
     uint8_t             chans_to_reorder;
     uint8_t             chan_table[AOUT_CHAN_MAX];
-
-    /* The following need to set by the caller */
-
-    /* ca_TimeGet extra latency, in samples. */
-    uint32_t            i_latency_samples;
     /* ca_TimeGet extra latency, in micro-seconds */
-    mtime_t             i_latency_us;
+    mtime_t             i_dev_latency_us;
 };
 
 void ca_Render(audio_output_t *p_aout, uint8_t *p_output, size_t i_requested);
@@ -75,7 +70,7 @@ void ca_Pause(audio_output_t * p_aout, bool pause, mtime_t date);
 void ca_Play(audio_output_t * p_aout, block_t * p_block);
 
 int  ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
-                   size_t i_audio_buffer_size);
+                   mtime_t i_dev_latency_us);
 
 void ca_Uninitialize(audio_output_t *p_aout);
 
@@ -83,6 +78,6 @@ AudioUnit au_NewOutputInstance(audio_output_t *p_aout, OSType comp_sub_type);
 
 int  au_Initialize(audio_output_t *p_aout, AudioUnit au,
                    audio_sample_format_t *fmt,
-                   const AudioChannelLayout *outlayout);
+                   const AudioChannelLayout *outlayout, mtime_t i_dev_latency_us);
 
 void au_Uninitialize(audio_output_t *p_aout, AudioUnit au);



More information about the vlc-commits mailing list