Commit 36d1d663 authored by Laurent Aimar's avatar Laurent Aimar

Fixed a segfault in aout_EnableFilter.

Fixed missing lock in aout callbacks !
Factorized duplicated code.
parent ab131d8b
...@@ -138,4 +138,77 @@ aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t ); ...@@ -138,4 +138,77 @@ aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t );
void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * ); void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * );
int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate ); int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate );
/* Helpers */
/**
* This function will safely mark aout input to be restarted as soon as
* possible to take configuration changes into account */
static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout )
{
int i;
vlc_mutex_lock( &p_aout->mixer_lock );
for( i = 0; i < p_aout->i_nb_inputs; i++ )
p_aout->pp_inputs[i]->b_restart = true;
vlc_mutex_unlock( &p_aout->mixer_lock );
}
/* This function will add or remove a a module from a string list (comma
* separated). It will return true if there is a modification
* In case p_aout is NULL, we will use configuration instead of variable */
static inline bool AoutChangeFilterString( vlc_object_t *p_obj, aout_instance_t * p_aout,
const char* psz_variable,
const char *psz_name, bool b_add )
{
vlc_value_t val;
char *psz_parser;
if( *psz_name == '\0' )
return false;
if( p_aout )
var_Get( p_aout, psz_variable, &val );
else
val.psz_string = config_GetPsz( p_obj, "audio-filter" );
if( !val.psz_string )
val.psz_string = strdup("");
psz_parser = strstr( val.psz_string, psz_name );
if( ( b_add && psz_parser ) || ( !b_add && !psz_parser ) )
{
/* Nothing to do */
free( val.psz_string );
return false;
}
if( b_add )
{
char *psz_old = val.psz_string;
if( *psz_old )
asprintf( &val.psz_string, "%s:%s", psz_old, psz_name );
else
val.psz_string = strdup( psz_name );
free( psz_old );
}
else
{
const int i_name = strlen( psz_name );
const char *psz_next;
psz_next = &psz_parser[i_name];
if( *psz_next == ':' )
psz_next++;
memmove( psz_parser, psz_next, strlen(psz_next)+1 );
}
if( p_aout )
var_Set( p_aout, psz_variable, val );
else
config_PutPsz( p_obj, psz_variable, val.psz_string );
free( val.psz_string );
return true;
}
#endif /* !__LIBVLC_AOUT_INTERNAL_H */ #endif /* !__LIBVLC_AOUT_INTERNAL_H */
...@@ -766,47 +766,8 @@ static void inputResamplingStop( aout_input_t *p_input ) ...@@ -766,47 +766,8 @@ static void inputResamplingStop( aout_input_t *p_input )
static int ChangeFiltersString( aout_instance_t * p_aout, const char* psz_variable, static int ChangeFiltersString( aout_instance_t * p_aout, const char* psz_variable,
const char *psz_name, bool b_add ) const char *psz_name, bool b_add )
{ {
vlc_value_t val; return AoutChangeFilterString( VLC_OBJECT(p_aout), p_aout,
char *psz_parser; psz_variable, psz_name, b_add ) ? 1 : 0;
var_Get( p_aout, psz_variable, &val );
if( !val.psz_string ) val.psz_string = strdup("");
psz_parser = strstr( val.psz_string, psz_name );
if( b_add )
{
if( !psz_parser )
{
psz_parser = val.psz_string;
asprintf( &val.psz_string, (*val.psz_string) ? "%s:%s" : "%s%s",
val.psz_string, psz_name );
free( psz_parser );
}
else
{
return 0;
}
}
else
{
if( psz_parser )
{
memmove( psz_parser, psz_parser + strlen(psz_name) +
(*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
strlen(psz_parser + strlen(psz_name)) + 1 );
}
else
{
free( val.psz_string );
return 0;
}
}
var_Set( p_aout, psz_variable, val );
free( val.psz_string );
return 1;
} }
static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd, static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd,
...@@ -815,7 +776,6 @@ static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -815,7 +776,6 @@ static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd,
aout_instance_t *p_aout = (aout_instance_t *)p_this; aout_instance_t *p_aout = (aout_instance_t *)p_this;
char *psz_mode = newval.psz_string; char *psz_mode = newval.psz_string;
vlc_value_t val; vlc_value_t val;
int i;
(void)psz_cmd; (void)oldval; (void)p_data; (void)psz_cmd; (void)oldval; (void)p_data;
if( !psz_mode || !*psz_mode ) if( !psz_mode || !*psz_mode )
...@@ -851,10 +811,7 @@ static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -851,10 +811,7 @@ static int VisualizationCallback( vlc_object_t *p_this, char const *psz_cmd,
} }
/* That sucks */ /* That sucks */
for( i = 0; i < p_aout->i_nb_inputs; i++ ) AoutInputsMarkToRestart( p_aout );
{
p_aout->pp_inputs[i]->b_restart = true;
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -865,7 +822,6 @@ static int EqualizerCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -865,7 +822,6 @@ static int EqualizerCallback( vlc_object_t *p_this, char const *psz_cmd,
aout_instance_t *p_aout = (aout_instance_t *)p_this; aout_instance_t *p_aout = (aout_instance_t *)p_this;
char *psz_mode = newval.psz_string; char *psz_mode = newval.psz_string;
vlc_value_t val; vlc_value_t val;
int i;
int i_ret; int i_ret;
(void)psz_cmd; (void)oldval; (void)p_data; (void)psz_cmd; (void)oldval; (void)p_data;
...@@ -886,13 +842,7 @@ static int EqualizerCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -886,13 +842,7 @@ static int EqualizerCallback( vlc_object_t *p_this, char const *psz_cmd,
/* That sucks */ /* That sucks */
if( i_ret == 1 ) if( i_ret == 1 )
{ AoutInputsMarkToRestart( p_aout );
for( i = 0; i < p_aout->i_nb_inputs; i++ )
{
p_aout->pp_inputs[i]->b_restart = true;
}
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -489,64 +489,17 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable, ...@@ -489,64 +489,17 @@ int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable,
void aout_EnableFilter( vlc_object_t *p_this, const char *psz_name, void aout_EnableFilter( vlc_object_t *p_this, const char *psz_name,
bool b_add ) bool b_add )
{ {
char *psz_parser, *psz_string; aout_instance_t *p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT,
aout_instance_t * p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
FIND_ANYWHERE );
if( p_aout )
psz_string = var_GetNonEmptyString( p_aout, "audio-filter" );
else
psz_string = config_GetPsz( p_this, "audio-filter" );
if( !psz_string ) psz_string = strdup(""); if( AoutChangeFilterString( p_this, p_aout, "audio-filter", psz_name, b_add ) )
psz_parser = strstr( psz_string, psz_name );
if( b_add )
{ {
if( !psz_parser ) if( p_aout )
{ AoutInputsMarkToRestart( p_aout );
psz_parser = psz_string;
asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
psz_string, psz_name );
free( psz_parser );
}
else
{
vlc_object_release( p_aout );
return;
}
}
else
{
if( psz_parser )
{
memmove( psz_parser, psz_parser + strlen(psz_name) +
(*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
strlen(psz_parser + strlen(psz_name)) + 1 );
if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
{
*(psz_string+strlen(psz_string ) -1 ) = '\0';
}
}
else
{
free( psz_string );
return;
}
} }
if( p_aout == NULL ) if( p_aout )
config_PutPsz( p_this, "audio-filter", psz_string );
else
{
var_SetString( p_aout, "audio-filter", psz_string );
for( int i = 0; i < p_aout->i_nb_inputs; i++ )
p_aout->pp_inputs[i]->b_restart = true;
vlc_object_release( p_aout ); vlc_object_release( p_aout );
}
free( psz_string );
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment