]> git.sesse.net Git - vlc/blob - include/aout_internal.h
a36733210dcaf73765cf475bf4232c8bb48d592a
[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.3 2002/08/12 22:12:50 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; /* -1 if only the alloc_type is
31                                               * relevant. */
32 } aout_alloc_t;
33
34 #define AOUT_ALLOC_NONE     0
35 #define AOUT_ALLOC_STACK    1
36 #define AOUT_ALLOC_HEAP     2
37
38 #define aout_BufferAlloc( p_alloc, i_nb_usec, p_previous_buffer, 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         if ( (p_alloc)->i_alloc_type == AOUT_ALLOC_STACK )                  \
46         {                                                                   \
47             (p_new_buffer) = alloca( (u64)(p_alloc)->i_bytes_per_sec        \
48                                  * (i_nb_usec)                              \
49                                  / 1000000 + 1 + sizeof(aout_buffer_t) );   \
50         }                                                                   \
51         else                                                                \
52         {                                                                   \
53             (p_new_buffer) = malloc( (u64)(p_alloc)->i_bytes_per_sec        \
54                                  * (i_nb_usec)                              \
55                                  / 1000000 + 1 + sizeof(aout_buffer_t) );   \
56         }                                                                   \
57         if ( p_new_buffer != NULL )                                         \
58         {                                                                   \
59             (p_new_buffer)->i_alloc_type = (p_alloc)->i_alloc_type;         \
60             (p_new_buffer)->i_size = (u64)(p_alloc)->i_bytes_per_sec        \
61                                             * (i_nb_usec) / 1000000 + 1;    \
62             (p_new_buffer)->p_buffer = (byte_t *)(p_new_buffer)             \
63                                          + sizeof(aout_buffer_t);           \
64             if ( (p_previous_buffer) != NULL )                              \
65             {                                                               \
66                 (p_new_buffer)->start_date =                                \
67                            ((aout_buffer_t *)p_previous_buffer)->start_date;\
68                 (p_new_buffer)->end_date =                                  \
69                            ((aout_buffer_t *)p_previous_buffer)->end_date;  \
70             }                                                               \
71         }                                                                   \
72         /* we'll keep that for a while --Meuuh */                           \
73         /* else printf("%s:%d\n", __FILE__, __LINE__); */                   \
74     }
75
76 #define aout_BufferFree( p_buffer )                                         \
77     if ( (p_buffer)->i_alloc_type == AOUT_ALLOC_HEAP )                      \
78     {                                                                       \
79         free( p_buffer );                                                   \
80     }
81
82 /*****************************************************************************
83  * aout_fifo_t : audio output buffer FIFO
84  *****************************************************************************/
85 typedef struct aout_fifo_t
86 {
87     vlc_mutex_t             lock;
88     struct aout_buffer_t *  p_first;
89     struct aout_buffer_t ** pp_last;
90 } aout_fifo_t;
91
92 static inline void aout_FifoInit( struct aout_instance_t * p_aout,
93                                   aout_fifo_t * p_fifo )
94 {
95     vlc_mutex_init( (vlc_object_t *)p_aout, &p_fifo->lock );
96     p_fifo->p_first = NULL;
97     p_fifo->pp_last = &p_fifo->p_first;
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     vlc_mutex_unlock( &p_fifo->lock );
109 }
110
111 /* This function supposes there is one buffer in p_fifo. */
112 static inline aout_buffer_t * aout_FifoPop( struct aout_instance_t * p_aout,
113                                             aout_fifo_t * p_fifo )
114 {
115     aout_buffer_t * p_buffer;
116     vlc_mutex_lock( &p_fifo->lock );
117     p_buffer = p_fifo->p_first;
118     p_fifo->p_first = p_buffer->p_next;
119     if ( p_fifo->p_first == NULL )
120     {
121         p_fifo->pp_last = &p_fifo->p_first;
122     }
123     vlc_mutex_unlock( &p_fifo->lock );
124
125     return p_buffer;
126 }
127
128 static inline void aout_FifoDestroy( struct aout_instance_t * p_aout,
129                                      aout_fifo_t * p_fifo )
130 {
131     aout_buffer_t * p_buffer;
132
133     vlc_mutex_destroy( &p_fifo->lock );
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 }
142
143 /*****************************************************************************
144  * aout_filter_t : audio output filter
145  *****************************************************************************/
146 typedef struct aout_filter_t
147 {
148     VLC_COMMON_MEMBERS
149
150     audio_sample_format_t   input;
151     audio_sample_format_t   output;
152     aout_alloc_t            output_alloc;
153
154     module_t *              p_module;
155     struct aout_filter_sys_t * p_sys;
156     void                 (* pf_do_work)( struct aout_instance_t *,
157                                          struct aout_filter_t *,
158                                          struct aout_buffer_t *,
159                                          struct aout_buffer_t * );
160     vlc_bool_t              b_in_place;
161 } aout_filter_t;
162
163 /*****************************************************************************
164  * aout_mixer_t : audio output mixer
165  *****************************************************************************/
166 typedef struct aout_mixer_t
167 {
168     audio_sample_format_t   input;
169     audio_sample_format_t   output;
170     aout_alloc_t            output_alloc;
171
172     module_t *              p_module;
173     struct aout_mixer_sys_t * p_sys;
174     void                 (* pf_do_work)( struct aout_instance_t *,
175                                          struct aout_buffer_t * );
176 } aout_mixer_t;
177
178 /*****************************************************************************
179  * aout_input_t : input stream for the audio output
180  *****************************************************************************/
181 struct aout_input_t
182 {
183     audio_sample_format_t   input;
184     aout_alloc_t            input_alloc;
185
186     /* pre-filters */
187     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
188     int                     i_nb_filters;
189
190     aout_fifo_t             fifo;
191
192     mtime_t                 next_packet_date;
193     byte_t *                p_first_byte_to_mix;
194 };
195
196 /*****************************************************************************
197  * aout_output_t : output stream for the audio output
198  *****************************************************************************/
199 typedef struct aout_output_t
200 {
201     audio_sample_format_t   output;
202
203     /* post-filters */
204     aout_filter_t *         pp_filters[AOUT_MAX_FILTERS];
205     int                     i_nb_filters;
206
207     aout_fifo_t             fifo;
208     mtime_t                 last_date;
209
210     struct module_t *       p_module;
211     struct aout_sys_t *     p_sys;
212     int                  (* pf_setformat)( aout_instance_t * );
213     void                 (* pf_play)( aout_instance_t *, aout_buffer_t * );
214     int                     i_nb_samples;
215 } aout_output_t;
216
217 /*****************************************************************************
218  * aout_instance_t : audio output thread descriptor
219  *****************************************************************************/
220 struct aout_instance_t
221 {
222     VLC_COMMON_MEMBERS
223
224     /* Input streams & pre-filters */
225     vlc_mutex_t             input_lock;
226     vlc_cond_t              input_signal;
227     int                     i_inputs_active;
228     vlc_bool_t              b_change_requested;
229     aout_input_t *          pp_inputs[AOUT_MAX_INPUTS];
230     int                     i_nb_inputs;
231
232     /* Mixer */
233     vlc_mutex_t             mixer_lock;
234     vlc_cond_t              mixer_signal;
235     vlc_bool_t              b_mixer_active;
236     aout_mixer_t            mixer;
237
238     /* Output plug-in */
239     aout_output_t           output;
240 };
241
242 /*****************************************************************************
243  * Prototypes
244  *****************************************************************************/
245 void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
246                      aout_buffer_t * p_buffer );
247
248 int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
249                                 aout_filter_t ** pp_filters,
250                                 int * pi_nb_filters,
251                                 audio_sample_format_t * p_input_format,
252                                 audio_sample_format_t * p_output_format );
253 void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
254                                   aout_filter_t ** pp_filters,
255                                   int i_nb_filters );
256 void aout_FiltersHintBuffers( aout_instance_t * p_aout,
257                               aout_filter_t ** pp_filters,
258                               int i_nb_filters, aout_alloc_t * p_first_alloc );
259 void aout_FiltersPlay( aout_instance_t * p_aout,
260                        aout_filter_t ** pp_filters,
261                        int i_nb_filters, aout_buffer_t ** pp_input_buffer );
262
263 int aout_MixerNew( aout_instance_t * p_aout );
264 void aout_MixerDelete( aout_instance_t * p_aout );
265 void aout_MixerRun( aout_instance_t * p_aout );
266
267 int aout_OutputNew( aout_instance_t * p_aout,
268                     audio_sample_format_t * p_format );
269 void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer );
270 void aout_OutputDelete( aout_instance_t * p_aout );
271