1 /*****************************************************************************
2 * filters.c : audio output filters management
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: filters.c,v 1.1 2002/08/07 21:36:56 massiot Exp $
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* calloc(), malloc(), free() */
35 #include "audio_output.h"
36 #include "aout_internal.h"
38 /*****************************************************************************
39 * aout_FiltersCreatePipeline: create a filters pipeline to transform a sample
41 *****************************************************************************
42 * TODO : allow the user to add/remove specific filters
43 *****************************************************************************/
44 int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
45 aout_filter_t ** pp_filters,
47 audio_sample_format_t * p_input_format,
48 audio_sample_format_t * p_output_format )
50 if ( AOUT_FMTS_IDENTICAL( p_input_format, p_output_format ) )
52 msg_Dbg( p_aout, "no need for any filter" );
57 pp_filters[0] = vlc_object_create( p_aout, sizeof(aout_filter_t) );
58 if ( pp_filters[0] == NULL )
62 vlc_object_attach( pp_filters[0], p_aout );
64 /* Try to find a filter to do the whole conversion. */
65 memcpy( &pp_filters[0]->input, p_input_format,
66 sizeof(audio_sample_format_t) );
67 memcpy( &pp_filters[0]->output, p_output_format,
68 sizeof(audio_sample_format_t) );
69 pp_filters[0]->p_module = module_Need( pp_filters[0], "audio filter",
71 if ( pp_filters[0]->p_module != NULL )
73 msg_Dbg( p_aout, "found a filter for the whole conversion" );
78 /* Split the conversion : format | rate, or rate | format. */
79 pp_filters[0]->output.i_format = pp_filters[0]->input.i_format;
80 pp_filters[0]->p_module = module_Need( pp_filters[0], "audio filter",
82 if ( pp_filters[0]->p_module == NULL )
84 /* Then, start with the format conversion. */
85 memcpy( &pp_filters[0]->output, p_output_format,
86 sizeof(audio_sample_format_t) );
87 pp_filters[0]->output.i_rate = pp_filters[0]->input.i_rate;
88 pp_filters[0]->p_module = module_Need( pp_filters[0], "audio filter",
90 if ( pp_filters[0]->p_module == NULL )
92 msg_Err( p_aout, "couldn't find a filter for any conversion" );
93 vlc_object_detach_all( pp_filters[0] );
94 vlc_object_destroy( pp_filters[0] );
99 /* Find a filter for the rest. */
100 pp_filters[1] = vlc_object_create( p_aout, sizeof(aout_filter_t) );
101 if ( pp_filters[1] == NULL )
103 vlc_object_detach_all( pp_filters[0] );
104 vlc_object_destroy( pp_filters[0] );
107 vlc_object_attach( pp_filters[1], p_aout );
109 memcpy( &pp_filters[1]->input, &pp_filters[0]->output,
110 sizeof(audio_sample_format_t) );
111 memcpy( &pp_filters[1]->output, p_output_format,
112 sizeof(audio_sample_format_t) );
113 pp_filters[1]->p_module = module_Need( pp_filters[1], "audio filter",
115 if ( pp_filters[1]->p_module == NULL )
118 "couldn't find a filter for the 2nd part of the conversion" );
119 vlc_object_detach_all( pp_filters[0] );
120 vlc_object_destroy( pp_filters[0] );
121 vlc_object_detach_all( pp_filters[1] );
122 vlc_object_destroy( pp_filters[1] );
126 msg_Dbg( p_aout, "filter pipeline made of two filters" );
132 /*****************************************************************************
133 * aout_FiltersDestroyPipeline: deallocate a filters pipeline
134 *****************************************************************************/
135 void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
136 aout_filter_t ** pp_filters,
141 for ( i = 0; i < i_nb_filters; i++ )
143 module_Unneed( pp_filters[i], pp_filters[i]->p_module );
144 vlc_object_detach_all( pp_filters[i] );
145 vlc_object_destroy( pp_filters[i] );
149 /*****************************************************************************
150 * aout_FiltersHintBuffers: fill in aout_alloc_t structures to optimize
152 *****************************************************************************/
153 void aout_FiltersHintBuffers( aout_instance_t * p_aout,
154 aout_filter_t ** pp_filters,
155 int i_nb_filters, aout_alloc_t * p_first_alloc )
159 for ( i = i_nb_filters - 1; i >= 0; i-- )
161 aout_filter_t * p_filter = pp_filters[i];
163 int i_output_size = aout_FormatToBytes( &p_filter->output )
164 * p_filter->output.i_rate;
165 int i_input_size = aout_FormatToBytes( &p_filter->input )
166 * p_filter->input.i_rate;
168 p_first_alloc->i_bytes_per_sec = __MAX( p_first_alloc->i_bytes_per_sec,
171 if ( p_filter->b_in_place )
173 p_first_alloc->i_bytes_per_sec = __MAX(
174 p_first_alloc->i_bytes_per_sec,
179 /* We're gonna need a buffer allocation. */
180 memcpy( &p_filter->output_alloc, p_first_alloc,
181 sizeof(aout_alloc_t) );
182 p_first_alloc->i_alloc_type = AOUT_ALLOC_STACK;
183 p_first_alloc->i_bytes_per_sec = i_input_size;
188 /*****************************************************************************
189 * aout_FiltersPlay: play a buffer
190 *****************************************************************************/
191 void aout_FiltersPlay( aout_instance_t * p_aout,
192 aout_filter_t ** pp_filters,
193 int i_nb_filters, aout_buffer_t ** pp_input_buffer )
197 for ( i = 0; i < i_nb_filters; i++ )
199 aout_filter_t * p_filter = pp_filters[i];
200 aout_buffer_t * p_output_buffer;
202 aout_BufferAlloc( &p_filter->output_alloc,
203 (u64)((*pp_input_buffer)->i_nb_samples * 1000000)
204 / p_filter->output.i_rate, *pp_input_buffer,
206 if ( p_output_buffer == NULL )
208 msg_Err( p_aout, "out of memory" );
211 /* Please note that p_output_buffer->i_nb_samples shall be set by
212 * the filter plug-in. */
214 p_filter->pf_do_work( p_aout, p_filter, *pp_input_buffer,
217 if ( !p_filter->b_in_place )
219 aout_BufferFree( *pp_input_buffer );
220 *pp_input_buffer = p_output_buffer;