X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Faudio_output%2Fintf.c;h=017ece22599c726817ffb802045b7c32f5bc9286;hb=ecddc9b761c5a577835d7510d04c19568a581232;hp=64e54a221ee13455b39e92649a271e2f8702cd4a;hpb=5a55a589848fa6c68395288ab2bb47b45695cb1e;p=vlc diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c index 64e54a221e..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,210 +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 ) -{ - vlc_value_t val; - aout_instance_t *p_aout = vlc_object_find( p_object, VLC_OBJECT_AOUT, FIND_ANYWHERE ); - int i_result = 0; + if ( !b_unmute_condition ) + i_volume = config_GetInt( p_object, "volume" ); - config_PutInt( p_object, "volume", i_volume ); + i_new_volume = (int) i_volume + i_volume_step * i_nb_steps; - val.b_bool = true; - var_Set( p_object->p_libvlc, "volume-change", val ); + 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; + } - if ( p_aout == NULL ) return 0; + var_SetInteger( p_object, "saved-volume" , i_volume ); - aout_lock_mixer( p_aout ); - if ( !p_aout->mixer.b_error ) + /* On Mute */ + if ( b_mute_condition ) { - i_result = p_aout->output.pf_volume_set( p_aout, i_volume ); + i_volume = AOUT_VOLUME_MIN; + var_SetBool( p_object, "volume-muted", true ); } - aout_unlock_mixer( p_aout ); - var_Set( p_aout, "intf-change", val ); - vlc_object_release( p_aout ); + /* Commit volume changes */ + config_PutInt( p_object, "volume", i_volume ); + + 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 ); + } + + /* 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 ( pi_volume == NULL ) return -1; - if ( p_aout == NULL ) return 0; + 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 ) { - vlc_value_t val; - aout_instance_t * p_aout = vlc_object_find( p_object, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - int i_result = 0, i_volume = 0, i_volume_step = 0; - - i_volume_step = config_GetInt( p_object->p_libvlc, "volume-step" ); - i_volume = config_GetInt( p_object, "volume" ); - i_volume += i_volume_step * i_nb_steps; - if ( i_volume > AOUT_VOLUME_MAX ) - { - i_volume = AOUT_VOLUME_MAX; - } - config_PutInt( p_object, "volume", i_volume ); - var_Create( p_object->p_libvlc, "saved-volume", VLC_VAR_INTEGER ); - var_SetInteger( p_object->p_libvlc, "saved-volume" , - (audio_volume_t) i_volume ); - if ( pi_volume != NULL ) *pi_volume = (audio_volume_t) i_volume; - - val.b_bool = true; - var_Set( p_object->p_libvlc, "volume-change", val ); - - if ( p_aout == NULL ) return 0; - - aout_lock_mixer( p_aout ); - if ( !p_aout->mixer.b_error ) - { - i_result = p_aout->output.pf_volume_set( p_aout, - (audio_volume_t) i_volume ); - } - aout_unlock_mixer( p_aout ); - - vlc_object_release( p_aout ); - return i_result; + 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 ) { - vlc_value_t val; - aout_instance_t * p_aout = vlc_object_find( p_object, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - int i_result = 0, i_volume = 0, i_volume_step = 0; - - i_volume_step = config_GetInt( p_object->p_libvlc, "volume-step" ); - i_volume = config_GetInt( p_object, "volume" ); - i_volume -= i_volume_step * i_nb_steps; - if ( i_volume < AOUT_VOLUME_MIN ) - { - i_volume = AOUT_VOLUME_MIN; - } - config_PutInt( p_object, "volume", i_volume ); - var_Create( p_object->p_libvlc, "saved-volume", VLC_VAR_INTEGER ); - var_SetInteger( p_object->p_libvlc, "saved-volume", (audio_volume_t) i_volume ); - if ( pi_volume != NULL ) *pi_volume = (audio_volume_t) i_volume; - - val.b_bool = true; - var_Set( p_object->p_libvlc, "volume-change", val ); - - if ( p_aout == NULL ) return 0; - - aout_lock_mixer( p_aout ); - if ( !p_aout->mixer.b_error ) - { - i_result = p_aout->output.pf_volume_set( p_aout, (audio_volume_t) i_volume ); - } - aout_unlock_mixer( p_aout ); - - vlc_object_release( p_aout ); - return i_result; + return aout_VolumeUp( p_object, -i_nb_steps, pi_volume ); } +#undef aout_ToggleMute /***************************************************************************** - * aout_VolumeMute : Mute/un-mute the output volume + * 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_VolumeMute( 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 ); } /* @@ -277,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; @@ -294,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 ) { @@ -326,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 ) { @@ -378,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. */ @@ -441,20 +467,13 @@ 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; - 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" ); - } + var_Destroy( p_aout, "audio-device" ); + var_Destroy( p_aout, "audio-channels" ); aout_Restart( p_aout ); vlc_object_release( p_aout ); @@ -476,15 +495,13 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable, { /* 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" ); - } + var_Destroy( p_aout, "audio-channels" ); } aout_Restart( p_aout ); return 0; } +#undef aout_EnableFilter /** Enable or disable an audio filter * \param p_this a vlc object * \param psz_name name of the filter @@ -493,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 ); @@ -505,15 +521,3 @@ void aout_EnableFilter( vlc_object_t *p_this, const char *psz_name, if( p_aout ) vlc_object_release( p_aout ); } - -/** - * Change audio visualization - * -1 goes backwards, +1 goes forward - */ -char *aout_VisualChange( vlc_object_t *p_this, int i_skip ) -{ - (void)p_this; (void)i_skip; - msg_Err( p_this, "FIXME: %s (%s %d) isn't implemented.", __func__, - __FILE__, __LINE__ ); - return strdup("foobar"); -}