X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Falsa.c;h=1adb6d40253f54080f622f780695442f527cfc34;hb=bfb26c0ea72b8a7466afe486cf578aaee60df76a;hp=13a225586436cd0e10e0139318f35ab698e362a7;hpb=13ae40b0efc4f1b1ce205d9a057537047fcab3f4;p=vlc diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c index 13a2255864..1adb6d4025 100644 --- a/modules/audio_output/alsa.c +++ b/modules/audio_output/alsa.c @@ -31,11 +31,11 @@ # include "config.h" #endif -#include +#include #include #include /* ENOMEM */ -#include +#include #include @@ -62,7 +62,7 @@ struct aout_sys_t snd_output_t * p_snd_stderr; #endif - int b_playing; /* playing status */ + bool b_playing; /* playing status */ mtime_t start_date; vlc_mutex_t lock; @@ -90,32 +90,33 @@ struct aout_sys_t /***************************************************************************** * Local prototypes *****************************************************************************/ -static int Open ( vlc_object_t * ); -static void Close ( vlc_object_t * ); -static void Play ( aout_instance_t * ); -static int ALSAThread ( aout_instance_t * ); -static void ALSAFill ( aout_instance_t * ); +static int Open ( vlc_object_t * ); +static void Close ( vlc_object_t * ); +static void Play ( aout_instance_t * ); +static void* ALSAThread ( vlc_object_t * ); +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 ); /***************************************************************************** * Module descriptor *****************************************************************************/ -static const char *ppsz_devices[] = { "default" }; -static const char *ppsz_devices_text[] = { N_("Default") }; -vlc_module_begin(); - set_shortname( "ALSA" ); - set_description( N_("ALSA audio output") ); - set_category( CAT_AUDIO ); - set_subcategory( SUBCAT_AUDIO_AOUT ); - add_string( "alsadev", DEFAULT_ALSA_DEVICE, aout_FindAndRestart, - N_("ALSA Device Name"), NULL, false ); - change_string_list( ppsz_devices, ppsz_devices_text, FindDevicesCallback ); - change_action_add( FindDevicesCallback, N_("Refresh list") ); - - set_capability( "audio output", 150 ); - set_callbacks( Open, Close ); -vlc_module_end(); +static const char *const ppsz_devices[] = { "default" }; +static const char *const ppsz_devices_text[] = { N_("Default") }; +vlc_module_begin () + set_shortname( "ALSA" ) + set_description( N_("ALSA audio output") ) + set_category( CAT_AUDIO ) + set_subcategory( SUBCAT_AUDIO_AOUT ) + add_string( "alsa-audio-device", DEFAULT_ALSA_DEVICE, aout_FindAndRestart, + N_("ALSA Device Name"), NULL, false ) + add_deprecated_alias( "alsadev" ) /* deprecated since 0.9.3 */ + change_string_list( ppsz_devices, ppsz_devices_text, FindDevicesCallback ) + change_action_add( FindDevicesCallback, N_("Refresh list") ) + + set_capability( "audio output", 150 ) + set_callbacks( Open, Close ) +vlc_module_end () /***************************************************************************** * Probe: probe the audio device for available formats and channels @@ -186,20 +187,20 @@ static void Probe( aout_instance_t * p_aout, { case 1: val.i_int = AOUT_VAR_MONO; - text.psz_string = N_("Mono"); + text.psz_string = _("Mono"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); break; case 2: val.i_int = AOUT_VAR_STEREO; - text.psz_string = N_("Stereo"); + text.psz_string = _("Stereo"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); var_Set( p_aout, "audio-device", val ); break; case 4: val.i_int = AOUT_VAR_2F2R; - text.psz_string = N_("2 Front 2 Rear"); + text.psz_string = _("2 Front 2 Rear"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); break; @@ -223,7 +224,7 @@ static void Probe( aout_instance_t * p_aout, if ( !snd_pcm_hw_params_test_channels( p_sys->p_snd_pcm, p_hw, 2 )) { val.i_int = AOUT_VAR_STEREO; - text.psz_string = N_("Stereo"); + text.psz_string = (char*)N_("Stereo"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); var_Set( p_aout, "audio-device", val ); @@ -247,7 +248,7 @@ static void Probe( aout_instance_t * p_aout, SND_PCM_NONBLOCK ) ) ) { val.i_int = AOUT_VAR_SPDIF; - text.psz_string = N_("A/52 over S/PDIF"); + 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" ) ) @@ -266,15 +267,14 @@ static void Probe( aout_instance_t * p_aout, if( val.i_int <= 0 ) { /* Probe() has failed. */ - msg_Dbg( p_aout, "failed to find a useable alsa configuration" ); + msg_Dbg( p_aout, "failed to find a usable alsa configuration" ); var_Destroy( p_aout, "audio-device" ); return; } /* Add final settings to the variable */ var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL ); - val.b_bool = true; - var_Set( p_aout, "intf-change", val ); + var_SetBool( p_aout, "intf-change", true ); } /***************************************************************************** @@ -313,20 +313,17 @@ static int Open( vlc_object_t *p_this ) /* Allocate structures */ p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) ); if( p_sys == NULL ) - { - msg_Err( p_aout, "out of memory" ); return VLC_ENOMEM; - } p_sys->b_playing = false; p_sys->start_date = 0; - vlc_cond_init( p_aout, &p_sys->wait ); + vlc_cond_init( &p_sys->wait ); vlc_mutex_init( &p_sys->lock ); /* Get device name */ - if( (psz_device = config_GetPsz( p_aout, "alsadev" )) == NULL ) + if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL ) { msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" ); - intf_UserFatal( p_aout, false, _("No Audio Device"), + dialog_Fatal( p_aout, _("No Audio Device"), "%s", _("No audio device name was given. You might want to " \ "enter \"default\".") ); free( p_sys ); @@ -363,12 +360,12 @@ static int Open( vlc_object_t *p_this ) and float32) */ if( vlc_CPU() & CPU_CAPABILITY_FPU ) { - i_vlc_pcm_format = VLC_FOURCC('f','l','3','2'); + i_vlc_pcm_format = VLC_CODEC_FL32; i_snd_pcm_format = SND_PCM_FORMAT_FLOAT; } else { - i_vlc_pcm_format = AOUT_FMT_S16_NE; + i_vlc_pcm_format = VLC_CODEC_S16N; i_snd_pcm_format = SND_PCM_FORMAT_S16; } @@ -434,7 +431,7 @@ static int Open( vlc_object_t *p_this ) { msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", psz_iec_device, snd_strerror( i_snd_rc ) ); - intf_UserFatal( p_aout, false, _("Audio output failed"), + dialog_Fatal( p_aout, _("Audio output failed"), _("VLC could not open the ALSA device \"%s\" (%s)."), psz_iec_device, snd_strerror( i_snd_rc ) ); free( p_sys ); @@ -445,7 +442,7 @@ static int Open( vlc_object_t *p_this ) i_snd_pcm_format = SND_PCM_FORMAT_S16; i_channels = 2; - i_vlc_pcm_format = VLC_FOURCC('s','p','d','i'); + i_vlc_pcm_format = VLC_CODEC_SPDIFL; p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE; p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->output.output.i_frame_length = A52_FRAME_NB; @@ -473,7 +470,7 @@ static int Open( vlc_object_t *p_this ) { msg_Err( p_aout, "audio device: %s is already in use", psz_device ); - intf_UserFatal( p_aout, false, _("Audio output failed"), + dialog_Fatal( p_aout, _("Audio output failed"), _("The audio device \"%s\" is already in use."), psz_device ); } @@ -485,7 +482,7 @@ static int Open( vlc_object_t *p_this ) { msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", psz_device, snd_strerror( i_snd_rc ) ); - intf_UserFatal( p_aout, false, _("Audio output failed"), + dialog_Fatal( p_aout, _("Audio output failed"), _("VLC could not open the ALSA device \"%s\" (%s)."), psz_device, snd_strerror( i_snd_rc ) ); free( p_sys ); @@ -543,14 +540,14 @@ static int Open( vlc_object_t *p_this ) goto error; } } - if( i_vlc_pcm_format != VLC_FOURCC('s','p','d','i') ) + if( i_vlc_pcm_format != VLC_CODEC_SPDIFL ) switch( i_snd_pcm_format ) { case SND_PCM_FORMAT_FLOAT: - i_vlc_pcm_format = VLC_FOURCC('f','l','3','2'); + i_vlc_pcm_format = VLC_CODEC_FL32; break; case SND_PCM_FORMAT_S16: - i_vlc_pcm_format = AOUT_FMT_S16_NE; + i_vlc_pcm_format = VLC_CODEC_S16N; break; } p_aout->output.output.i_format = i_vlc_pcm_format; @@ -574,15 +571,9 @@ static int Open( vlc_object_t *p_this ) /* Set rate. */ i_old_rate = p_aout->output.output.i_rate; -#ifdef HAVE_ALSA_NEW_API i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw, &p_aout->output.output.i_rate, NULL ); -#else - i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw, - p_aout->output.output.i_rate, - NULL ); -#endif if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate ) { msg_Warn( p_aout, "The rate %d Hz is not supported by your " \ @@ -591,13 +582,8 @@ static int Open( vlc_object_t *p_this ) } /* Set period size. */ -#ifdef HAVE_ALSA_NEW_API if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, p_hw, &i_period_size, NULL ) ) < 0 ) -#else - if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, - p_hw, i_period_size, NULL ) ) < 0 ) -#endif { msg_Err( p_aout, "unable to set period size (%s)", snd_strerror( i_snd_rc ) ); @@ -606,13 +592,8 @@ static int Open( vlc_object_t *p_this ) p_aout->output.i_nb_samples = i_period_size; /* Set buffer size. */ -#ifdef HAVE_ALSA_NEW_API if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, p_hw, &i_buffer_size ) ) < 0 ) -#else - if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, - p_hw, i_buffer_size ) ) < 0 ) -#endif { msg_Err( p_aout, "unable to set buffer size (%s)", snd_strerror( i_snd_rc ) ); @@ -627,7 +608,7 @@ static int Open( vlc_object_t *p_this ) { b_retry = true; i_snd_pcm_format = SND_PCM_FORMAT_S16; - p_aout->output.output.i_format = AOUT_FMT_S16_NE; + p_aout->output.output.i_format = VLC_CODEC_S16N; msg_Warn( p_aout, "unable to commit hardware configuration " "with fl32 samples. Retrying with s16l (%s)", snd_strerror( i_snd_rc ) ); } @@ -640,13 +621,8 @@ static int Open( vlc_object_t *p_this ) } } -#ifdef HAVE_ALSA_NEW_API if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw, &p_sys->i_period_time, NULL ) ) < 0 ) -#else - if( ( p_sys->i_period_time = - (int)snd_pcm_hw_params_get_period_time( p_hw, NULL ) ) < 0 ) -#endif { msg_Err( p_aout, "unable to get period time (%s)", snd_strerror( i_snd_rc ) ); @@ -687,7 +663,7 @@ static int Open( vlc_object_t *p_this ) /* Create ALSA thread and wait for its readiness. */ if( vlc_thread_create( p_aout, "aout", ALSAThread, - VLC_THREAD_PRIORITY_OUTPUT, false ) ) + VLC_THREAD_PRIORITY_OUTPUT ) ) { msg_Err( p_aout, "cannot create ALSA thread (%m)" ); goto error; @@ -711,14 +687,14 @@ static void Play( aout_instance_t *p_aout ) { if( !p_aout->output.p_sys->b_playing ) { - p_aout->output.p_sys->b_playing = 1; + p_aout->output.p_sys->b_playing = true; /* get the playing date of the first aout buffer */ + vlc_mutex_lock( &p_aout->output.p_sys->lock ); p_aout->output.p_sys->start_date = aout_FifoFirstDate( p_aout, &p_aout->output.fifo ); /* wake up the audio output thread */ - vlc_mutex_lock( &p_aout->output.p_sys->lock ); vlc_cond_signal( &p_aout->output.p_sys->wait ); vlc_mutex_unlock( &p_aout->output.p_sys->lock ); } @@ -733,12 +709,15 @@ static void Close( vlc_object_t *p_this ) struct aout_sys_t * p_sys = p_aout->output.p_sys; int i_snd_rc; + /* Make sure that the thread will stop once it is waken up */ + vlc_object_kill( p_aout ); + /* make sure the audio output thread is waken up */ vlc_mutex_lock( &p_aout->output.p_sys->lock ); vlc_cond_signal( &p_aout->output.p_sys->wait ); vlc_mutex_unlock( &p_aout->output.p_sys->lock ); - vlc_object_kill( p_aout ); + /* */ vlc_thread_join( p_aout ); p_aout->b_die = false; @@ -760,23 +739,25 @@ static void Close( vlc_object_t *p_this ) /***************************************************************************** * ALSAThread: asynchronous thread used to DMA the data to the device *****************************************************************************/ -static int ALSAThread( aout_instance_t * p_aout ) +static void* ALSAThread( vlc_object_t* p_this ) { + aout_instance_t * p_aout = (aout_instance_t*)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; + int canc = vlc_savecancel (); p_sys->p_status = (snd_pcm_status_t *)malloc(snd_pcm_status_sizeof()); /* Wait for the exact time to start playing (avoids resampling) */ vlc_mutex_lock( &p_sys->lock ); - while( !p_sys->start_date && !p_aout->b_die ) + while( !p_sys->start_date && vlc_object_alive (p_aout) ) vlc_cond_wait( &p_sys->wait, &p_sys->lock ); vlc_mutex_unlock( &p_sys->lock ); - if( p_aout->b_die ) - goto cleanup; + if( !vlc_object_alive (p_aout) ) + goto cleanup; mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 ); - while ( !p_aout->b_die ) + while ( vlc_object_alive (p_aout) ) { ALSAFill( p_aout ); } @@ -784,7 +765,8 @@ static int ALSAThread( aout_instance_t * p_aout ) cleanup: snd_pcm_drop( p_sys->p_snd_pcm ); free( p_aout->output.p_sys->p_status ); - return 0; + vlc_restorecancel (canc); + return NULL; } /***************************************************************************** @@ -862,7 +844,7 @@ static void ALSAFill( aout_instance_t * p_aout ) } p_buffer = aout_OutputNextBuffer( p_aout, next_date, - (p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i')) ); + (p_aout->output.output.i_format == VLC_CODEC_SPDIFL) ); /* Audio output buffer shortage -> stop the fill process and wait */ if( p_buffer == NULL ) @@ -879,7 +861,7 @@ static void ALSAFill( aout_instance_t * p_aout ) * (stream is suspended and waiting for an application recovery) */ msg_Dbg( p_aout, "entering in suspend mode, trying to resume..." ); - while( !p_aout->b_die && !p_aout->p_libvlc->b_die && + while( vlc_object_alive (p_aout) && vlc_object_alive (p_aout->p_libvlc) && ( i_snd_rc = snd_pcm_resume( p_sys->p_snd_pcm ) ) == -EAGAIN ) { msleep( 1000000 ); @@ -914,6 +896,9 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name, { module_config_t *p_item; int i; + (void)newval; + (void)oldval; + (void)p_unused; p_item = config_FindConfig( p_this, psz_name ); if( !p_item ) return VLC_SUCCESS; @@ -939,7 +924,6 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name, p_item->b_dirty = true; return VLC_SUCCESS; - } @@ -986,15 +970,20 @@ static void GetDevicesForCard( module_config_t *p_item, int i_card ) continue; } - asprintf( &psz_device, "hw:%d,%d", i_card, i_pcm_device ); - asprintf( &psz_descr, "%s: %s (%s)", psz_card_name, - snd_pcm_info_get_name(p_pcm_info), psz_device ); + if( asprintf( &psz_device, "hw:%d,%d", i_card, i_pcm_device ) == -1 ) + break; + if( asprintf( &psz_descr, "%s: %s (%s)", psz_card_name, + snd_pcm_info_get_name(p_pcm_info), psz_device ) == -1 ) + { + free( psz_device ); + break; + } p_item->ppsz_list = - (const char **)realloc( p_item->ppsz_list, + (char **)realloc( p_item->ppsz_list, (p_item->i_list + 2) * sizeof(char *) ); p_item->ppsz_list_text = - (const char **)realloc( 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;