]> git.sesse.net Git - vlc/blob - src/audio_output/audio_output.c
. no need to add "\n" at the end of intf_*Msg() messages anymore.
[vlc] / src / audio_output / audio_output.c
1 /*****************************************************************************
2  * audio_output.c : audio output thread
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors: Michel Kaempf <maxx@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /* TODO:
24  *
25  * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
26  *   inline
27  * - Faire les optimisations dans les fonctions threads :
28  *   = Stocker les "petits calculs" dans des variables au lieu de les refaire
29  *     à chaque boucle
30  *   = Utiliser des tables pour les gros calculs
31  * - Faire une structure différente pour intf/adec fifo
32  *
33  */
34
35 /*****************************************************************************
36  * Preamble
37  *****************************************************************************/
38 #include "defs.h"
39
40 #include <unistd.h>                                              /* getpid() */
41
42 #include <stdio.h>                                           /* "intf_msg.h" */
43 #include <stdlib.h>                            /* calloc(), malloc(), free() */
44
45 #include "config.h"
46 #include "common.h"
47 #include "threads.h"
48 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
49 #include "plugins.h"
50
51 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
52
53 #include "audio_output.h"
54 #include "main.h"
55
56 /*****************************************************************************
57  * Local prototypes
58  *****************************************************************************/
59
60 static int aout_SpawnThread( aout_thread_t * p_aout );
61
62 /* Creating as much aout_Thread functions as configurations is one solution,
63  * examining the different cases in the Thread loop of an unique function is
64  * another. I chose the first solution. */
65 void aout_Thread_S8_Mono        ( aout_thread_t * p_aout );
66 void aout_Thread_U8_Mono        ( aout_thread_t * p_aout );
67 void aout_Thread_S16_Mono       ( aout_thread_t * p_aout );
68 void aout_Thread_U16_Mono       ( aout_thread_t * p_aout );
69 void aout_Thread_S8_Stereo      ( aout_thread_t * p_aout );
70 void aout_Thread_U8_Stereo      ( aout_thread_t * p_aout );
71 void aout_Thread_S16_Stereo     ( aout_thread_t * p_aout );
72 void aout_Thread_U16_Stereo     ( aout_thread_t * p_aout );
73
74 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
75 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
76
77 /*****************************************************************************
78  * InitializeIncrement
79  *****************************************************************************/
80 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
81 {
82     p_increment->l_remainder = -l_denominator;
83
84     p_increment->l_euclidean_integer = 0;
85     while ( l_numerator >= l_denominator )
86     {
87         p_increment->l_euclidean_integer++;
88         l_numerator -= l_denominator;
89     }
90
91     p_increment->l_euclidean_remainder = l_numerator;
92
93     p_increment->l_euclidean_denominator = l_denominator;
94 }
95
96 /*****************************************************************************
97  * aout_CreateThread: initialize audio thread
98  *****************************************************************************/
99 aout_thread_t *aout_CreateThread( int *pi_status )
100 {
101     aout_thread_t * p_aout;                             /* thread descriptor */
102     typedef void    ( aout_getplugin_t ) ( aout_thread_t * p_aout );
103     int             i_index;
104     int             i_best_index = 0, i_best_score = 0;
105 #if 0
106     int             i_status;                               /* thread status */
107 #endif
108
109     /* Allocate descriptor */
110     p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
111     if( p_aout == NULL )
112     {
113         return( NULL );
114     }
115
116     /* Get a suitable audio plugin */
117     for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
118     {
119         /* If there's a plugin in p_info ... */
120         if( p_main->p_bank->p_info[ i_index ] != NULL )
121         {
122             /* ... and if this plugin provides the functions we want ... */
123             if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
124             {
125                 /* ... and if this plugin has a good score ... */
126                 if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
127                 {
128                     /* ... then take it */
129                     i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
130                     i_best_index = i_index;
131                 }
132             }
133         }
134     }
135
136     if( i_best_score == 0 )
137     {
138         free( p_aout );
139         return( NULL );
140     }
141
142     /* Get the plugin functions */
143     ( (aout_getplugin_t *)
144       p_main->p_bank->p_info[ i_best_index ]->aout_GetPlugin )( p_aout );
145
146     /*
147      * Initialize audio device
148      */
149     if ( p_aout->p_sys_open( p_aout ) )
150     {
151         free( p_aout );
152         return( NULL );
153     }
154
155     p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
156                                                    for i_channels == 1 or 2 ??*/
157
158     if ( p_aout->p_sys_reset( p_aout ) )
159     {
160         p_aout->p_sys_close( p_aout );
161         free( p_aout );
162         return( NULL );
163     }
164     if ( p_aout->p_sys_setformat( p_aout ) )
165     {
166         p_aout->p_sys_close( p_aout );
167         free( p_aout );
168         return( NULL );
169     }
170     if ( p_aout->p_sys_setchannels( p_aout ) )
171     {
172         p_aout->p_sys_close( p_aout );
173         free( p_aout );
174         return( NULL );
175     }
176     if ( p_aout->p_sys_setrate( p_aout ) )
177     {
178         p_aout->p_sys_close( p_aout );
179         free( p_aout );
180         return( NULL );
181     }
182
183     /* Initialize the volume level */
184     p_aout->vol = VOLUME_DEFAULT;
185     
186     /* FIXME: maybe it would be cleaner to change SpawnThread prototype
187      * see vout to handle status correctly ?? however, it is not critical since
188      * this thread is only called in main and all calls are blocking */
189     if( aout_SpawnThread( p_aout ) )
190     {
191         p_aout->p_sys_close( p_aout );
192         free( p_aout );
193         return( NULL );
194     }
195
196     return( p_aout );
197 }
198
199 /*****************************************************************************
200  * aout_SpawnThread
201  *****************************************************************************/
202 static int aout_SpawnThread( aout_thread_t * p_aout )
203 {
204     int             i_fifo;
205     long            l_bytes;
206     void *          aout_thread = NULL;
207
208     intf_DbgMsg("aout debug: spawning audio output thread (%p)", p_aout);
209
210     /* We want the audio output thread to live */
211     p_aout->b_die = 0;
212     p_aout->b_active = 1;
213
214     /* Initialize the fifos lock */
215     vlc_mutex_init( &p_aout->fifos_lock );
216     /* Initialize audio fifos : set all fifos as empty and initialize locks */
217     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
218     {
219         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
220         vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
221         vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
222     }
223
224     /* Compute the size (in audio units) of the audio output buffer. Although
225      * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
226      * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
227     p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
228     p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
229
230     /* Make aout_thread point to the right thread function, and compute the
231      * byte size of the audio output buffer */
232     switch ( p_aout->i_channels )
233     {
234         /* Audio output is mono */
235         case 1:
236             switch ( p_aout->i_format )
237             {
238                 case AOUT_FMT_U8:
239                     l_bytes = 1 * sizeof(u8) * p_aout->l_units;
240                     aout_thread = (void *)aout_Thread_U8_Mono;
241                     break;
242
243                 case AOUT_FMT_S8:
244                     l_bytes = 1 * sizeof(s8) * p_aout->l_units;
245                     aout_thread = (void *)aout_Thread_S8_Mono;
246                     break;
247
248                 case AOUT_FMT_U16_LE:
249                 case AOUT_FMT_U16_BE:
250                     l_bytes = 1 * sizeof(u16) * p_aout->l_units;
251                     aout_thread = (void *)aout_Thread_U16_Mono;
252                     break;
253
254                 case AOUT_FMT_S16_LE:
255                 case AOUT_FMT_S16_BE:
256                     l_bytes = 1 * sizeof(s16) * p_aout->l_units;
257                     aout_thread = (void *)aout_Thread_S16_Mono;
258                     break;
259
260                 default:
261                     intf_ErrMsg( "aout error: unknown audio output format (%i)",
262                                  p_aout->i_format );
263                     return( -1 );
264             }
265             break;
266
267         /* Audio output is stereo */
268         case 2:
269             switch ( p_aout->i_format )
270             {
271                 case AOUT_FMT_U8:
272                     l_bytes = 2 * sizeof(u8) * p_aout->l_units;
273                     aout_thread = (void *)aout_Thread_U8_Stereo;
274                     break;
275
276                 case AOUT_FMT_S8:
277                     l_bytes = 2 * sizeof(s8) * p_aout->l_units;
278                     aout_thread = (void *)aout_Thread_S8_Stereo;
279                     break;
280
281                 case AOUT_FMT_U16_LE:
282                 case AOUT_FMT_U16_BE:
283                     l_bytes = 2 * sizeof(u16) * p_aout->l_units;
284                     aout_thread = (void *)aout_Thread_U16_Stereo;
285                     break;
286
287                 case AOUT_FMT_S16_LE:
288                 case AOUT_FMT_S16_BE:
289                     l_bytes = 2 * sizeof(s16) * p_aout->l_units;
290                     aout_thread = (void *)aout_Thread_S16_Stereo;
291                     break;
292
293                 default:
294                     intf_ErrMsg("aout error: unknown audio output format (%i)",
295                         p_aout->i_format);
296                     return( -1 );
297             }
298             break;
299
300         default:
301             intf_ErrMsg("aout error: unknown number of audio channels (%i)",
302                 p_aout->i_channels );
303             return( -1 );
304     }
305
306     /* Allocate the memory needed by the audio output buffers, and set to zero
307      * the s32 buffer's memory */
308     if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
309     {
310         intf_ErrMsg("aout error: not enough memory to create the output buffer");
311         return( -1 );
312     }
313     if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
314     {
315         intf_ErrMsg("aout error: not enough memory to create the s32 output buffer");
316         free( p_aout->buffer );
317         return( -1 );
318     }
319
320     /* Before launching the thread, we try to predict the date of the first
321      * audio unit in the first output buffer */
322     p_aout->date = mdate() - 1000000;
323
324     /* Launch the thread */
325     if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
326     {
327         intf_ErrMsg("aout error: can't spawn audio output thread (%p)", p_aout);
328         free( p_aout->buffer );
329         free( p_aout->s32_buffer );
330         return( -1 );
331     }
332
333     intf_DbgMsg("aout debug: audio output thread (%p) spawned", p_aout);
334     return( 0 );
335 }
336
337 /*****************************************************************************
338  * aout_DestroyThread
339  *****************************************************************************/
340 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
341 {
342     /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
343
344     intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)", p_aout);
345
346     /* Ask thread to kill itself and wait until it's done */
347     p_aout->b_die = 1;
348     vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
349
350     /* Free the allocated memory */
351     free( p_aout->buffer );
352     free( p_aout->s32_buffer );
353
354     /* Free the structure */
355     p_aout->p_sys_close( p_aout );
356     intf_DbgMsg("aout debug: audio device (%s) closed", p_aout->psz_device);
357
358     /* Free structure */
359     free( p_aout );
360 }
361
362 /*****************************************************************************
363  * aout_CreateFifo
364  *****************************************************************************/
365 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
366 {
367     int i_fifo;
368
369     /* Take the fifos lock */
370     vlc_mutex_lock( &p_aout->fifos_lock );
371
372     /* Looking for a free fifo structure */
373     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
374     {
375         if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
376         {
377             break;
378         }
379     }
380     if ( i_fifo == AOUT_MAX_FIFOS )
381     {
382         intf_ErrMsg("aout error: no empty fifo available");
383         vlc_mutex_unlock( &p_aout->fifos_lock );
384         return( NULL );
385     }
386
387     /* Initialize the new fifo structure */
388     switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
389     {
390         case AOUT_INTF_MONO_FIFO:
391         case AOUT_INTF_STEREO_FIFO:
392             p_aout->fifo[i_fifo].b_die = 0;
393
394             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
395             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
396             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
397
398             p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
399
400             p_aout->fifo[i_fifo].l_unit = 0;
401             InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
402             p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
403             break;
404
405         case AOUT_ADEC_MONO_FIFO:
406         case AOUT_ADEC_STEREO_FIFO:
407             p_aout->fifo[i_fifo].b_die = 0;
408
409             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
410             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
411             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
412
413             p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
414             /* Allocate the memory needed to store the audio frames. As the
415              * fifo is a rotative fifo, we must be able to find out whether the
416              * fifo is full or empty, that's why we must in fact allocate memory
417              * for (AOUT_FIFO_SIZE+1) audio frames. */
418             if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
419             {
420                 intf_ErrMsg("aout error: not enough memory to create the frames buffer");
421                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
422                 vlc_mutex_unlock( &p_aout->fifos_lock );
423                 return( NULL );
424             }
425
426             /* Allocate the memory needed to store the dates of the frames */
427             if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
428             {
429                 intf_ErrMsg("aout error: not enough memory to create the dates buffer");
430                 free( p_aout->fifo[i_fifo].buffer );
431                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
432                 vlc_mutex_unlock( &p_aout->fifos_lock );
433                 return( NULL );
434             }
435
436             /* Set the fifo's buffer as empty (the first frame that is to be
437              * played is also the first frame that is not to be played) */
438             p_aout->fifo[i_fifo].l_start_frame = 0;
439             /* p_aout->fifo[i_fifo].l_next_frame = 0; */
440             p_aout->fifo[i_fifo].l_end_frame = 0;
441
442             /* Waiting for the audio decoder to compute enough frames to work
443              * out the fifo's current rate (as soon as the decoder has decoded
444              * enough frames, the members of the fifo structure that are not
445              * initialized now will be calculated) */
446             p_aout->fifo[i_fifo].b_start_frame = 0;
447             p_aout->fifo[i_fifo].b_next_frame = 0;
448             break;
449
450         default:
451             intf_ErrMsg("aout error: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
452             p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
453             vlc_mutex_unlock( &p_aout->fifos_lock );
454             return( NULL );
455     }
456
457     /* Release the fifos lock */
458     vlc_mutex_unlock( &p_aout->fifos_lock );
459
460     /* Return the pointer to the fifo structure */
461     intf_DbgMsg("aout debug: audio output fifo (%p) allocated", &p_aout->fifo[i_fifo]);
462     return( &p_aout->fifo[i_fifo] );
463 }
464
465 /*****************************************************************************
466  * aout_DestroyFifo
467  *****************************************************************************/
468 void aout_DestroyFifo( aout_fifo_t * p_fifo )
469 {
470     intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)", p_fifo);
471     p_fifo->b_die = 1;
472 }
473
474 /* Here are the local macros */
475
476 #define UPDATE_INCREMENT( increment, integer ) \
477     if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
478     { \
479         (integer) += (increment).l_euclidean_integer + 1; \
480         (increment).l_remainder -= (increment).l_euclidean_denominator; \
481     } \
482     else \
483     { \
484         (integer) += (increment).l_euclidean_integer; \
485     }
486
487 /* Following functions are local */
488
489 /*****************************************************************************
490  * NextFrame
491  *****************************************************************************/
492 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
493 {
494     long l_units, l_rate;
495
496     /* We take the lock */
497     vlc_mutex_lock( &p_fifo->data_lock );
498
499     /* Are we looking for a dated start frame ? */
500     if ( !p_fifo->b_start_frame )
501     {
502         while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
503         {
504             if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
505             {
506                 p_fifo->b_start_frame = 1;
507                 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
508                 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
509                 break;
510             }
511             p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
512         }
513
514         if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
515         {
516             vlc_mutex_unlock( &p_fifo->data_lock );
517             return( -1 );
518         }
519     }
520
521     /* We are looking for the next dated frame */
522     /* FIXME : is the output fifo full ?? */
523     while ( !p_fifo->b_next_frame )
524     {
525         while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
526         {
527             if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
528             {
529                 p_fifo->b_next_frame = 1;
530                 break;
531             }
532             p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
533         }
534
535         while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
536         {
537             vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
538             if ( p_fifo->b_die )
539             {
540                 vlc_mutex_unlock( &p_fifo->data_lock );
541                 return( -1 );
542             }
543         }
544     }
545
546     l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
547
548     l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
549     intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
550
551     InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
552
553     p_fifo->l_units = (((l_units - (p_fifo->l_unit -
554         (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
555         * p_aout->l_rate) / l_rate) + 1;
556
557     /* We release the lock before leaving */
558     vlc_mutex_unlock( &p_fifo->data_lock );
559     return( 0 );
560 }
561
562 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
563 {
564 }
565
566 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
567 {
568 }
569
570 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
571 {
572     int i_fifo;
573     long l_buffer, l_buffer_limit;
574     long l_units, l_bytes;
575
576     intf_DbgMsg("adec debug: running audio output U8_M_thread (%p) (pid == %i)", p_aout, getpid());
577
578     /* As the s32_buffer was created with calloc(), we don't have to set this
579      * memory to zero and we can immediately jump into the thread's loop */
580     while ( !p_aout->b_die )
581     {
582         vlc_mutex_lock( &p_aout->fifos_lock );
583         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
584         {
585             switch ( p_aout->fifo[i_fifo].i_type )
586             {
587                 case AOUT_EMPTY_FIFO:
588                     break;
589
590                 case AOUT_INTF_MONO_FIFO:
591                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
592                     {
593                         l_buffer = 0;
594                         while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
595                         {
596                             p_aout->s32_buffer[l_buffer++] +=
597                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
598                             p_aout->s32_buffer[l_buffer++] +=
599                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
600                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
601                         }
602                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
603                     }
604                     else
605                     {
606                         l_buffer = 0;
607                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
608                         {
609                             p_aout->s32_buffer[l_buffer++] +=
610                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
611                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
612                         }
613                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
614                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
615                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
616                     }
617                     break;
618
619                 case AOUT_INTF_STEREO_FIFO:
620                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
621                     {
622                         l_buffer = 0;
623                         while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
624                         {
625                             /* I mix half left - half right */
626                             p_aout->s32_buffer[l_buffer++] +=
627                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
628                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
629                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
630                         }
631                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
632                     }
633                     else
634                     {
635                         l_buffer = 0;
636                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
637                         {
638                             /* I mix half left - half right */
639                             p_aout->s32_buffer[l_buffer++] +=
640                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
641                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
642                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
643                         }
644                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
645                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
646                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
647                     }
648                     break;
649
650                 case AOUT_ADEC_MONO_FIFO:
651                     if ( p_aout->fifo[i_fifo].b_die )
652                     {
653                         free( p_aout->fifo[i_fifo].buffer );
654                         free( p_aout->fifo[i_fifo].date );
655                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
656                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
657                         continue;
658                     }
659
660                     l_units = p_aout->l_units;
661                     l_buffer = 0;
662                     while ( l_units > 0 )
663                     {
664                         if ( !p_aout->fifo[i_fifo].b_next_frame )
665                         {
666                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
667                             {
668                                 break;
669                             }
670                         }
671
672                         if ( p_aout->fifo[i_fifo].l_units > l_units )
673                         {
674                             l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
675                             while ( l_buffer < l_buffer_limit )
676                             {
677                                 p_aout->s32_buffer[l_buffer++] +=
678                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
679
680                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
681                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
682                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
683                                 {
684                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
685                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
686                                 }
687                             }
688                             p_aout->fifo[i_fifo].l_units -= l_units;
689                             break;
690                         }
691                         else
692                         {
693                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
694                             /* p_aout->b_stereo == 0 */
695                             while ( l_buffer < l_buffer_limit )
696                             {
697                                 p_aout->s32_buffer[l_buffer++] +=
698                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
699
700                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
701                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
702                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
703                                 {
704                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
705                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
706                                 }
707                             }
708                             l_units -= p_aout->fifo[i_fifo].l_units;
709
710                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
711                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
712                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
713                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
714
715                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
716                             p_aout->fifo[i_fifo].l_next_frame += 1;
717                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
718                             p_aout->fifo[i_fifo].b_next_frame = 0;
719                         }
720                     }
721                     break;
722
723                 case AOUT_ADEC_STEREO_FIFO:
724                     if ( p_aout->fifo[i_fifo].b_die )
725                     {
726                         free( p_aout->fifo[i_fifo].buffer );
727                         free( p_aout->fifo[i_fifo].date );
728                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
729                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
730                         continue;
731                     }
732
733                     l_units = p_aout->l_units;
734                     l_buffer = 0;
735                     while ( l_units > 0 )
736                     {
737                         if ( !p_aout->fifo[i_fifo].b_next_frame )
738                         {
739                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
740                             {
741                                 break;
742                             }
743                         }
744
745                         if ( p_aout->fifo[i_fifo].l_units > l_units )
746                         {
747                             l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
748                             while ( l_buffer < l_buffer_limit )
749                             {
750                                 /* I mix half left - half right */
751                                 p_aout->s32_buffer[l_buffer++] +=
752                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
753                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
754
755                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
756                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
757                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
758                                 {
759                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
760                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
761                                 }
762                             }
763                             p_aout->fifo[i_fifo].l_units -= l_units;
764                             break;
765                         }
766                         else
767                         {
768                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
769                             /* p_aout->b_stereo == 0 */
770                             while ( l_buffer < l_buffer_limit )
771                             {
772                                 /* I mix half left - half right */
773                                 p_aout->s32_buffer[l_buffer++] +=
774                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
775                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
776
777                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
778                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
779                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
780                                 {
781                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
782                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
783                                 }
784                             }
785                             l_units -= p_aout->fifo[i_fifo].l_units;
786
787                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
788                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
789                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
790                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
791
792                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
793                             p_aout->fifo[i_fifo].l_next_frame += 1;
794                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
795                             p_aout->fifo[i_fifo].b_next_frame = 0;
796                         }
797                     }
798                     break;
799
800             default:
801                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
802                     break;
803             }
804         }
805         vlc_mutex_unlock( &p_aout->fifos_lock );
806
807         l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
808
809         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
810         {
811             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
812             p_aout->s32_buffer[l_buffer] = 0;
813         }
814         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
815         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
816         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
817         if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
818         {
819             msleep( p_aout->l_msleep );
820         }
821     }
822
823     vlc_mutex_lock( &p_aout->fifos_lock );
824     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
825     {
826         switch ( p_aout->fifo[i_fifo].i_type )
827         {
828             case AOUT_EMPTY_FIFO:
829                 break;
830
831             case AOUT_INTF_MONO_FIFO:
832             case AOUT_INTF_STEREO_FIFO:
833                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
834                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
835                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
836                 break;
837
838             case AOUT_ADEC_MONO_FIFO:
839             case AOUT_ADEC_STEREO_FIFO:
840                 free( p_aout->fifo[i_fifo].buffer );
841                 free( p_aout->fifo[i_fifo].date );
842                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
843                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
844                 break;
845
846             default:
847                 break;
848         }
849     }
850     vlc_mutex_unlock( &p_aout->fifos_lock );
851
852
853 }
854
855 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
856 {
857     int i_fifo;
858     long l_buffer, l_buffer_limit;
859     long l_units, l_bytes;
860
861     intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
862
863     /* As the s32_buffer was created with calloc(), we don't have to set this
864      * memory to zero and we can immediately jump into the thread's loop */
865     while ( !p_aout->b_die )
866     {
867         vlc_mutex_lock( &p_aout->fifos_lock );
868         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
869         {
870             switch ( p_aout->fifo[i_fifo].i_type )
871             {
872                 case AOUT_EMPTY_FIFO:
873                     break;
874
875                 case AOUT_INTF_MONO_FIFO:
876                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
877                     {
878                         l_buffer = 0;
879                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
880                         {
881                             p_aout->s32_buffer[l_buffer++] +=
882                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
883                             p_aout->s32_buffer[l_buffer++] +=
884                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
885                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
886                         }
887                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
888                     }
889                     else
890                     {
891                         l_buffer = 0;
892                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
893                         {
894                             p_aout->s32_buffer[l_buffer++] +=
895                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
896                             p_aout->s32_buffer[l_buffer++] +=
897                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
898                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
899                         }
900                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
901                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
902                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
903                     }
904                     break;
905
906                 case AOUT_INTF_STEREO_FIFO:
907                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
908                     {
909                         l_buffer = 0;
910                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
911                         {
912                             p_aout->s32_buffer[l_buffer++] +=
913                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
914                             p_aout->s32_buffer[l_buffer++] +=
915                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
916                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
917                         }
918                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
919                     }
920                     else
921                     {
922                         l_buffer = 0;
923                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
924                         {
925                             p_aout->s32_buffer[l_buffer++] +=
926                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
927                             p_aout->s32_buffer[l_buffer++] +=
928                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
929                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
930                         }
931                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
932                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
933                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
934                     }
935                     break;
936
937                 case AOUT_ADEC_MONO_FIFO:
938                     if ( p_aout->fifo[i_fifo].b_die )
939                     {
940                         free( p_aout->fifo[i_fifo].buffer );
941                         free( p_aout->fifo[i_fifo].date );
942                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
943                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
944                         continue;
945                     }
946
947                     l_units = p_aout->l_units;
948                     l_buffer = 0;
949                     while ( l_units > 0 )
950                     {
951                         if ( !p_aout->fifo[i_fifo].b_next_frame )
952                         {
953                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
954                             {
955                                 break;
956                             }
957                         }
958
959                         if ( p_aout->fifo[i_fifo].l_units > l_units )
960                         {
961                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
962                             while ( l_buffer < l_buffer_limit )
963                             {
964                                 p_aout->s32_buffer[l_buffer++] +=
965                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
966                                 p_aout->s32_buffer[l_buffer++] +=
967                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
968
969                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
970                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
971                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
972                                 {
973                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
974                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
975                                 }
976                             }
977                             p_aout->fifo[i_fifo].l_units -= l_units;
978                             break;
979                         }
980                         else
981                         {
982                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
983                             /* p_aout->b_stereo == 1 */
984                             while ( l_buffer < l_buffer_limit )
985                             {
986                                 p_aout->s32_buffer[l_buffer++] +=
987                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
988                                 p_aout->s32_buffer[l_buffer++] +=
989                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
990
991                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
992                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
993                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
994                                 {
995                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
996                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
997                                 }
998                             }
999                             l_units -= p_aout->fifo[i_fifo].l_units;
1000
1001                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1002                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1003                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1004                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1005
1006                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1007                             p_aout->fifo[i_fifo].l_next_frame += 1;
1008                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1009                             p_aout->fifo[i_fifo].b_next_frame = 0;
1010                         }
1011                     }
1012                     break;
1013
1014                 case AOUT_ADEC_STEREO_FIFO:
1015                     if ( p_aout->fifo[i_fifo].b_die )
1016                     {
1017                         free( p_aout->fifo[i_fifo].buffer );
1018                         free( p_aout->fifo[i_fifo].date );
1019                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1020                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1021                         continue;
1022                     }
1023
1024                     l_units = p_aout->l_units;
1025                     l_buffer = 0;
1026                     while ( l_units > 0 )
1027                     {
1028                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1029                         {
1030                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1031                             {
1032                                 break;
1033                             }
1034                         }
1035
1036                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1037                         {
1038                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1039                             while ( l_buffer < l_buffer_limit )
1040                             {
1041                                 p_aout->s32_buffer[l_buffer++] +=
1042                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1043                                 p_aout->s32_buffer[l_buffer++] +=
1044                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1045
1046                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1047                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1048                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1049                                 {
1050                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1051                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1052                                 }
1053                             }
1054                             p_aout->fifo[i_fifo].l_units -= l_units;
1055                             break;
1056                         }
1057                         else
1058                         {
1059                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1060                             /* p_aout->b_stereo == 1 */
1061                             while ( l_buffer < l_buffer_limit )
1062                             {
1063                                 p_aout->s32_buffer[l_buffer++] +=
1064                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1065                                 p_aout->s32_buffer[l_buffer++] +=
1066                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1067
1068                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1069                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1070                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1071                                 {
1072                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1073                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1074                                 }
1075                             }
1076                             l_units -= p_aout->fifo[i_fifo].l_units;
1077
1078                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1079                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1080                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1081                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1082
1083                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1084                             p_aout->fifo[i_fifo].l_next_frame += 1;
1085                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1086                             p_aout->fifo[i_fifo].b_next_frame = 0;
1087                         }
1088                     }
1089                     break;
1090
1091             default:
1092                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1093                     break;
1094             }
1095         }
1096         vlc_mutex_unlock( &p_aout->fifos_lock );
1097
1098         l_buffer_limit = p_aout->l_units  << 1 ; /* p_aout->b_stereo == 1 */
1099
1100         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1101         {
1102             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
1103             p_aout->s32_buffer[l_buffer] = 0;
1104         }
1105         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1106         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1107         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1108         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1109         {
1110             msleep( p_aout->l_msleep );
1111         }
1112     }
1113
1114     vlc_mutex_lock( &p_aout->fifos_lock );
1115     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1116     {
1117         switch ( p_aout->fifo[i_fifo].i_type )
1118         {
1119             case AOUT_EMPTY_FIFO:
1120                 break;
1121
1122             case AOUT_INTF_MONO_FIFO:
1123             case AOUT_INTF_STEREO_FIFO:
1124                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1125                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1126                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1127                 break;
1128
1129             case AOUT_ADEC_MONO_FIFO:
1130             case AOUT_ADEC_STEREO_FIFO:
1131                 free( p_aout->fifo[i_fifo].buffer );
1132                 free( p_aout->fifo[i_fifo].date );
1133                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1134                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1135                 break;
1136
1137             default:
1138                 break;
1139         }
1140     }
1141     vlc_mutex_unlock( &p_aout->fifos_lock );
1142
1143 }
1144
1145 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1146 {
1147 }
1148
1149 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1150 {
1151     int i_fifo;
1152     long l_buffer, l_buffer_limit;
1153     long l_units, l_bytes;
1154
1155     intf_DbgMsg("adec debug: running audio output S16_S_thread (%p) (pid == %i)", p_aout, getpid());
1156
1157     /* As the s32_buffer was created with calloc(), we don't have to set this
1158      * memory to zero and we can immediately jump into the thread's loop */
1159     while ( !p_aout->b_die )
1160     {
1161         vlc_mutex_lock( &p_aout->fifos_lock );
1162         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1163         {
1164             switch ( p_aout->fifo[i_fifo].i_type )
1165             {
1166                 case AOUT_EMPTY_FIFO:
1167                     break;
1168
1169                 case AOUT_INTF_MONO_FIFO:
1170                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1171                     {
1172                         l_buffer = 0;
1173                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1174                         {
1175                             p_aout->s32_buffer[l_buffer++] +=
1176                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1177                             p_aout->s32_buffer[l_buffer++] +=
1178                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1179                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1180                         }
1181                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1182                     }
1183                     else
1184                     {
1185                         l_buffer = 0;
1186                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1187                         {
1188                             p_aout->s32_buffer[l_buffer++] +=
1189                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1190                             p_aout->s32_buffer[l_buffer++] +=
1191                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1192                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1193                         }
1194                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1195                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1196                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1197                     }
1198                     break;
1199
1200                 case AOUT_INTF_STEREO_FIFO:
1201                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1202                     {
1203                         l_buffer = 0;
1204                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1205                         {
1206                             p_aout->s32_buffer[l_buffer++] +=
1207                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1208                             p_aout->s32_buffer[l_buffer++] +=
1209                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1210                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1211                         }
1212                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1213                     }
1214                     else
1215                     {
1216                         l_buffer = 0;
1217                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1218                         {
1219                             p_aout->s32_buffer[l_buffer++] +=
1220                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1221                             p_aout->s32_buffer[l_buffer++] +=
1222                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1223                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1224                         }
1225                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1226                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1227                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1228                     }
1229                     break;
1230
1231                 case AOUT_ADEC_MONO_FIFO:
1232                     if ( p_aout->fifo[i_fifo].b_die )
1233                     {
1234                         free( p_aout->fifo[i_fifo].buffer );
1235                         free( p_aout->fifo[i_fifo].date );
1236                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1237                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1238                         continue;
1239                     }
1240
1241                     l_units = p_aout->l_units;
1242                     l_buffer = 0;
1243                     while ( l_units > 0 )
1244                     {
1245                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1246                         {
1247                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1248                             {
1249                                 break;
1250                             }
1251                         }
1252
1253                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1254                         {
1255                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1256                             while ( l_buffer < l_buffer_limit )
1257                             {
1258                                 p_aout->s32_buffer[l_buffer++] +=
1259                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1260                                 p_aout->s32_buffer[l_buffer++] +=
1261                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1262
1263                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1264                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1265                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1266                                 {
1267                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1268                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1269                                 }
1270                             }
1271                             p_aout->fifo[i_fifo].l_units -= l_units;
1272                             break;
1273                         }
1274                         else
1275                         {
1276                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1277                             /* p_aout->b_stereo == 1 */
1278                             while ( l_buffer < l_buffer_limit )
1279                             {
1280                                 p_aout->s32_buffer[l_buffer++] +=
1281                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1282                                 p_aout->s32_buffer[l_buffer++] +=
1283                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1284
1285                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1286                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1287                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1288                                 {
1289                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1290                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1291                                 }
1292                             }
1293                             l_units -= p_aout->fifo[i_fifo].l_units;
1294
1295                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1296                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1297                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1298                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1299
1300                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1301                             p_aout->fifo[i_fifo].l_next_frame += 1;
1302                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1303                             p_aout->fifo[i_fifo].b_next_frame = 0;
1304                         }
1305                     }
1306                     break;
1307
1308                 case AOUT_ADEC_STEREO_FIFO:
1309                     if ( p_aout->fifo[i_fifo].b_die )
1310                     {
1311                         free( p_aout->fifo[i_fifo].buffer );
1312                         free( p_aout->fifo[i_fifo].date );
1313                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1314                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1315                         continue;
1316                     }
1317
1318                     l_units = p_aout->l_units;
1319                     l_buffer = 0;
1320                     while ( l_units > 0 )
1321                     {
1322                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1323                         {
1324                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1325                             {
1326                                 break;
1327                             }
1328                         }
1329
1330                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1331                         {
1332                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1333                             while ( l_buffer < l_buffer_limit )
1334                             {
1335                                 p_aout->s32_buffer[l_buffer++] +=
1336                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1337                                 p_aout->s32_buffer[l_buffer++] +=
1338                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1339
1340                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1341                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1342                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1343                                 {
1344                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1345                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1346                                 }
1347                             }
1348                             p_aout->fifo[i_fifo].l_units -= l_units;
1349                             break;
1350                         }
1351                         else
1352                         {
1353                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1354                             /* p_aout->b_stereo == 1 */
1355                             while ( l_buffer < l_buffer_limit )
1356                             {
1357                                 p_aout->s32_buffer[l_buffer++] +=
1358                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1359                                 p_aout->s32_buffer[l_buffer++] +=
1360                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1361
1362                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1363                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1364                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1365                                 {
1366                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1367                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1368                                 }
1369                             }
1370                             l_units -= p_aout->fifo[i_fifo].l_units;
1371
1372                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1373                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1374                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1375                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1376
1377                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1378                             p_aout->fifo[i_fifo].l_next_frame += 1;
1379                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1380                             p_aout->fifo[i_fifo].b_next_frame = 0;
1381                         }
1382                     }
1383                     break;
1384
1385             default:
1386                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1387                     break;
1388             }
1389         }
1390         vlc_mutex_unlock( &p_aout->fifos_lock );
1391
1392         l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1393
1394         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1395         {
1396             ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * p_aout->vol / 256 ) ;
1397             p_aout->s32_buffer[l_buffer] = 0;
1398         }
1399
1400         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1401         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1402         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1403         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1404         {
1405             msleep( p_aout->l_msleep );
1406         }
1407     }
1408
1409     vlc_mutex_lock( &p_aout->fifos_lock );
1410     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1411     {
1412         switch ( p_aout->fifo[i_fifo].i_type )
1413         {
1414             case AOUT_EMPTY_FIFO:
1415                 break;
1416
1417             case AOUT_INTF_MONO_FIFO:
1418             case AOUT_INTF_STEREO_FIFO:
1419                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1420                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1421                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1422                 break;
1423
1424             case AOUT_ADEC_MONO_FIFO:
1425             case AOUT_ADEC_STEREO_FIFO:
1426                 free( p_aout->fifo[i_fifo].buffer );
1427                 free( p_aout->fifo[i_fifo].date );
1428                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1429                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1430                 break;
1431
1432             default:
1433                 break;
1434         }
1435     }
1436     vlc_mutex_unlock( &p_aout->fifos_lock );
1437 }
1438
1439 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1440 {
1441 }
1442
1443 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )
1444 {
1445 }