]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/alsa.c
Forgot to update these when adding the omxil module
[vlc] / modules / audio_output / alsa.c
index 1594b7f8d00888739218f11204a5d23d11e90626..ac19bd9fc03ac3675a1cce780dce455e448334bc 100644 (file)
@@ -31,6 +31,8 @@
 # include "config.h"
 #endif
 
+#include <assert.h>
+
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 
@@ -45,6 +47,7 @@
 #define ALSA_PCM_NEW_HW_PARAMS_API
 #define ALSA_PCM_NEW_SW_PARAMS_API
 #include <alsa/asoundlib.h>
+#include <alsa/version.h>
 
 /*#define ALSA_DEBUG*/
 
@@ -94,6 +97,8 @@ static void* ALSAThread   ( void * );
 static void  ALSAFill     ( aout_instance_t * );
 static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
                                 vlc_value_t newval, vlc_value_t oldval, void *p_unused );
+static void GetDevicesForCard( vlc_object_t *, module_config_t *, int card );
+static void GetDevices( vlc_object_t *, module_config_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -248,7 +253,7 @@ static void Probe( aout_instance_t * p_aout,
             text.psz_string = (char*)N_("A/52 over S/PDIF");
             var_Change( p_aout, "audio-device",
                         VLC_VAR_ADDCHOICE, &val, &text );
-            if( config_GetInt( p_aout, "spdif" ) )
+            if( var_InheritInteger( p_aout, "spdif" ) )
                 var_Set( p_aout, "audio-device", val );
 
             snd_pcm_close( p_sys->p_snd_pcm );
@@ -261,11 +266,26 @@ static void Probe( aout_instance_t * p_aout,
     }
 
     var_Change( p_aout, "audio-device", VLC_VAR_CHOICESCOUNT, &val, NULL );
+#if (SND_LIB_VERSION <= 0x010015)
+# warning Please update alsa-lib to version > 1.0.21a.
+    var_Create( p_aout->p_libvlc, "alsa-working", VLC_VAR_BOOL );
+    if( val.i_int <= 0 )
+    {
+        if( var_GetBool( p_aout->p_libvlc, "alsa-working" ) )
+            dialog_FatalWait( p_aout, "ALSA version problem",
+                "VLC failed to re-initialize your sound output device.\n"
+                "Please update alsa-lib to version 1.0.22 or higher "
+                "to fix this issue." );
+    }
+    else
+        var_SetBool( p_aout->p_libvlc, "alsa-working", true );
+#endif
     if( val.i_int <= 0 )
     {
         /* Probe() has failed. */
-        msg_Dbg( p_aout, "failed to find a usable alsa configuration" );
+        msg_Dbg( p_aout, "failed to find a usable ALSA configuration" );
         var_Destroy( p_aout, "audio-device" );
+        GetDevices( VLC_OBJECT(p_aout), NULL );
         return;
     }
 
@@ -313,7 +333,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_ENOMEM;
 
     /* Get device name */
-    if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
+    if( (psz_device = var_InheritString( p_aout, "alsa-audio-device" )) == NULL )
     {
         msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
         dialog_Fatal( p_aout, _("No Audio Device"), "%s",
@@ -891,9 +911,6 @@ error:
     msleep(p_sys->i_period_time / 2);
 }
 
-static void GetDevicesForCard( module_config_t *p_item, int i_card );
-static void GetDevices( module_config_t *p_item );
-
 /*****************************************************************************
  * config variable callback
  *****************************************************************************/
@@ -901,7 +918,6 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
                                vlc_value_t newval, vlc_value_t oldval, void *p_unused )
 {
     module_config_t *p_item;
-    int i;
     (void)newval;
     (void)oldval;
     (void)p_unused;
@@ -912,6 +928,8 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
     /* Clear-up the current list */
     if( p_item->i_list )
     {
+        int i;
+
         /* Keep the first entrie */
         for( i = 1; i < p_item->i_list; i++ )
         {
@@ -924,7 +942,7 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
     }
     p_item->i_list = 1;
 
-    GetDevices( p_item );
+    GetDevices( p_this, p_item );
 
     /* Signal change to the interface */
     p_item->b_dirty = true;
@@ -933,7 +951,8 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
 }
 
 
-static void GetDevicesForCard( module_config_t *p_item, int i_card )
+static void GetDevicesForCard( vlc_object_t *obj, module_config_t *p_item,
+                               int i_card )
 {
     int i_pcm_device = -1;
     int i_err = 0;
@@ -967,12 +986,8 @@ static void GetDevicesForCard( module_config_t *p_item, int i_card )
         if( ( i_err = snd_ctl_pcm_info( p_ctl, p_pcm_info ) ) < 0 )
         {
             if( i_err != -ENOENT )
-            {
-                /*printf( "get_devices_for_card(): "
-                         "snd_ctl_pcm_info() "
-                         "failed (%d:%d): %s.\n", i_card,
-                         i_pcm_device, snd_strerror( -i_err ) );*/
-            }
+                msg_Err( obj, "cannot get PCM device %d:%d infos: %s", i_card,
+                         i_pcm_device, snd_strerror( -i_err ) );
             continue;
         }
 
@@ -985,42 +1000,40 @@ static void GetDevicesForCard( module_config_t *p_item, int i_card )
             break;
         }
 
-        p_item->ppsz_list =
-            (char **)realloc( p_item->ppsz_list,
-                              (p_item->i_list + 2) * sizeof(char *) );
-        p_item->ppsz_list_text =
-            (char **)realloc( p_item->ppsz_list_text,
-                              (p_item->i_list + 2) * sizeof(char *) );
-        p_item->ppsz_list[ p_item->i_list ] = psz_device;
-        p_item->ppsz_list_text[ p_item->i_list ] = psz_descr;
-        p_item->i_list++;
-        p_item->ppsz_list[ p_item->i_list ] = NULL;
-        p_item->ppsz_list_text[ p_item->i_list ] = NULL;
+        msg_Dbg( obj, "  %s", psz_descr );
+
+        if( p_item )
+        {
+            p_item->ppsz_list = xrealloc( p_item->ppsz_list,
+                                  (p_item->i_list + 2) * sizeof(char *) );
+            p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text,
+                                  (p_item->i_list + 2) * sizeof(char *) );
+            p_item->ppsz_list[ p_item->i_list ] = psz_device;
+            p_item->ppsz_list_text[ p_item->i_list ] = psz_descr;
+            p_item->i_list++;
+            p_item->ppsz_list[ p_item->i_list ] = NULL;
+            p_item->ppsz_list_text[ p_item->i_list ] = NULL;
+        }
+        else
+        {
+            free( psz_device );
+            free( psz_descr );
+        }
     }
 
     snd_ctl_close( p_ctl );
 }
 
 
-
-static void GetDevices( module_config_t *p_item )
+static void GetDevices( vlc_object_t *obj, module_config_t *p_item )
 {
     int i_card = -1;
-    int i_err = 0;
+    int i_err;
 
-    if( ( i_err = snd_card_next( &i_card ) ) != 0 )
-    {
-        /*printf( "snd_card_next() failed: %s", snd_strerror( -i_err ) );*/
-        return;
-    }
+    msg_Dbg( obj, "Available alsa output devices:" );
+    while( (i_err = snd_card_next( &i_card )) == 0 && i_card > -1 )
+        GetDevicesForCard( obj, p_item, i_card );
 
-    while( i_card > -1 )
-    {
-        GetDevicesForCard( p_item, i_card );
-        if( ( i_err = snd_card_next( &i_card ) ) != 0 )
-        {
-            /*printf( "snd_card_next() failed: %s", snd_strerror( -i_err ) );*/
-            break;
-        }
-    }
+    if( i_err )
+        msg_Err( obj, "cannot enumerate cards: %s", snd_strerror( -i_err ) );
 }