- var_AddCallback( p_aout, "audio-replay-gain-mode", ReplayGainCallback, NULL );
- }
- }
- if( var_Type( p_aout, "audio-replay-gain-preamp" ) == 0 )
- {
- var_Create( p_aout, "audio-replay-gain-preamp",
- VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
- }
- if( var_Type( p_aout, "audio-replay-gain-default" ) == 0 )
- {
- var_Create( p_aout, "audio-replay-gain-default",
- VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
- }
- if( var_Type( p_aout, "audio-replay-gain-peak-protection" ) == 0 )
- {
- var_Create( p_aout, "audio-replay-gain-peak-protection",
- VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
- }
- if( var_Type( p_aout, "audio-time-stretch" ) == 0 )
- {
- var_Create( p_aout, "audio-time-stretch",
- VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
- }
-
- psz_filters = var_GetString( p_aout, "audio-filter" );
- psz_visual = var_GetString( p_aout, "audio-visual");
- psz_scaletempo = var_GetBool( p_aout, "audio-time-stretch" ) ? strdup( "scaletempo" ) : NULL;
-
- p_input->b_recycle_vout = psz_visual && *psz_visual;
-
- /* parse user filter lists */
- char *const ppsz_array[] = { psz_scaletempo, psz_filters, psz_visual };
- p_input->p_playback_rate_filter = NULL;
-
- for( i_visual = 0; i_visual < 3 && !AOUT_FMT_NON_LINEAR(&chain_output_format); i_visual++ )
- {
- char *psz_next = NULL;
- char *psz_parser = ppsz_array[i_visual];
-
- if( psz_parser == NULL || !*psz_parser )
- continue;
-
- while( psz_parser && *psz_parser )
- {
- 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 */
- static const char typename[] = "audio filter";
- p_filter = vlc_custom_create( p_aout, sizeof(*p_filter),
- VLC_OBJECT_GENERIC, typename );
- 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 );
-
- p_filter->p_owner = malloc( sizeof(*p_filter->p_owner) );
- p_filter->p_owner->p_aout = p_aout;
- p_filter->p_owner->p_input = p_input;
-
- /* request format */
- memcpy( &p_filter->fmt_in.audio, &chain_output_format,
- sizeof(audio_sample_format_t) );
- p_filter->fmt_in.i_codec = chain_output_format.i_format;
- memcpy( &p_filter->fmt_out.audio, &chain_output_format,
- sizeof(audio_sample_format_t) );
- p_filter->fmt_out.i_codec = chain_output_format.i_format;
- p_filter->pf_audio_buffer_new = aout_FilterBufferNew;
-
- /* try to find the requested filter */
- if( i_visual == 2 ) /* this can only be a visualization module */
- {
- p_filter->p_module = module_need( p_filter, "visualization2",
- psz_parser, true );
- }
- else /* this can be a audio filter module as well as a visualization module */
- {
- p_filter->p_module = module_need( p_filter, "audio filter",
- psz_parser, true );
-
- if ( p_filter->p_module == NULL )
- {
- /* if the filter requested a special format, retry */
- if ( !( AOUT_FMTS_IDENTICAL( &p_filter->fmt_in.audio,
- &chain_input_format )
- && AOUT_FMTS_IDENTICAL( &p_filter->fmt_out.audio,
- &chain_output_format ) ) )
- {
- aout_FormatPrepare( &p_filter->fmt_in.audio );
- aout_FormatPrepare( &p_filter->fmt_out.audio );
- p_filter->p_module = module_need( p_filter,
- "audio filter",
- psz_parser, true );
- }
- /* try visual filters */
- else
- {
- memcpy( &p_filter->fmt_in.audio, &chain_output_format,
- sizeof(audio_sample_format_t) );
- memcpy( &p_filter->fmt_out.audio, &chain_output_format,
- sizeof(audio_sample_format_t) );
- p_filter->p_module = module_need( p_filter,
- "visualization2",
- psz_parser, true );
- }
- }
- }
-
- /* failure */
- if ( p_filter->p_module == NULL )
- {
- msg_Err( p_aout, "cannot add user filter %s (skipped)",
- psz_parser );
-
- free( p_filter->p_owner );
- 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->fmt_in.audio ) )
- {
- if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
- &p_input->i_nb_filters,
- &chain_input_format,
- &p_filter->fmt_in.audio ) < 0 )
- {
- msg_Err( p_aout, "cannot add user filter %s (skipped)",
- psz_parser );
-
- module_unneed( p_filter, p_filter->p_module );
- free( p_filter->p_owner );
- vlc_object_release( p_filter );
-
- psz_parser = psz_next;
- continue;
- }
- }
-
- /* success */
- p_input->pp_filters[p_input->i_nb_filters++] = p_filter;
- memcpy( &chain_input_format, &p_filter->fmt_out.audio,
- sizeof( audio_sample_format_t ) );
-
- if( i_visual == 0 ) /* scaletempo */
- p_input->p_playback_rate_filter = p_filter;
-
- /* next filter if any */
- psz_parser = psz_next;
- }
- }
- free( psz_visual );
- free( psz_filters );
- free( psz_scaletempo );
-
- /* complete the filter chain if necessary */
- if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &chain_output_format ) )
- {
- if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
- &p_input->i_nb_filters,
- &chain_input_format,
- &chain_output_format ) < 0 )
- {
- inputFailure( p_aout, p_input, "couldn't set an input pipeline" );
- return -1;
- }
- }
-
- /* Prepare hints for the buffer allocator. */
- p_input->input_alloc.b_alloc = true;
- p_input->input_alloc.i_bytes_per_sec = -1;
-
- /* Create resamplers. */
- if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer_format ) )
- {
- chain_output_format.i_rate = (__MAX(p_input->input.i_rate,
- p_aout->mixer_format.i_rate)
- * (100 + AOUT_MAX_RESAMPLING)) / 100;
- if ( chain_output_format.i_rate == p_aout->mixer_format.i_rate )
- {
- /* Just in case... */
- chain_output_format.i_rate++;
- }
- if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers,
- &p_input->i_nb_resamplers,
- &chain_output_format,
- &p_aout->mixer_format ) < 0 )
- {
- inputFailure( p_aout, p_input, "couldn't set a resampler pipeline");
- return -1;
- }
-
- aout_FiltersHintBuffers( p_aout, p_input->pp_resamplers,
- p_input->i_nb_resamplers,
- &p_input->input_alloc );
- p_input->input_alloc.b_alloc = true;
-
- /* Setup the initial rate of the resampler */
- p_input->pp_resamplers[0]->fmt_in.audio.i_rate = p_input->input.i_rate;
- }