[vlc-commits] ALSA: trust ALSA-lib to convert the sample formats
Rémi Denis-Courmont
git at videolan.org
Wed Apr 13 19:36:06 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Apr 13 20:16:48 2011 +0300| [f4585b92df5ea734a830518345bdb41a18fe8163] | committer: Rémi Denis-Courmont
ALSA: trust ALSA-lib to convert the sample formats
Some weird hardware only support weird formats that VLC does not know
of (e.g. unsigned 18-bits padded to 3 bytes). The ALSA plug plugin will
do the conversion if needed.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f4585b92df5ea734a830518345bdb41a18fe8163
---
modules/audio_output/alsa.c | 148 +++++++++++++++++++++++--------------------
1 files changed, 80 insertions(+), 68 deletions(-)
diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 4bd5b94..500173d 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -130,7 +130,7 @@ static const int mode = SND_PCM_NO_AUTO_RESAMPLE
*****************************************************************************/
static void Probe (aout_instance_t *p_aout,
const char *psz_device, const char *psz_iec_device,
- int *pi_snd_pcm_format)
+ snd_pcm_format_t pcm_format)
{
struct aout_sys_t * p_sys = p_aout->output.p_sys;
vlc_value_t value, text;
@@ -161,24 +161,11 @@ static void Probe (aout_instance_t *p_aout,
return;
}
- if ( snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
- *pi_snd_pcm_format ) < 0 )
+ if (snd_pcm_hw_params_set_format (p_sys->p_snd_pcm, p_hw,
+ pcm_format) < 0)
{
- int i_snd_rc = -1;
-
- if( *pi_snd_pcm_format != SND_PCM_FORMAT_S16 )
- {
- *pi_snd_pcm_format = SND_PCM_FORMAT_S16;
- i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
- p_hw, *pi_snd_pcm_format );
- }
- if ( i_snd_rc < 0 )
- {
- msg_Warn( p_aout, "unable to set stream sample size and "
- "word order, disabling linear PCM audio" );
- snd_pcm_close( p_sys->p_snd_pcm );
- return;
- }
+ snd_pcm_close( p_sys->p_snd_pcm );
+ return;
}
i_channels = aout_FormatNbChannels( &p_aout->output.output );
@@ -335,18 +322,79 @@ static int Open( vlc_object_t *p_this )
psz_iec_device = strdup( psz_device );
}
- /* Choose the linear PCM format (read the comment above about FPU
- and float32) */
- int i_snd_pcm_format; /* Audio format for ALSA's data */
- if( HAVE_FPU )
- i_snd_pcm_format = SND_PCM_FORMAT_FLOAT;
- else
- i_snd_pcm_format = SND_PCM_FORMAT_S16;
+ snd_pcm_format_t pcm_format; /* ALSA sample format */
+ vlc_fourcc_t fourcc = p_aout->output.output.i_format;
+ switch (fourcc)
+ {
+ case VLC_CODEC_F64B:
+ pcm_format = SND_PCM_FORMAT_FLOAT64_BE;
+ break;
+ case VLC_CODEC_F64L:
+ pcm_format = SND_PCM_FORMAT_FLOAT64_LE;
+ break;
+ case VLC_CODEC_F32B:
+ pcm_format = SND_PCM_FORMAT_FLOAT_BE;
+ break;
+ case VLC_CODEC_F32L:
+ pcm_format = SND_PCM_FORMAT_FLOAT_LE;
+ break;
+ case VLC_CODEC_FI32:
+ fourcc = VLC_CODEC_FL32;
+ pcm_format = SND_PCM_FORMAT_FLOAT;
+ break;
+ case VLC_CODEC_S32B:
+ pcm_format = SND_PCM_FORMAT_S32_BE;
+ break;
+ case VLC_CODEC_S32L:
+ pcm_format = SND_PCM_FORMAT_S32_LE;
+ break;
+ case VLC_CODEC_S24B:
+ pcm_format = SND_PCM_FORMAT_S24_3BE;
+ break;
+ case VLC_CODEC_S24L:
+ pcm_format = SND_PCM_FORMAT_S24_3LE;
+ break;
+ case VLC_CODEC_U24B:
+ pcm_format = SND_PCM_FORMAT_U24_3BE;
+ break;
+ case VLC_CODEC_U24L:
+ pcm_format = SND_PCM_FORMAT_U24_3LE;
+ break;
+ case VLC_CODEC_S16B:
+ pcm_format = SND_PCM_FORMAT_S16_BE;
+ break;
+ case VLC_CODEC_S16L:
+ pcm_format = SND_PCM_FORMAT_S16_LE;
+ break;
+ case VLC_CODEC_U16B:
+ pcm_format = SND_PCM_FORMAT_U16_BE;
+ break;
+ case VLC_CODEC_U16L:
+ pcm_format = SND_PCM_FORMAT_U16_LE;
+ break;
+ case VLC_CODEC_S8:
+ pcm_format = SND_PCM_FORMAT_S8;
+ break;
+ case VLC_CODEC_U8:
+ pcm_format = SND_PCM_FORMAT_U8;
+ break;
+ default:
+ if (HAVE_FPU)
+ {
+ fourcc = VLC_CODEC_FL32;
+ pcm_format = SND_PCM_FORMAT_FLOAT;
+ }
+ else
+ {
+ fourcc = VLC_CODEC_S16N;
+ pcm_format = SND_PCM_FORMAT_S16;
+ }
+ }
/* If the variable doesn't exist then it's the first time we're called
and we have to probe the available audio formats and channels */
if (var_Type (p_aout, "audio-device") == 0)
- Probe (p_aout, psz_device, psz_iec_device, &i_snd_pcm_format);
+ Probe (p_aout, psz_device, psz_iec_device, pcm_format);
bool spdif = false;
switch( var_GetInteger( p_aout, "audio-device") )
@@ -433,7 +481,7 @@ static int Open( vlc_object_t *p_this )
if( spdif )
{
i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
- i_snd_pcm_format = SND_PCM_FORMAT_S16;
+ pcm_format = SND_PCM_FORMAT_S16;
i_channels = 2;
p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE;
@@ -460,9 +508,6 @@ static int Open( vlc_object_t *p_this )
snd_pcm_hw_params_alloca(&p_hw);
snd_pcm_sw_params_alloca(&p_sw);
- /* Due to some bugs in alsa with some drivers, we need to retry in s16l
- if snd_pcm_hw_params fails in fl32 */
-retry:
/* Get Initial hardware parameters */
val = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw );
if( val < 0 )
@@ -473,40 +518,16 @@ retry:
}
/* Set format. */
- val = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
- i_snd_pcm_format );
+ val = snd_pcm_hw_params_set_format (p_sys->p_snd_pcm, p_hw, pcm_format);
if( val < 0 )
{
- if( i_snd_pcm_format != SND_PCM_FORMAT_S16 )
- {
- i_snd_pcm_format = SND_PCM_FORMAT_S16;
- val = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
- p_hw, i_snd_pcm_format );
- }
- if ( val < 0 )
- {
- msg_Err( p_aout, "unable to set stream sample size and "
- "word order (%s)", snd_strerror( val ) );
- goto error;
- }
+ msg_Err (p_aout, "cannot set sample format: %s", snd_strerror (val));
+ goto error;
}
- vlc_fourcc_t i_vlc_pcm_format;
if( spdif )
- i_vlc_pcm_format = VLC_CODEC_SPDIFL;
- else
- switch( i_snd_pcm_format )
- {
- case SND_PCM_FORMAT_FLOAT:
- i_vlc_pcm_format = VLC_CODEC_FL32;
- break;
- case SND_PCM_FORMAT_S16:
- i_vlc_pcm_format = VLC_CODEC_S16N;
- break;
- default:
- assert(0);
- }
- p_aout->output.output.i_format = i_vlc_pcm_format;
+ fourcc = VLC_CODEC_SPDIFL;
+ p_aout->output.output.i_format = fourcc;
val = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw,
SND_PCM_ACCESS_RW_INTERLEAVED );
@@ -566,15 +587,6 @@ retry:
val = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw );
if( val < 0 )
{
- if( i_snd_pcm_format == SND_PCM_FORMAT_FLOAT )
- {
- i_snd_pcm_format = SND_PCM_FORMAT_S16;
- p_aout->output.output.i_format = VLC_CODEC_S16N;
- msg_Warn( p_aout, "unable to commit hardware configuration "
- "with fl32 samples (%s). Retrying with s16l.",
- snd_strerror( val ) );
- goto retry;
- }
msg_Err( p_aout, "unable to commit hardware configuration (%s)",
snd_strerror( val ) );
goto error;
More information about the vlc-commits
mailing list