X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Faudio_output%2Fintf.c;h=2e4d42164b391a3fef87b953592a02ae76a5125b;hb=7fc0df74caec0814a9f91c5f73566578914081aa;hp=cc82727057ba2080e18c3b3d9bf98832c067370d;hpb=81442b6bf1af46dbaedc3388ea0b48f55bf13ae1;p=vlc diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c index cc82727057..2e4d42164b 100644 --- a/src/audio_output/intf.c +++ b/src/audio_output/intf.c @@ -2,7 +2,7 @@ * intf.c : audio output API towards the interface modules ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: intf.c,v 1.3 2002/09/19 21:56:40 massiot Exp $ + * $Id: intf.c,v 1.11 2002/12/10 18:22:01 gbazin Exp $ * * Authors: Christophe Massiot * @@ -10,7 +10,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -32,6 +32,7 @@ #include "audio_output.h" #include "aout_internal.h" + /* * Volume management * @@ -40,7 +41,7 @@ * mixer is running, so we need the mixer lock (too). * * Here is a schematic of the i_volume range : - * + * * |------------------------------+---------------------------------------| * 0 pi_soft 1024 * @@ -64,7 +65,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) vlc_mutex_lock( &p_aout->mixer_lock ); - if ( p_aout->i_nb_inputs == 0 ) + if ( p_aout->mixer.b_error ) { /* The output module is destroyed. */ vlc_mutex_unlock( &p_aout->mixer_lock ); @@ -87,7 +88,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume ) vlc_mutex_lock( &p_aout->mixer_lock ); - if ( p_aout->i_nb_inputs == 0 ) + if ( p_aout->mixer.b_error ) { /* The output module is destroyed. */ vlc_mutex_unlock( &p_aout->mixer_lock ); @@ -102,7 +103,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume ) } /***************************************************************************** - * aout_VolumeInfos : get the boundaries pi_low_soft and pi_high_soft + * aout_VolumeInfos : get the boundary pi_soft *****************************************************************************/ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft ) { @@ -110,7 +111,7 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft ) vlc_mutex_lock( &p_aout->mixer_lock ); - if ( p_aout->i_nb_inputs == 0 ) + if ( p_aout->mixer.b_error ) { /* The output module is destroyed. */ vlc_mutex_unlock( &p_aout->mixer_lock ); @@ -138,7 +139,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps, vlc_mutex_lock( &p_aout->mixer_lock ); - if ( p_aout->i_nb_inputs == 0 ) + if ( p_aout->mixer.b_error ) { /* The output module is destroyed. */ vlc_mutex_unlock( &p_aout->mixer_lock ); @@ -177,7 +178,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps, vlc_mutex_lock( &p_aout->mixer_lock ); - if ( p_aout->i_nb_inputs == 0 ) + if ( p_aout->mixer.b_error ) { /* The output module is destroyed. */ vlc_mutex_unlock( &p_aout->mixer_lock ); @@ -204,6 +205,51 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps, return i_result; } +/***************************************************************************** + * aout_VolumeMute : Mute/un-mute the output volume + ***************************************************************************** + * If pi_volume != NULL, *pi_volume will contain the volume at the end of the + * function (muted => 0). + *****************************************************************************/ +int aout_VolumeMute( aout_instance_t * p_aout, audio_volume_t * pi_volume ) +{ + int i_result; + audio_volume_t i_volume; + + vlc_mutex_lock( &p_aout->mixer_lock ); + + if ( p_aout->mixer.b_error ) + { + /* The output module is destroyed. */ + vlc_mutex_unlock( &p_aout->mixer_lock ); + msg_Err( p_aout, "VolumeUp called without output module" ); + return -1; + } + + if ( p_aout->output.pf_volume_get( p_aout, &i_volume ) ) + { + vlc_mutex_unlock( &p_aout->mixer_lock ); + return -1; + } + + if ( i_volume == 0 ) + { + i_volume = p_aout->output.i_saved_volume; + } + else + { + p_aout->output.i_saved_volume = i_volume; + i_volume = 0; + } + + i_result = p_aout->output.pf_volume_set( p_aout, i_volume ); + + vlc_mutex_unlock( &p_aout->mixer_lock ); + + if ( pi_volume != NULL ) *pi_volume = i_volume; + return i_result; +} + /* * The next functions are not supposed to be called by the interface, but * are placeholders for software-only scaling. @@ -219,12 +265,16 @@ void aout_VolumeSoftInit( aout_instance_t * p_aout ) p_aout->output.pf_volume_set = aout_VolumeSoftSet; i_volume = config_GetInt( p_aout, "volume" ); - if ( i_volume == -1 ) + if ( i_volume < 0 ) { i_volume = AOUT_VOLUME_DEFAULT; } + else if ( i_volume > AOUT_VOLUME_MAX ) + { + i_volume = AOUT_VOLUME_MAX; + } - aout_VolumeSoftSet( p_aout, i_volume ); + aout_VolumeSoftSet( p_aout, (audio_volume_t)i_volume ); } /* Placeholder for pf_volume_infos(). */ @@ -275,10 +325,131 @@ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) return -1; } - /* Placeholder for pf_volume_set(). */ int aout_VolumeNoneSet( aout_instance_t * p_aout, audio_volume_t i_volume ) { return -1; } + +/* + * Pipelines management + */ + +/***************************************************************************** + * aout_Restart : re-open the output device and rebuild the input and output + * pipelines + ***************************************************************************** + * This function is used whenever the parameters of the output plug-in are + * changed (eg. selecting S/PDIF or PCM). + *****************************************************************************/ +int aout_Restart( aout_instance_t * p_aout ) +{ + int i; + vlc_bool_t b_error = 0; + + vlc_mutex_lock( &p_aout->mixer_lock ); + + if ( p_aout->i_nb_inputs == 0 ) + { + vlc_mutex_unlock( &p_aout->mixer_lock ); + msg_Err( p_aout, "no decoder thread" ); + return -1; + } + + /* Lock all inputs. */ + for ( i = 0; i < p_aout->i_nb_inputs; i++ ) + { + vlc_mutex_lock( &p_aout->pp_inputs[i]->lock ); + aout_InputDelete( p_aout, p_aout->pp_inputs[i] ); + } + + aout_MixerDelete( p_aout ); + + /* Re-open the output plug-in. */ + aout_OutputDelete( p_aout ); + + if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 ) + { + /* Release all locks and report the error. */ + for ( i = 0; i < p_aout->i_nb_inputs; i++ ) + { + vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock ); + } + vlc_mutex_unlock( &p_aout->mixer_lock ); + return -1; + } + + if ( aout_MixerNew( p_aout ) == -1 ) + { + aout_OutputDelete( p_aout ); + for ( i = 0; i < p_aout->i_nb_inputs; i++ ) + { + vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock ); + } + vlc_mutex_unlock( &p_aout->mixer_lock ); + return -1; + } + + /* Re-open all inputs. */ + for ( i = 0; i < p_aout->i_nb_inputs; i++ ) + { + aout_input_t * p_input = p_aout->pp_inputs[i]; + + b_error |= aout_InputNew( p_aout, p_input ); + vlc_mutex_unlock( &p_input->lock ); + } + + vlc_mutex_unlock( &p_aout->mixer_lock ); + + return b_error; +} + +/***************************************************************************** + * aout_FindAndRestart : find the audio output instance and restart + ***************************************************************************** + * This is used for callbacks of the configuration variables, and we believe + * that when those are changed, it is a significant change which implies + * rebuilding the audio-device and audio-channels variables. + *****************************************************************************/ +void aout_FindAndRestart( vlc_object_t * p_this ) +{ + aout_instance_t * p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, + FIND_ANYWHERE ); + + if ( p_aout == NULL ) return; + + if ( var_Type( p_aout, "audio-device" ) != 0 ) + { + var_Destroy( p_aout, "audio-device" ); + } + if ( var_Type( p_aout, "audio-channels" ) != 0 ) + { + var_Destroy( p_aout, "audio-channels" ); + } + + aout_Restart( p_aout ); + vlc_object_release( p_aout ); +} + +/***************************************************************************** + * aout_ChannelsRestart : change the audio device or channels and restart + *****************************************************************************/ +int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable, + vlc_value_t old_value, vlc_value_t new_value, + void * unused ) +{ + aout_instance_t * p_aout = (aout_instance_t *)p_this; + + if ( !strcmp( psz_variable, "audio-device" ) ) + { + /* This is supposed to be a significant change and supposes + * rebuilding the channel choices. */ + if ( var_Type( p_aout, "audio-channels" ) >= 0 ) + { + var_Destroy( p_aout, "audio-channels" ); + } + } + aout_Restart( p_aout ); + return 0; +}