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

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


For info: I tested this patch with a very small buffer length (20ms) and it works like planned.

On Tue, Mar 12, 2019, at 18:18, Thomas Guillem wrote:
> ---
>  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
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list