/***************************************************************************** * aout_FiltersCreatePipeline: create a filters pipeline to transform a sample * format to another ***************************************************************************** * TODO : allow the user to add/remove specific filters *****************************************************************************/ int aout_FiltersCreatePipeline( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) { audio_sample_format_t temp_format; int i_nb_conversions; if ( AOUT_FMTS_IDENTICAL( p_input_format, p_output_format ) ) { msg_Dbg( p_aout, "no need for any filter" ); *pi_nb_filters = 0; return 0; } aout_FormatsPrint( p_aout, "filter(s)", p_input_format, p_output_format ); /* Try to find a filter to do the whole conversion. */ pp_filters[0] = FindFilter( p_aout, p_input_format, p_output_format ); if ( pp_filters[0] != NULL ) { msg_Dbg( p_aout, "found a filter for the whole conversion" ); *pi_nb_filters = 1; return 0; } /* We'll have to split the conversion. We always do the downmixing * before the resampling, because the audio decoder can probably do it * for us. */ i_nb_conversions = SplitConversion( p_input_format, p_output_format, &temp_format ); if ( !i_nb_conversions ) { /* There was only one conversion to do, and we already failed. */ msg_Err( p_aout, "couldn't find a filter for the conversion" ); return -1; } pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); if ( pp_filters[0] == NULL && i_nb_conversions == 2 ) { /* Try with only one conversion. */ SplitConversion( p_input_format, &temp_format, &temp_format ); pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); } if ( pp_filters[0] == NULL ) { msg_Err( p_aout, "couldn't find a filter for the first part of the conversion" ); return -1; } /* We have the first stage of the conversion. Find a filter for * the rest. */ pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, p_output_format ); if ( pp_filters[1] == NULL ) { /* Try to split the conversion. */ i_nb_conversions = SplitConversion( &pp_filters[0]->output, p_output_format, &temp_format ); if ( !i_nb_conversions ) { vlc_object_detach( pp_filters[0] ); vlc_object_destroy( pp_filters[0] ); msg_Err( p_aout, "couldn't find a filter for the second part of the conversion" ); } pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, &temp_format ); pp_filters[2] = FindFilter( p_aout, &temp_format, p_output_format ); if ( pp_filters[1] == NULL || pp_filters[2] == NULL ) { vlc_object_detach( pp_filters[0] ); vlc_object_destroy( pp_filters[0] ); if ( pp_filters[1] != NULL ) { vlc_object_detach( pp_filters[1] ); vlc_object_destroy( pp_filters[1] ); } if ( pp_filters[2] != NULL ) { vlc_object_detach( pp_filters[2] ); vlc_object_destroy( pp_filters[2] ); } msg_Err( p_aout, "couldn't find filters for the second part of the conversion" ); } *pi_nb_filters = 3; } else { *pi_nb_filters = 2; } /* We have enough filters. */ msg_Dbg( p_aout, "found %d filters for the whole conversion", *pi_nb_filters ); return 0; }
/***************************************************************************** * aout_FiltersCreatePipeline: create a filters pipeline to transform a sample * format to another ***************************************************************************** * pi_nb_filters must be initialized before calling this function *****************************************************************************/ int aout_FiltersCreatePipeline( aout_instance_t * p_aout, aout_filter_t ** pp_filters_start, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) { aout_filter_t** pp_filters = pp_filters_start + *pi_nb_filters; audio_sample_format_t temp_format; int i_nb_conversions; if ( AOUT_FMTS_IDENTICAL( p_input_format, p_output_format ) ) { msg_Dbg( p_aout, "no need for any filter" ); return 0; } aout_FormatsPrint( p_aout, "filter(s)", p_input_format, p_output_format ); if( *pi_nb_filters + 1 > AOUT_MAX_FILTERS ) { msg_Err( p_aout, "max filter reached (%d)", AOUT_MAX_FILTERS ); return -1; } /* Try to find a filter to do the whole conversion. */ pp_filters[0] = FindFilter( p_aout, p_input_format, p_output_format ); if ( pp_filters[0] != NULL ) { msg_Dbg( p_aout, "found a filter for the whole conversion" ); ++*pi_nb_filters; return 0; } /* We'll have to split the conversion. We always do the downmixing * before the resampling, because the audio decoder can probably do it * for us. */ i_nb_conversions = SplitConversion( p_input_format, p_output_format, &temp_format ); if ( !i_nb_conversions ) { /* There was only one conversion to do, and we already failed. */ msg_Err( p_aout, "couldn't find a filter for the conversion" ); return -1; } pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); if ( pp_filters[0] == NULL && i_nb_conversions == 2 ) { /* Try with only one conversion. */ SplitConversion( p_input_format, &temp_format, &temp_format ); pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); } if ( pp_filters[0] == NULL ) { msg_Err( p_aout, "couldn't find a filter for the first part of the conversion" ); return -1; } /* We have the first stage of the conversion. Find a filter for * the rest. */ if( *pi_nb_filters + 2 > AOUT_MAX_FILTERS ) { ReleaseFilter( pp_filters[0] ); msg_Err( p_aout, "max filter reached (%d)", AOUT_MAX_FILTERS ); return -1; } pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, p_output_format ); if ( pp_filters[1] == NULL ) { /* Try to split the conversion. */ i_nb_conversions = SplitConversion( &pp_filters[0]->output, p_output_format, &temp_format ); if ( !i_nb_conversions ) { ReleaseFilter( pp_filters[0] ); msg_Err( p_aout, "couldn't find a filter for the second part of the conversion" ); return -1; } if( *pi_nb_filters + 3 > AOUT_MAX_FILTERS ) { ReleaseFilter( pp_filters[0] ); msg_Err( p_aout, "max filter reached (%d)", AOUT_MAX_FILTERS ); return -1; } pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, &temp_format ); pp_filters[2] = FindFilter( p_aout, &temp_format, p_output_format ); if ( pp_filters[1] == NULL || pp_filters[2] == NULL ) { ReleaseFilter( pp_filters[0] ); if ( pp_filters[1] != NULL ) { ReleaseFilter( pp_filters[1] ); } if ( pp_filters[2] != NULL ) { ReleaseFilter( pp_filters[2] ); } msg_Err( p_aout, "couldn't find filters for the second part of the conversion" ); return -1; } *pi_nb_filters += 3; msg_Dbg( p_aout, "found 3 filters for the whole conversion" ); } else { *pi_nb_filters += 2; msg_Dbg( p_aout, "found 2 filters for the whole conversion" ); } return 0; }