+ aout_filter_t * p_filter = NULL;
+
+ if( p_input->i_nb_filters >= AOUT_MAX_FILTERS )
+ {
+ msg_Dbg( p_aout, "max filters reached (%d)", AOUT_MAX_FILTERS );
+ break;
+ }
+
+ while( *psz_parser == ' ' && *psz_parser == ':' )
+ {
+ psz_parser++;
+ }
+ if( ( psz_next = strchr( psz_parser , ':' ) ) )
+ {
+ *psz_next++ = '\0';
+ }
+ if( *psz_parser =='\0' )
+ {
+ break;
+ }
+
+ /* Create a VLC object */
+ p_filter = vlc_object_create( p_aout, sizeof(aout_filter_t) );
+ if( p_filter == NULL )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+ psz_parser = psz_next;
+ continue;
+ }
+
+ vlc_object_attach( p_filter , p_aout );
+
+ /* try to find the requested filter */
+ if( i_visual == 1 ) /* this can only be a visualization module */
+ {
+ /* request format */
+ memcpy( &p_filter->input, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+
+ p_filter->p_module = module_Need( p_filter, "visualization",
+ psz_parser, VLC_TRUE );
+ }
+ else /* this can be a audio filter module as well as a visualization module */
+ {
+ /* request format */
+ memcpy( &p_filter->input, &chain_input_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+
+ p_filter->p_module = module_Need( p_filter, "audio filter",
+ psz_parser, VLC_TRUE );
+
+ if ( p_filter->p_module == NULL )
+ {
+ /* if the filter requested a special format, retry */
+ if ( !( AOUT_FMTS_IDENTICAL( &p_filter->input,
+ &chain_input_format )
+ && AOUT_FMTS_IDENTICAL( &p_filter->output,
+ &chain_output_format ) ) )
+ {
+ aout_FormatPrepare( &p_filter->input );
+ aout_FormatPrepare( &p_filter->output );
+ p_filter->p_module = module_Need( p_filter,
+ "audio filter",
+ psz_parser, VLC_TRUE );
+ }
+ /* try visual filters */
+ else
+ {
+ memcpy( &p_filter->input, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ p_filter->p_module = module_Need( p_filter,
+ "visualization",
+ psz_parser, VLC_TRUE );
+ }
+ }
+ }
+
+ /* failure */
+ if ( p_filter->p_module == NULL )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+
+ vlc_object_detach( p_filter );
+ vlc_object_release( p_filter );
+
+ psz_parser = psz_next;
+ continue;
+ }
+
+ /* complete the filter chain if necessary */
+ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &p_filter->input ) )
+ {
+ if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
+ &p_input->i_nb_filters,
+ &chain_input_format,
+ &p_filter->input ) < 0 )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+
+ module_Unneed( p_filter, p_filter->p_module );
+ vlc_object_detach( p_filter );
+ vlc_object_release( p_filter );
+
+ psz_parser = psz_next;
+ continue;
+ }
+ }
+
+ /* success */
+ p_filter->b_continuity = VLC_FALSE;
+ p_input->pp_filters[p_input->i_nb_filters++] = p_filter;
+ memcpy( &chain_input_format, &p_filter->output,
+ sizeof( audio_sample_format_t ) );
+
+ /* next filter if any */
+ psz_parser = psz_next;