]> git.sesse.net Git - vlc/blob - include/aout_internal.h
a6c93ecd2d411b39efcc3c67de4a772ef59d8993
[vlc] / include / aout_internal.h
1 /*****************************************************************************
2  * aout_internal.h : internal defines for audio output
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: aout_internal.h,v 1.7 2002/08/19 23:12:57 massiot Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * aout_alloc_t : allocation of memory in the audio output
26  *****************************************************************************/
27 typedef struct aout_alloc_t
28 {
29     int                     i_alloc_type;
30     int                     i_bytes_per_sec;
31 } aout_alloc_t;
32
33 #define AOUT_ALLOC_NONE     0
34 #define AOUT_ALLOC_STACK    1
35 #define AOUT_ALLOC_HEAP     2
36
37 #define aout_BufferAlloc( p_alloc, i_nb_usec, p_previous_buffer,            \
38                           p_new_buffer )                                    \
39     if ( (p_alloc)->i_alloc_type == AOUT_ALLOC_NONE )                       \
40     {                                                                       \
41         (p_new_buffer) = p_previous_buffer;                                 \
42     }                                                                       \
43     else                                                                    \
44     {                                                                       \
45         int i_alloc_size;                                                   \
46         i_alloc_size = (u64)(p_alloc)->i_bytes_per_sec                      \
47                                             * (i_nb_usec) / 1000000 + 1;    \
48         if ( (p_alloc)->i_alloc_type == AOUT_ALLOC_STACK )                  \
49         {                                                                   \
50             (p_new_buffer) = alloca( i_alloc_size + sizeof(aout_buffer_t) );\
51         }                                                                   \
52         else                                                                \
53         {                                                                   \
54             (p_new_buffer) = malloc( i_alloc_size + sizeof(aout_buffer_t) );\
55         }                                                                   \
56         if ( p_new_buffer != NULL )                                         \
57         {                                                                   \
58             (p_new_buffer)->i_alloc_type = (p_alloc)->i_alloc_type;         \
59             (p_new_buffer)->i_size = i_alloc_size;                          \
60             (p_new_buffer)->p_buffer = (byte_t *)(p_new_buffer)             \
61                                          + sizeof(aout_buffer_t);           \
62             if ( (p_previous_buffer) != NULL )                              \
63             {                                                               \
64                 (p_new_buffer)->start_date =                                \
65                            ((aout_buffer_t *)p_previous_buffer)->start_date;\
66                 (p_new_buffer)->end_date =                                  \
67                            ((aout_buffer_t *)p_previous_buffer)->end_date;  \
68             }                                                               \
69         }                                                                   \
70         /* we'll keep that for a while --Meuuh */                           \
71         /* else printf("%s:%d\n", __FILE__, __LINE__); */                   \
72     }
73
74 #define aout_BufferFree( p_buffer )                                         \
75     if ( (p_buffer)->i_alloc_type == AOUT_ALLOC_HEAP )                      \
76     {                                                                       \
77         free( p_buffer );                                                   \
78     }
79
80 /*****************************************************************************
81  * aout_fifo_t : audio output buffer FIFO
82  *****************************************************************************/
83 typedef struct aout_fifo_t
84 {
85     struct aout_buffer_t *  p_first;
86     struct aout_buffer_t ** pp_last;
87     mtime_t                 end_date;
88 } aout_fifo_t;
89
90 static inline void aout_FifoInit( struct aout_instance_t * p_aout,
91                                   aout_fifo_t * p_fifo )
92 {
93     p_fifo->p_first = NULL;
94     p_fifo->pp_last = &p_fifo->p_first;
95     p_fifo->end_date = 0;
96 }
97
98 static inline void aout_FifoPush( struct aout_instance_t * p_aout,
99                                   aout_fifo_t * p_fifo,
100                                   aout_buffer_t * p_buffer )
101 {
102     *p_fifo->pp_last = p_buffer;
103     p_fifo->pp_last = &p_buffer->p_next;
104     *p_fifo->pp_last = NULL;
105     /* Enforce continuity of the stream. */
106     if ( p_fifo->end_date )
107     {
108         mtime_t duration = p_buffer->end_date - p_buffer->start_date;
109
110         p_buffer->start_date = p_fifo->end_date;
111         p_buffer->end_date = p_fifo->end_date =
112                              p_buffer->start_date + duration;
113     }
114     else
115     {
116         p_fifo->end_date = p_buffer->end_date;
117     }
118 }
119
120 static inline mtime_t aout_FifoNextStart( struct aout_instance_t * p_aout,
121                                           aout_fifo_t * p_fifo )
122 {
123     return p_fifo->end_date;
124 }
125
126 /* Reinit the end_date (for instance after a pause). */
127 static inline void aout_FifoSet( struct aout_instance_t * p_aout,
128                                  aout_fifo_t * p_fifo, mtime_t date )
129 {
130     aout_buffer_t * p_buffer;
131     p_fifo->end_date = date;
132
133     /* Remove all buffers. */
134     p_buffer = p_fifo->p_first;
135     while ( p_buffer != NULL )
136     {
137         aout_buffer_t * p_next = p_buffer->p_next;
138         aout_BufferFree( p_buffer );
139         p_buffer = p_next;
140     }
141     p_fifo->p_first = NULL;
142     p_fifo->pp_last = &p_fifo->p_first;
143 }
144
145 /* This function supposes there is at least one buffer in p_fifo. */
146 static inline aout_buffer_t * aout_FifoPop( struct aout_instance_t * p_aout,
147                                             aout_fifo_t * p_fifo )
148 {
149     aout_buffer_t * p_buffer;
150     p_buffer = p_fifo->p_first;
151     p_fifo->p_first = p_buffer->p_next;
152     if ( p_fifo->p_first == NULL )
153     {
154         p_fifo->pp_last = &p_fifo->p_first;
155     }
156
157     return p_buffer;
158 }
159
160 static inline void aout_FifoDestroy( struct aout_instance_t * p_aout,
161                                      aout_fifo_t * p_fifo )
162 {
163     aout_buffer_t * p_buffer;
164
165     p_buffer = p_fifo->p_first;
166     while ( p_buffer != NULL )
167     {
168         aout_buffer_t * p_next = p_buffer->p_next;
169         aout_BufferFree( p_buffer );
170         p_buffer = p_next;
171     }
172 }
173
174 /*****************************************************************************
175  * aout_filter_t : audio output filter
176  *****************************************************************************/
177 typedef struct aout_filter_t
178 {
179     VLC_COMMON_MEMBERS
180
181     audio_sample_format_t   input;
182     audio_sample_format_t   output;
183     aout_alloc_t            output_alloc;
184
185     module_t *              p_module;
186     struct aout_filter_sys_t * p_sys;
187     void                 (* pf_do_work)( struct aout_instance_t *,
188                                          struct aout_filter_t *,
189                                          struct aout_buffer_t *,
190                                          struct aout_buffer_t * );
191     vlc_bool_t              b_in_place;
192 } aout_filter_t;
193
194 /*****************************************************************************
195  * aout_mixer_t : audio output mixer
196  *****************************************************************************/
197 typedef struct aout_mixer_t
198 {
199     audio_sample_format_t   mixer;
200     aout_alloc_t            output_alloc;
201
202     module_t *              p_module;
203     struct aout_mixer_sys_t * p_sys;
204     void                 (* pf_do_work)( struct aout_instance_t *,
205                                          struct aout_buffer_t * );
206 } aout_mixer_t;
207
208 /*****************************************************************************
209  * aout_input_t : input stream for the audio output
210  *****************************************************************************/
211 struct aout_input_t
212 {
213     audio_sample_format_t   input;
214     aout_alloc_t            input_alloc;
215
216     /* pre-filters */
217     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
218     int                     i_nb_filters;
219
220     aout_fifo_t             fifo;
221
222     /* Mixer information */
223     byte_t *                p_first_byte_to_mix;
224 };
225
226 /*****************************************************************************
227  * aout_output_t : output stream for the audio output
228  *****************************************************************************/
229 typedef struct aout_output_t
230 {
231     audio_sample_format_t   output;
232
233     /* post-filters */
234     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
235     int                     i_nb_filters;
236
237     aout_fifo_t             fifo;
238
239     struct module_t *       p_module;
240     struct aout_sys_t *     p_sys;
241     int                  (* pf_setformat)( aout_instance_t * );
242     void                 (* pf_play)( aout_instance_t * );
243     int                     i_nb_samples;
244 } aout_output_t;
245
246 /*****************************************************************************
247  * aout_instance_t : audio output thread descriptor
248  *****************************************************************************/
249 struct aout_instance_t
250 {
251     VLC_COMMON_MEMBERS
252
253     /* Input streams & pre-filters */
254     vlc_mutex_t             input_lock;
255     vlc_cond_t              input_signal;
256     int                     i_inputs_active;
257     vlc_bool_t              b_change_requested;
258     aout_input_t *          pp_inputs[AOUT_MAX_INPUTS];
259     int                     i_nb_inputs;
260
261     /* Mixer */
262     vlc_mutex_t             mixer_lock;
263     aout_mixer_t            mixer;
264
265     /* Output plug-in */
266     aout_output_t           output;
267 };
268
269 /*****************************************************************************
270  * Prototypes
271  *****************************************************************************/
272 void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
273                      aout_buffer_t * p_buffer );
274
275 int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
276                                 aout_filter_t ** pp_filters,
277                                 int * pi_nb_filters,
278                                 const audio_sample_format_t * p_input_format,
279                                 const audio_sample_format_t * p_output_format );
280 void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
281                                   aout_filter_t ** pp_filters,
282                                   int i_nb_filters );
283 void aout_FiltersHintBuffers( aout_instance_t * p_aout,
284                               aout_filter_t ** pp_filters,
285                               int i_nb_filters, aout_alloc_t * p_first_alloc );
286 void aout_FiltersPlay( aout_instance_t * p_aout,
287                        aout_filter_t ** pp_filters,
288                        int i_nb_filters, aout_buffer_t ** pp_input_buffer );
289
290 int aout_MixerNew( aout_instance_t * p_aout );
291 void aout_MixerDelete( aout_instance_t * p_aout );
292 void aout_MixerRun( aout_instance_t * p_aout );
293
294 int aout_OutputNew( aout_instance_t * p_aout,
295                     audio_sample_format_t * p_format );
296 void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer );
297 void aout_OutputDelete( aout_instance_t * p_aout );
298 VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
299