]> git.sesse.net Git - vlc/blob - include/aout_internal.h
4d247cafd5681278d1b48620f44261d648327778
[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.6 2002/08/19 21:31:11 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     vlc_mutex_t             lock;
86     struct aout_buffer_t *  p_first;
87     struct aout_buffer_t ** pp_last;
88     mtime_t                 end_date;
89 } aout_fifo_t;
90
91 static inline void aout_FifoInit( struct aout_instance_t * p_aout,
92                                   aout_fifo_t * p_fifo )
93 {
94     vlc_mutex_init( (vlc_object_t *)p_aout, &p_fifo->lock );
95     p_fifo->p_first = NULL;
96     p_fifo->pp_last = &p_fifo->p_first;
97     p_fifo->end_date = 0;
98 }
99
100 static inline void aout_FifoPush( struct aout_instance_t * p_aout,
101                                   aout_fifo_t * p_fifo,
102                                   aout_buffer_t * p_buffer )
103 {
104     vlc_mutex_lock( &p_fifo->lock );
105     *p_fifo->pp_last = p_buffer;
106     p_fifo->pp_last = &p_buffer->p_next;
107     *p_fifo->pp_last = NULL;
108     /* Enforce continuity of the stream. */
109     if ( p_fifo->end_date )
110     {
111         mtime_t duration = p_buffer->end_date - p_buffer->start_date;
112
113         p_buffer->start_date = p_fifo->end_date;
114         p_buffer->end_date = p_fifo->end_date =
115                              p_buffer->start_date + duration;
116     }
117     else
118     {
119         p_fifo->end_date = p_buffer->end_date;
120     }
121     vlc_mutex_unlock( &p_fifo->lock );
122 }
123
124 static inline mtime_t aout_FifoNextStart( struct aout_instance_t * p_aout,
125                                           aout_fifo_t * p_fifo )
126 {
127     mtime_t end_date;
128     vlc_mutex_lock( &p_fifo->lock );
129     end_date = p_fifo->end_date;
130     vlc_mutex_unlock( &p_fifo->lock );
131     return end_date;
132 }
133
134 /* Reinit the end_date (for instance after a pause). */
135 static inline void aout_FifoSet( struct aout_instance_t * p_aout,
136                                  aout_fifo_t * p_fifo, mtime_t date )
137 {
138     vlc_mutex_lock( &p_fifo->lock );
139     p_fifo->end_date = date;
140     vlc_mutex_unlock( &p_fifo->lock );
141 }
142
143 /* This function supposes there is at least one buffer in p_fifo. */
144 static inline aout_buffer_t * aout_FifoPop( struct aout_instance_t * p_aout,
145                                             aout_fifo_t * p_fifo )
146 {
147     aout_buffer_t * p_buffer;
148     vlc_mutex_lock( &p_fifo->lock );
149     p_buffer = p_fifo->p_first;
150     p_fifo->p_first = p_buffer->p_next;
151     if ( p_fifo->p_first == NULL )
152     {
153         p_fifo->pp_last = &p_fifo->p_first;
154     }
155     vlc_mutex_unlock( &p_fifo->lock );
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     vlc_mutex_destroy( &p_fifo->lock );
166     p_buffer = p_fifo->p_first;
167     while ( p_buffer != NULL )
168     {
169         aout_buffer_t * p_next = p_buffer->p_next;
170         aout_BufferFree( p_buffer );
171         p_buffer = p_next;
172     }
173 }
174
175 /*****************************************************************************
176  * aout_filter_t : audio output filter
177  *****************************************************************************/
178 typedef struct aout_filter_t
179 {
180     VLC_COMMON_MEMBERS
181
182     audio_sample_format_t   input;
183     audio_sample_format_t   output;
184     aout_alloc_t            output_alloc;
185
186     module_t *              p_module;
187     struct aout_filter_sys_t * p_sys;
188     void                 (* pf_do_work)( struct aout_instance_t *,
189                                          struct aout_filter_t *,
190                                          struct aout_buffer_t *,
191                                          struct aout_buffer_t * );
192     vlc_bool_t              b_in_place;
193 } aout_filter_t;
194
195 /*****************************************************************************
196  * aout_mixer_t : audio output mixer
197  *****************************************************************************/
198 typedef struct aout_mixer_t
199 {
200     audio_sample_format_t   mixer;
201     aout_alloc_t            output_alloc;
202
203     module_t *              p_module;
204     struct aout_mixer_sys_t * p_sys;
205     void                 (* pf_do_work)( struct aout_instance_t *,
206                                          struct aout_buffer_t * );
207 } aout_mixer_t;
208
209 /*****************************************************************************
210  * aout_input_t : input stream for the audio output
211  *****************************************************************************/
212 struct aout_input_t
213 {
214     audio_sample_format_t   input;
215     aout_alloc_t            input_alloc;
216
217     /* pre-filters */
218     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
219     int                     i_nb_filters;
220
221     aout_fifo_t             fifo;
222
223     /* Mixer information */
224     byte_t *                p_first_byte_to_mix;
225 };
226
227 /*****************************************************************************
228  * aout_output_t : output stream for the audio output
229  *****************************************************************************/
230 typedef struct aout_output_t
231 {
232     audio_sample_format_t   output;
233
234     /* post-filters */
235     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
236     int                     i_nb_filters;
237
238     aout_fifo_t             fifo;
239
240     struct module_t *       p_module;
241     struct aout_sys_t *     p_sys;
242     int                  (* pf_setformat)( aout_instance_t * );
243     void                 (* pf_play)( aout_instance_t * );
244     int                     i_nb_samples;
245 } aout_output_t;
246
247 /*****************************************************************************
248  * aout_instance_t : audio output thread descriptor
249  *****************************************************************************/
250 struct aout_instance_t
251 {
252     VLC_COMMON_MEMBERS
253
254     /* Input streams & pre-filters */
255     vlc_mutex_t             input_lock;
256     vlc_cond_t              input_signal;
257     int                     i_inputs_active;
258     vlc_bool_t              b_change_requested;
259     aout_input_t *          pp_inputs[AOUT_MAX_INPUTS];
260     int                     i_nb_inputs;
261
262     /* Mixer */
263     vlc_cond_t              mixer_signal; /* the associated mutex is
264                                            * p_aout->output.fifo.lock */
265     vlc_bool_t              b_mixer_active;
266     aout_mixer_t            mixer;
267
268     /* Output plug-in */
269     aout_output_t           output;
270 };
271
272 /*****************************************************************************
273  * Prototypes
274  *****************************************************************************/
275 void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
276                      aout_buffer_t * p_buffer );
277
278 int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
279                                 aout_filter_t ** pp_filters,
280                                 int * pi_nb_filters,
281                                 const audio_sample_format_t * p_input_format,
282                                 const audio_sample_format_t * p_output_format );
283 void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
284                                   aout_filter_t ** pp_filters,
285                                   int i_nb_filters );
286 void aout_FiltersHintBuffers( aout_instance_t * p_aout,
287                               aout_filter_t ** pp_filters,
288                               int i_nb_filters, aout_alloc_t * p_first_alloc );
289 void aout_FiltersPlay( aout_instance_t * p_aout,
290                        aout_filter_t ** pp_filters,
291                        int i_nb_filters, aout_buffer_t ** pp_input_buffer );
292
293 int aout_MixerNew( aout_instance_t * p_aout );
294 void aout_MixerDelete( aout_instance_t * p_aout );
295 void aout_MixerRun( aout_instance_t * p_aout );
296
297 int aout_OutputNew( aout_instance_t * p_aout,
298                     audio_sample_format_t * p_format );
299 void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer );
300 void aout_OutputDelete( aout_instance_t * p_aout );
301 VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
302