X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Faudio_output%2Fintf.c;h=017ece22599c726817ffb802045b7c32f5bc9286;hb=a5dc11a80916461de6e279143db532d7782cfea2;hp=ed0c78b70d751022c412893a547df5297e04df0f;hpb=f5236c7b95a3966f2f80fe3d4980a90b81d72dfa;p=vlc diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c index ed0c78b70d..017ece2259 100644 --- a/src/audio_output/intf.c +++ b/src/audio_output/intf.c @@ -38,6 +38,26 @@ #include #include "aout_internal.h" +#include + +static aout_instance_t *findAout (vlc_object_t *obj) +{ + input_thread_t *(*pf_find_input) (vlc_object_t *); + + pf_find_input = var_GetAddress (obj, "find-input-callback"); + if (unlikely(pf_find_input == NULL)) + return NULL; + + input_thread_t *p_input = pf_find_input (obj); + if (p_input == NULL) + return NULL; + + aout_instance_t *p_aout = input_GetAout (p_input); + vlc_object_release (p_input); + return p_aout; +} +#define findAout(o) findAout(VLC_OBJECT(o)) + /* * Volume management * @@ -61,161 +81,232 @@ * a very low volume and users may complain. */ +enum { + SET_MUTE=1, + SET_VOLUME=2, + INCREMENT_VOLUME=4, + TOGGLE_MUTE=8 +}; + /***************************************************************************** - * aout_VolumeGet : get the volume of the output device + * doVolumeChanges : handle all volume changes. Internal use only to ease + * variables locking. *****************************************************************************/ -int __aout_VolumeGet( vlc_object_t * p_object, audio_volume_t * pi_volume ) +static +int doVolumeChanges( unsigned action, vlc_object_t * p_object, int i_nb_steps, + audio_volume_t i_volume, audio_volume_t * i_return_volume, + bool b_mute ) { - int i_result = 0; - aout_instance_t * p_aout = vlc_object_find( p_object, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - - if ( pi_volume == NULL ) return -1; - - if ( p_aout == NULL ) + int i_result = VLC_SUCCESS; + int i_volume_step = 1, i_new_volume = 0; + bool b_var_mute = false; + aout_instance_t *p_aout = findAout( p_object ); + + if ( p_aout ) aout_lock_volume( p_aout ); + + b_var_mute = var_GetBool( p_object, "volume-muted"); + + const bool b_unmute_condition = ( b_var_mute + && ( /* Unmute: on increments */ + ( action == INCREMENT_VOLUME ) + || /* On explicit unmute */ + ( ( action == SET_MUTE ) && !b_mute ) + || /* On toggle from muted */ + ( action == TOGGLE_MUTE ) + )); + + const bool b_mute_condition = ( !b_var_mute + && ( /* explicit */ + ( ( action == SET_MUTE ) && b_mute ) + || /* or toggle */ + ( action == TOGGLE_MUTE ) + )); + + /* If muting or unmuting when play hasn't started */ + if ( action == SET_MUTE && !b_unmute_condition && !b_mute_condition ) { - *pi_volume = (audio_volume_t)config_GetInt( p_object, "volume" ); - return 0; + if ( p_aout ) + { + aout_unlock_volume( p_aout ); + vlc_object_release( p_aout ); + } + return i_result; } - aout_lock_mixer( p_aout ); - if ( !p_aout->mixer.b_error ) + /* On UnMute */ + if ( b_unmute_condition ) { - i_result = p_aout->output.pf_volume_get( p_aout, pi_volume ); + /* Restore saved volume */ + i_volume = var_GetInteger( p_object, "saved-volume" ); + var_SetBool( p_object, "volume-muted", false ); } - else + else if ( b_mute_condition ) { - *pi_volume = (audio_volume_t)config_GetInt( p_object, "volume" ); + /* We need an initial value to backup later */ + i_volume = config_GetInt( p_object, "volume" ); } - aout_unlock_mixer( p_aout ); - vlc_object_release( p_aout ); - return i_result; -} + if ( action == INCREMENT_VOLUME ) + { + i_volume_step = var_InheritInteger( p_object, "volume-step" ); -/***************************************************************************** - * aout_VolumeSet : set the volume of the output device - *****************************************************************************/ -int __aout_VolumeSet( vlc_object_t * p_object, audio_volume_t i_volume ) -{ - config_PutInt( p_object, "volume", i_volume ); - var_SetBool( p_object->p_libvlc, "volume-change", true ); + if ( !b_unmute_condition ) + i_volume = config_GetInt( p_object, "volume" ); - var_Create( p_object->p_libvlc, "saved-volume", VLC_VAR_INTEGER ); - var_SetInteger( p_object->p_libvlc, "saved-volume" , i_volume ); + i_new_volume = (int) i_volume + i_volume_step * i_nb_steps; - aout_instance_t *p_aout = vlc_object_find( p_object, - VLC_OBJECT_AOUT, FIND_ANYWHERE ); - if ( p_aout == NULL ) - return VLC_SUCCESS; + if ( i_new_volume > AOUT_VOLUME_MAX ) + i_volume = AOUT_VOLUME_MAX; + else if ( i_new_volume < AOUT_VOLUME_MIN ) + i_volume = AOUT_VOLUME_MIN; + else + i_volume = i_new_volume; + } - int i_result = VLC_SUCCESS; - aout_lock_mixer( p_aout ); + var_SetInteger( p_object, "saved-volume" , i_volume ); + + /* On Mute */ + if ( b_mute_condition ) + { + i_volume = AOUT_VOLUME_MIN; + var_SetBool( p_object, "volume-muted", true ); + } - if ( !p_aout->mixer.b_error ) - i_result = p_aout->output.pf_volume_set( p_aout, i_volume ); + /* Commit volume changes */ + config_PutInt( p_object, "volume", i_volume ); - aout_unlock_mixer( p_aout ); + if ( p_aout ) + { + aout_lock_mixer( p_aout ); + aout_lock_input_fifos( p_aout ); + if ( p_aout->p_mixer ) + i_result = p_aout->output.pf_volume_set( p_aout, i_volume ); + aout_unlock_input_fifos( p_aout ); + aout_unlock_mixer( p_aout ); + } - var_SetBool( p_aout, "intf-change", true ); - vlc_object_release( p_aout ); + /* trigger callbacks */ + var_TriggerCallback( p_object, "volume-change" ); + if ( p_aout ) + { + var_SetBool( p_aout, "intf-change", true ); + aout_unlock_volume( p_aout ); + vlc_object_release( p_aout ); + } + + if ( i_return_volume != NULL ) + *i_return_volume = i_volume; return i_result; } +#undef aout_VolumeGet /***************************************************************************** - * aout_VolumeInfos : get the boundary pi_soft + * aout_VolumeGet : get the volume of the output device *****************************************************************************/ -int __aout_VolumeInfos( vlc_object_t * p_object, audio_volume_t * pi_soft ) +int aout_VolumeGet( vlc_object_t * p_object, audio_volume_t * pi_volume ) { - aout_instance_t * p_aout = vlc_object_find( p_object, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - int i_result; + int i_result = 0; + aout_instance_t * p_aout = findAout( p_object ); - if ( p_aout == NULL ) return 0; + if ( pi_volume == NULL ) return -1; + if ( p_aout == NULL ) + { + *pi_volume = (audio_volume_t)config_GetInt( p_object, "volume" ); + return 0; + } + + aout_lock_volume( p_aout ); aout_lock_mixer( p_aout ); - if ( p_aout->mixer.b_error ) + if ( p_aout->p_mixer ) { - /* The output module is destroyed. */ - i_result = -1; + i_result = p_aout->output.pf_volume_get( p_aout, pi_volume ); } else { - i_result = p_aout->output.pf_volume_infos( p_aout, pi_soft ); + *pi_volume = (audio_volume_t)config_GetInt( p_object, "volume" ); } aout_unlock_mixer( p_aout ); + aout_unlock_volume( p_aout ); vlc_object_release( p_aout ); return i_result; } +#undef aout_VolumeSet +/***************************************************************************** + * aout_VolumeSet : set the volume of the output device + *****************************************************************************/ +int aout_VolumeSet( vlc_object_t * p_object, audio_volume_t i_volume ) +{ + return doVolumeChanges( SET_VOLUME, p_object, 1, i_volume, NULL, true ); +} + +#undef aout_VolumeUp /***************************************************************************** * aout_VolumeUp : raise the output volume ***************************************************************************** * If pi_volume != NULL, *pi_volume will contain the volume at the end of the * function. *****************************************************************************/ -int __aout_VolumeUp( vlc_object_t * p_object, int i_nb_steps, +int aout_VolumeUp( vlc_object_t * p_object, int i_nb_steps, audio_volume_t * pi_volume ) { - - const int i_volume_step = config_GetInt( p_object->p_libvlc, "volume-step" ); - - int i_volume = config_GetInt( p_object, "volume" ) + - i_volume_step * i_nb_steps; - if ( i_volume > AOUT_VOLUME_MAX ) - i_volume = AOUT_VOLUME_MAX; - else if ( i_volume < AOUT_VOLUME_MIN ) - i_volume = AOUT_VOLUME_MIN; - if ( pi_volume != NULL ) - *pi_volume = i_volume; - - return __aout_VolumeSet( p_object, i_volume ); + return doVolumeChanges( INCREMENT_VOLUME, p_object, i_nb_steps, 0, pi_volume, true ); } +#undef aout_VolumeDown /***************************************************************************** * aout_VolumeDown : lower the output volume ***************************************************************************** * If pi_volume != NULL, *pi_volume will contain the volume at the end of the * function. *****************************************************************************/ -int __aout_VolumeDown( vlc_object_t * p_object, int i_nb_steps, +int aout_VolumeDown( vlc_object_t * p_object, int i_nb_steps, audio_volume_t * pi_volume ) { - return __aout_VolumeUp( p_object, -i_nb_steps, pi_volume ); + return aout_VolumeUp( p_object, -i_nb_steps, pi_volume ); } +#undef aout_ToggleMute /***************************************************************************** * aout_ToggleMute : 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_ToggleMute( vlc_object_t * p_object, audio_volume_t * pi_volume ) +int aout_ToggleMute( vlc_object_t * p_object, audio_volume_t * pi_volume ) { - int i_result; - audio_volume_t i_volume; + return doVolumeChanges( TOGGLE_MUTE, p_object, 1, 0, pi_volume, true ); +} - i_volume = (audio_volume_t)config_GetInt( p_object, "volume" ); - if ( i_volume != 0 ) - { - /* Mute */ - i_result = aout_VolumeSet( p_object, AOUT_VOLUME_MIN ); - var_Create( p_object->p_libvlc, "saved-volume", VLC_VAR_INTEGER ); - var_SetInteger( p_object->p_libvlc, "saved-volume", (int)i_volume ); - if ( pi_volume != NULL ) *pi_volume = AOUT_VOLUME_MIN; - } - else +/***************************************************************************** + * aout_IsMuted : Get the output volume mute status + *****************************************************************************/ +bool aout_IsMuted( vlc_object_t * p_object ) +{ + bool b_return_val; + aout_instance_t * p_aout = findAout( p_object ); + if ( p_aout ) aout_lock_volume( p_aout ); + b_return_val = var_GetBool( p_object, "volume-muted"); + if ( p_aout ) { - /* Un-mute */ - var_Create( p_object->p_libvlc, "saved-volume", VLC_VAR_INTEGER ); - i_volume = (audio_volume_t)var_GetInteger( p_object->p_libvlc, - "saved-volume" ); - i_result = aout_VolumeSet( p_object, i_volume ); - if ( pi_volume != NULL ) *pi_volume = i_volume; + aout_unlock_volume( p_aout ); + vlc_object_release( p_aout ); } + return b_return_val; +} - return i_result; +/***************************************************************************** + * aout_SetMute : Sets mute status + ***************************************************************************** + * If pi_volume != NULL, *pi_volume will contain the volume at the end of the + * function (muted => 0). + *****************************************************************************/ +int aout_SetMute( vlc_object_t * p_object, audio_volume_t * pi_volume, + bool b_mute ) +{ + return doVolumeChanges( SET_MUTE, p_object, 1, 0, pi_volume, b_mute ); } /* @@ -228,7 +319,6 @@ void aout_VolumeSoftInit( aout_instance_t * p_aout ) { int i_volume; - p_aout->output.pf_volume_infos = aout_VolumeSoftInfos; p_aout->output.pf_volume_get = aout_VolumeSoftGet; p_aout->output.pf_volume_set = aout_VolumeSoftSet; @@ -245,14 +335,6 @@ void aout_VolumeSoftInit( aout_instance_t * p_aout ) aout_VolumeSoftSet( p_aout, (audio_volume_t)i_volume ); } -/* Placeholder for pf_volume_infos(). */ -int aout_VolumeSoftInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft ) -{ - (void)p_aout; - *pi_soft = 0; - return 0; -} - /* Placeholder for pf_volume_get(). */ int aout_VolumeSoftGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) { @@ -277,18 +359,10 @@ int aout_VolumeSoftSet( aout_instance_t * p_aout, audio_volume_t i_volume ) /* Meant to be called by the output plug-in's Open(). */ void aout_VolumeNoneInit( aout_instance_t * p_aout ) { - p_aout->output.pf_volume_infos = aout_VolumeNoneInfos; p_aout->output.pf_volume_get = aout_VolumeNoneGet; p_aout->output.pf_volume_set = aout_VolumeNoneSet; } -/* Placeholder for pf_volume_infos(). */ -int aout_VolumeNoneInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft ) -{ - (void)p_aout; (void)pi_soft; - return -1; -} - /* Placeholder for pf_volume_get(). */ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) { @@ -329,15 +403,16 @@ static int aout_Restart( aout_instance_t * p_aout ) return -1; } - /* Lock all inputs. */ - aout_lock_input_fifos( p_aout ); - for ( i = 0; i < p_aout->i_nb_inputs; i++ ) { aout_lock_input( p_aout, p_aout->pp_inputs[i] ); + aout_lock_input_fifos( p_aout ); aout_InputDelete( p_aout, p_aout->pp_inputs[i] ); + aout_unlock_input_fifos( p_aout ); } + /* Lock all inputs. */ + aout_lock_input_fifos( p_aout ); aout_MixerDelete( p_aout ); /* Re-open the output plug-in. */ @@ -392,8 +467,7 @@ static int aout_Restart( aout_instance_t * p_aout ) int aout_FindAndRestart( vlc_object_t * p_this, const char *psz_name, vlc_value_t oldval, vlc_value_t newval, void *p_data ) { - aout_instance_t * p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); + aout_instance_t * p_aout = findAout( pl_Get(p_this) ); (void)psz_name; (void)oldval; (void)newval; (void)p_data; if ( p_aout == NULL ) return VLC_SUCCESS; @@ -436,10 +510,9 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable, void aout_EnableFilter( vlc_object_t *p_this, const char *psz_name, bool b_add ) { - aout_instance_t *p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); + aout_instance_t *p_aout = findAout( p_this ); - if( AoutChangeFilterString( p_this, p_aout, "audio-filter", psz_name, b_add ) ) + if( aout_ChangeFilterString( p_this, p_aout, "audio-filter", psz_name, b_add ) ) { if( p_aout ) AoutInputsMarkToRestart( p_aout );