[vlc-devel] [RFC PATCH 2/2] alsa: implement non-blocking play()

Thomas Guillem thomas at gllm.fr
Tue Mar 12 18:18:43 CET 2019


---
 modules/audio_output/alsa.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 5d30d05af9..5c44df4a6e 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -47,6 +47,7 @@ typedef struct
     vlc_fourcc_t format; /**< Sample format */
     uint8_t chans_table[AOUT_CHAN_MAX]; /**< Channels order table */
     uint8_t chans_to_reorder; /**< Number of channels to reorder */
+    vlc_tick_t buffer_len;
 
     bool soft_mute;
     float soft_gain;
@@ -411,7 +412,7 @@ static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
     /* Open the device */
     snd_pcm_t *pcm;
     /* VLC always has a resampler. No need for ALSA's. */
-    const int mode = SND_PCM_NO_AUTO_RESAMPLE;
+    const int mode = SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NONBLOCK;
 
     int val = snd_pcm_open (&pcm, device, SND_PCM_STREAM_PLAYBACK, mode);
     if (val != 0)
@@ -539,6 +540,7 @@ static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt)
         msg_Err (aout, "cannot set buffer duration: %s", snd_strerror (val));
         goto error;
     }
+    sys->buffer_len = param;
 #if 0
     val = snd_pcm_hw_params_get_buffer_time (hw, &param, NULL);
     if (val)
@@ -657,10 +659,8 @@ static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
 
     snd_pcm_t *pcm = sys->pcm;
 
-    /* TODO: better overflow handling */
     /* TODO: no period wake ups */
 
-    while (block->i_nb_samples > 0)
     {
         snd_pcm_sframes_t frames;
 
@@ -671,9 +671,8 @@ static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
             block->i_nb_samples -= frames;
             block->p_buffer += bytes;
             block->i_buffer -= bytes;
-            // pts, length
         }
-        else  
+        else if (frames != -EAGAIN)
         {
             int val = snd_pcm_recover (pcm, frames, 1);
             if (val)
@@ -681,10 +680,15 @@ static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
                 msg_Err (aout, "cannot recover playback stream: %s",
                          snd_strerror (val));
                 DumpDeviceStatus (aout, pcm);
-                break;
             }
             msg_Warn (aout, "cannot write samples: %s", snd_strerror (frames));
         }
+        if (block->i_buffer != 0)
+        {
+            const vlc_tick_t len =
+                vlc_tick_from_samples(block->i_nb_samples, sys->rate);
+            return len > sys->buffer_len / 2 ? sys->buffer_len / 2 : len;
+        }
     }
     block_Release (block);
     return AOUT_PLAY_DONE;
-- 
2.20.1



More information about the vlc-devel mailing list