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