[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, ¶m, 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