]> git.sesse.net Git - vlc/blob - src/audio_output/audio_output.c
- Added vlc_mutex_destroy and vlc_cond_destroy function, for pthreads.
[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
343     int i_fifo;
344     
345     /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
346
347     intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)", p_aout);
348
349     /* Ask thread to kill itself and wait until it's done */
350     p_aout->b_die = 1;
351     vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
352
353     /* Free the allocated memory */
354     free( p_aout->buffer );
355     free( p_aout->s32_buffer );
356
357     /* Destroy the condition and mutex locks */
358     vlc_mutex_destroy( &p_aout->fifos_lock );
359     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
360     {
361         vlc_mutex_destroy( &p_aout->fifo[i_fifo].data_lock );
362         vlc_cond_destroy( &p_aout->fifo[i_fifo].data_wait );
363     }
364     
365     /* Free the structure */
366     p_aout->p_sys_close( p_aout );
367     intf_DbgMsg("aout debug: audio device (%s) closed", p_aout->psz_device);
368
369     /* Free structure */
370     free( p_aout );
371 }
372
373 /*****************************************************************************
374  * aout_CreateFifo
375  *****************************************************************************/
376 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
377 {
378     int i_fifo;
379
380     /* Take the fifos lock */
381     vlc_mutex_lock( &p_aout->fifos_lock );
382
383     /* Looking for a free fifo structure */
384     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
385     {
386         if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
387         {
388             break;
389         }
390     }
391     if ( i_fifo == AOUT_MAX_FIFOS )
392     {
393         intf_ErrMsg("aout error: no empty fifo available");
394         vlc_mutex_unlock( &p_aout->fifos_lock );
395         return( NULL );
396     }
397
398     /* Initialize the new fifo structure */
399     switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
400     {
401         case AOUT_INTF_MONO_FIFO:
402         case AOUT_INTF_STEREO_FIFO:
403             p_aout->fifo[i_fifo].b_die = 0;
404
405             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
406             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
407             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
408
409             p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
410
411             p_aout->fifo[i_fifo].l_unit = 0;
412             InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
413             p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
414             break;
415
416         case AOUT_ADEC_MONO_FIFO:
417         case AOUT_ADEC_STEREO_FIFO:
418             p_aout->fifo[i_fifo].b_die = 0;
419
420             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
421             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
422             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
423
424             p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
425             /* Allocate the memory needed to store the audio frames. As the
426              * fifo is a rotative fifo, we must be able to find out whether the
427              * fifo is full or empty, that's why we must in fact allocate memory
428              * for (AOUT_FIFO_SIZE+1) audio frames. */
429             if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
430             {
431                 intf_ErrMsg("aout error: not enough memory to create the frames buffer");
432                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
433                 vlc_mutex_unlock( &p_aout->fifos_lock );
434                 return( NULL );
435             }
436
437             /* Allocate the memory needed to store the dates of the frames */
438             if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
439             {
440                 intf_ErrMsg("aout error: not enough memory to create the dates buffer");
441                 free( p_aout->fifo[i_fifo].buffer );
442                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
443                 vlc_mutex_unlock( &p_aout->fifos_lock );
444                 return( NULL );
445             }
446
447             /* Set the fifo's buffer as empty (the first frame that is to be
448              * played is also the first frame that is not to be played) */
449             p_aout->fifo[i_fifo].l_start_frame = 0;
450             /* p_aout->fifo[i_fifo].l_next_frame = 0; */
451             p_aout->fifo[i_fifo].l_end_frame = 0;
452
453             /* Waiting for the audio decoder to compute enough frames to work
454              * out the fifo's current rate (as soon as the decoder has decoded
455              * enough frames, the members of the fifo structure that are not
456              * initialized now will be calculated) */
457             p_aout->fifo[i_fifo].b_start_frame = 0;
458             p_aout->fifo[i_fifo].b_next_frame = 0;
459             break;
460
461         default:
462             intf_ErrMsg("aout error: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
463             p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
464             vlc_mutex_unlock( &p_aout->fifos_lock );
465             return( NULL );
466     }
467
468     /* Release the fifos lock */
469     vlc_mutex_unlock( &p_aout->fifos_lock );
470
471     /* Return the pointer to the fifo structure */
472     intf_DbgMsg("aout debug: audio output fifo (%p) allocated", &p_aout->fifo[i_fifo]);
473     return( &p_aout->fifo[i_fifo] );
474 }
475
476 /*****************************************************************************
477  * aout_DestroyFifo
478  *****************************************************************************/
479 void aout_DestroyFifo( aout_fifo_t * p_fifo )
480 {
481     intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)", p_fifo);
482     p_fifo->b_die = 1;
483 }
484
485 /* Here are the local macros */
486
487 #define UPDATE_INCREMENT( increment, integer ) \
488     if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
489     { \
490         (integer) += (increment).l_euclidean_integer + 1; \
491         (increment).l_remainder -= (increment).l_euclidean_denominator; \
492     } \
493     else \
494     { \
495         (integer) += (increment).l_euclidean_integer; \
496     }
497
498 /* Following functions are local */
499
500 /*****************************************************************************
501  * NextFrame
502  *****************************************************************************/
503 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
504 {
505     long l_units, l_rate;
506
507     /* We take the lock */
508     vlc_mutex_lock( &p_fifo->data_lock );
509
510     /* Are we looking for a dated start frame ? */
511     if ( !p_fifo->b_start_frame )
512     {
513         while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
514         {
515             if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
516             {
517                 p_fifo->b_start_frame = 1;
518                 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
519                 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
520                 break;
521             }
522             p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
523         }
524
525         if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
526         {
527             vlc_mutex_unlock( &p_fifo->data_lock );
528             return( -1 );
529         }
530     }
531
532     /* We are looking for the next dated frame */
533     /* FIXME : is the output fifo full ?? */
534     while ( !p_fifo->b_next_frame )
535     {
536         while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
537         {
538             if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
539             {
540                 p_fifo->b_next_frame = 1;
541                 break;
542             }
543             p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
544         }
545
546         while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
547         {
548             vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
549             if ( p_fifo->b_die )
550             {
551                 vlc_mutex_unlock( &p_fifo->data_lock );
552                 return( -1 );
553             }
554         }
555     }
556
557     l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
558
559     l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
560     intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
561
562     InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
563
564     p_fifo->l_units = (((l_units - (p_fifo->l_unit -
565         (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
566         * p_aout->l_rate) / l_rate) + 1;
567
568     /* We release the lock before leaving */
569     vlc_mutex_unlock( &p_fifo->data_lock );
570     return( 0 );
571 }
572
573 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
574 {
575 }
576
577 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
578 {
579 }
580
581 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
582 {
583     int i_fifo;
584     long l_buffer, l_buffer_limit;
585     long l_units, l_bytes;
586
587     intf_DbgMsg("adec debug: running audio output U8_M_thread (%p) (pid == %i)", p_aout, getpid());
588
589     /* As the s32_buffer was created with calloc(), we don't have to set this
590      * memory to zero and we can immediately jump into the thread's loop */
591     while ( !p_aout->b_die )
592     {
593         vlc_mutex_lock( &p_aout->fifos_lock );
594         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
595         {
596             switch ( p_aout->fifo[i_fifo].i_type )
597             {
598                 case AOUT_EMPTY_FIFO:
599                     break;
600
601                 case AOUT_INTF_MONO_FIFO:
602                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
603                     {
604                         l_buffer = 0;
605                         while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
606                         {
607                             p_aout->s32_buffer[l_buffer++] +=
608                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
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                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
614                     }
615                     else
616                     {
617                         l_buffer = 0;
618                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
619                         {
620                             p_aout->s32_buffer[l_buffer++] +=
621                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
622                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
623                         }
624                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
625                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
626                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
627                     }
628                     break;
629
630                 case AOUT_INTF_STEREO_FIFO:
631                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
632                     {
633                         l_buffer = 0;
634                         while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
635                         {
636                             /* I mix half left - half right */
637                             p_aout->s32_buffer[l_buffer++] +=
638                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
639                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
640                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
641                         }
642                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
643                     }
644                     else
645                     {
646                         l_buffer = 0;
647                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
648                         {
649                             /* I mix half left - half right */
650                             p_aout->s32_buffer[l_buffer++] +=
651                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
652                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
653                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
654                         }
655                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
656                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
657                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
658                     }
659                     break;
660
661                 case AOUT_ADEC_MONO_FIFO:
662                     if ( p_aout->fifo[i_fifo].b_die )
663                     {
664                         free( p_aout->fifo[i_fifo].buffer );
665                         free( p_aout->fifo[i_fifo].date );
666                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
667                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
668                         continue;
669                     }
670
671                     l_units = p_aout->l_units;
672                     l_buffer = 0;
673                     while ( l_units > 0 )
674                     {
675                         if ( !p_aout->fifo[i_fifo].b_next_frame )
676                         {
677                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
678                             {
679                                 break;
680                             }
681                         }
682
683                         if ( p_aout->fifo[i_fifo].l_units > l_units )
684                         {
685                             l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
686                             while ( l_buffer < l_buffer_limit )
687                             {
688                                 p_aout->s32_buffer[l_buffer++] +=
689                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
690
691                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
692                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
693                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
694                                 {
695                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
696                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
697                                 }
698                             }
699                             p_aout->fifo[i_fifo].l_units -= l_units;
700                             break;
701                         }
702                         else
703                         {
704                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
705                             /* p_aout->b_stereo == 0 */
706                             while ( l_buffer < l_buffer_limit )
707                             {
708                                 p_aout->s32_buffer[l_buffer++] +=
709                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
710
711                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
712                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
713                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
714                                 {
715                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
716                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
717                                 }
718                             }
719                             l_units -= p_aout->fifo[i_fifo].l_units;
720
721                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
722                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
723                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
724                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
725
726                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
727                             p_aout->fifo[i_fifo].l_next_frame += 1;
728                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
729                             p_aout->fifo[i_fifo].b_next_frame = 0;
730                         }
731                     }
732                     break;
733
734                 case AOUT_ADEC_STEREO_FIFO:
735                     if ( p_aout->fifo[i_fifo].b_die )
736                     {
737                         free( p_aout->fifo[i_fifo].buffer );
738                         free( p_aout->fifo[i_fifo].date );
739                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
740                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
741                         continue;
742                     }
743
744                     l_units = p_aout->l_units;
745                     l_buffer = 0;
746                     while ( l_units > 0 )
747                     {
748                         if ( !p_aout->fifo[i_fifo].b_next_frame )
749                         {
750                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
751                             {
752                                 break;
753                             }
754                         }
755
756                         if ( p_aout->fifo[i_fifo].l_units > l_units )
757                         {
758                             l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
759                             while ( l_buffer < l_buffer_limit )
760                             {
761                                 /* I mix half left - half right */
762                                 p_aout->s32_buffer[l_buffer++] +=
763                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
764                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
765
766                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
767                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
768                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
769                                 {
770                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
771                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
772                                 }
773                             }
774                             p_aout->fifo[i_fifo].l_units -= l_units;
775                             break;
776                         }
777                         else
778                         {
779                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
780                             /* p_aout->b_stereo == 0 */
781                             while ( l_buffer < l_buffer_limit )
782                             {
783                                 /* I mix half left - half right */
784                                 p_aout->s32_buffer[l_buffer++] +=
785                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
786                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
787
788                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
789                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
790                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
791                                 {
792                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
793                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
794                                 }
795                             }
796                             l_units -= p_aout->fifo[i_fifo].l_units;
797
798                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
799                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
800                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
801                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
802
803                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
804                             p_aout->fifo[i_fifo].l_next_frame += 1;
805                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
806                             p_aout->fifo[i_fifo].b_next_frame = 0;
807                         }
808                     }
809                     break;
810
811             default:
812                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
813                     break;
814             }
815         }
816         vlc_mutex_unlock( &p_aout->fifos_lock );
817
818         l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
819
820         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
821         {
822             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
823             p_aout->s32_buffer[l_buffer] = 0;
824         }
825         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
826         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
827         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
828         if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
829         {
830             msleep( p_aout->l_msleep );
831         }
832     }
833
834     vlc_mutex_lock( &p_aout->fifos_lock );
835     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
836     {
837         switch ( p_aout->fifo[i_fifo].i_type )
838         {
839             case AOUT_EMPTY_FIFO:
840                 break;
841
842             case AOUT_INTF_MONO_FIFO:
843             case AOUT_INTF_STEREO_FIFO:
844                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
845                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
846                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
847                 break;
848
849             case AOUT_ADEC_MONO_FIFO:
850             case AOUT_ADEC_STEREO_FIFO:
851                 free( p_aout->fifo[i_fifo].buffer );
852                 free( p_aout->fifo[i_fifo].date );
853                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
854                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
855                 break;
856
857             default:
858                 break;
859         }
860     }
861     vlc_mutex_unlock( &p_aout->fifos_lock );
862
863
864 }
865
866 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
867 {
868     int i_fifo;
869     long l_buffer, l_buffer_limit;
870     long l_units, l_bytes;
871
872     intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
873
874     /* As the s32_buffer was created with calloc(), we don't have to set this
875      * memory to zero and we can immediately jump into the thread's loop */
876     while ( !p_aout->b_die )
877     {
878         vlc_mutex_lock( &p_aout->fifos_lock );
879         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
880         {
881             switch ( p_aout->fifo[i_fifo].i_type )
882             {
883                 case AOUT_EMPTY_FIFO:
884                     break;
885
886                 case AOUT_INTF_MONO_FIFO:
887                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
888                     {
889                         l_buffer = 0;
890                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
891                         {
892                             p_aout->s32_buffer[l_buffer++] +=
893                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
894                             p_aout->s32_buffer[l_buffer++] +=
895                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
896                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
897                         }
898                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
899                     }
900                     else
901                     {
902                         l_buffer = 0;
903                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
904                         {
905                             p_aout->s32_buffer[l_buffer++] +=
906                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
907                             p_aout->s32_buffer[l_buffer++] +=
908                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
909                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
910                         }
911                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
912                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
913                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
914                     }
915                     break;
916
917                 case AOUT_INTF_STEREO_FIFO:
918                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
919                     {
920                         l_buffer = 0;
921                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
922                         {
923                             p_aout->s32_buffer[l_buffer++] +=
924                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
925                             p_aout->s32_buffer[l_buffer++] +=
926                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
927                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
928                         }
929                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
930                     }
931                     else
932                     {
933                         l_buffer = 0;
934                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
935                         {
936                             p_aout->s32_buffer[l_buffer++] +=
937                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
938                             p_aout->s32_buffer[l_buffer++] +=
939                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
940                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
941                         }
942                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
943                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
944                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
945                     }
946                     break;
947
948                 case AOUT_ADEC_MONO_FIFO:
949                     if ( p_aout->fifo[i_fifo].b_die )
950                     {
951                         free( p_aout->fifo[i_fifo].buffer );
952                         free( p_aout->fifo[i_fifo].date );
953                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
954                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
955                         continue;
956                     }
957
958                     l_units = p_aout->l_units;
959                     l_buffer = 0;
960                     while ( l_units > 0 )
961                     {
962                         if ( !p_aout->fifo[i_fifo].b_next_frame )
963                         {
964                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
965                             {
966                                 break;
967                             }
968                         }
969
970                         if ( p_aout->fifo[i_fifo].l_units > l_units )
971                         {
972                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
973                             while ( l_buffer < l_buffer_limit )
974                             {
975                                 p_aout->s32_buffer[l_buffer++] +=
976                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
977                                 p_aout->s32_buffer[l_buffer++] +=
978                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
979
980                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
981                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
982                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
983                                 {
984                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
985                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
986                                 }
987                             }
988                             p_aout->fifo[i_fifo].l_units -= l_units;
989                             break;
990                         }
991                         else
992                         {
993                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
994                             /* p_aout->b_stereo == 1 */
995                             while ( l_buffer < l_buffer_limit )
996                             {
997                                 p_aout->s32_buffer[l_buffer++] +=
998                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
999                                 p_aout->s32_buffer[l_buffer++] +=
1000                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1001
1002                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1003                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1004                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1005                                 {
1006                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1007                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1008                                 }
1009                             }
1010                             l_units -= p_aout->fifo[i_fifo].l_units;
1011
1012                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1013                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1014                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1015                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1016
1017                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1018                             p_aout->fifo[i_fifo].l_next_frame += 1;
1019                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1020                             p_aout->fifo[i_fifo].b_next_frame = 0;
1021                         }
1022                     }
1023                     break;
1024
1025                 case AOUT_ADEC_STEREO_FIFO:
1026                     if ( p_aout->fifo[i_fifo].b_die )
1027                     {
1028                         free( p_aout->fifo[i_fifo].buffer );
1029                         free( p_aout->fifo[i_fifo].date );
1030                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1031                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1032                         continue;
1033                     }
1034
1035                     l_units = p_aout->l_units;
1036                     l_buffer = 0;
1037                     while ( l_units > 0 )
1038                     {
1039                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1040                         {
1041                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1042                             {
1043                                 break;
1044                             }
1045                         }
1046
1047                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1048                         {
1049                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1050                             while ( l_buffer < l_buffer_limit )
1051                             {
1052                                 p_aout->s32_buffer[l_buffer++] +=
1053                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1054                                 p_aout->s32_buffer[l_buffer++] +=
1055                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1056
1057                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1058                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1059                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1060                                 {
1061                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1062                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1063                                 }
1064                             }
1065                             p_aout->fifo[i_fifo].l_units -= l_units;
1066                             break;
1067                         }
1068                         else
1069                         {
1070                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1071                             /* p_aout->b_stereo == 1 */
1072                             while ( l_buffer < l_buffer_limit )
1073                             {
1074                                 p_aout->s32_buffer[l_buffer++] +=
1075                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1076                                 p_aout->s32_buffer[l_buffer++] +=
1077                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1078
1079                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1080                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1081                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1082                                 {
1083                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1084                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1085                                 }
1086                             }
1087                             l_units -= p_aout->fifo[i_fifo].l_units;
1088
1089                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1090                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1091                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1092                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1093
1094                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1095                             p_aout->fifo[i_fifo].l_next_frame += 1;
1096                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1097                             p_aout->fifo[i_fifo].b_next_frame = 0;
1098                         }
1099                     }
1100                     break;
1101
1102             default:
1103                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1104                     break;
1105             }
1106         }
1107         vlc_mutex_unlock( &p_aout->fifos_lock );
1108
1109         l_buffer_limit = p_aout->l_units  << 1 ; /* p_aout->b_stereo == 1 */
1110
1111         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1112         {
1113             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
1114             p_aout->s32_buffer[l_buffer] = 0;
1115         }
1116         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1117         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1118         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1119         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1120         {
1121             msleep( p_aout->l_msleep );
1122         }
1123     }
1124
1125     vlc_mutex_lock( &p_aout->fifos_lock );
1126     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1127     {
1128         switch ( p_aout->fifo[i_fifo].i_type )
1129         {
1130             case AOUT_EMPTY_FIFO:
1131                 break;
1132
1133             case AOUT_INTF_MONO_FIFO:
1134             case AOUT_INTF_STEREO_FIFO:
1135                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1136                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1137                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1138                 break;
1139
1140             case AOUT_ADEC_MONO_FIFO:
1141             case AOUT_ADEC_STEREO_FIFO:
1142                 free( p_aout->fifo[i_fifo].buffer );
1143                 free( p_aout->fifo[i_fifo].date );
1144                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1145                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1146                 break;
1147
1148             default:
1149                 break;
1150         }
1151     }
1152     vlc_mutex_unlock( &p_aout->fifos_lock );
1153
1154 }
1155
1156 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1157 {
1158 }
1159
1160 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1161 {
1162     int i_fifo;
1163     long l_buffer, l_buffer_limit;
1164     long l_units, l_bytes;
1165
1166     intf_DbgMsg("adec debug: running audio output S16_S_thread (%p) (pid == %i)", p_aout, getpid());
1167
1168     /* As the s32_buffer was created with calloc(), we don't have to set this
1169      * memory to zero and we can immediately jump into the thread's loop */
1170     while ( !p_aout->b_die )
1171     {
1172         vlc_mutex_lock( &p_aout->fifos_lock );
1173         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1174         {
1175             switch ( p_aout->fifo[i_fifo].i_type )
1176             {
1177                 case AOUT_EMPTY_FIFO:
1178                     break;
1179
1180                 case AOUT_INTF_MONO_FIFO:
1181                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1182                     {
1183                         l_buffer = 0;
1184                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1185                         {
1186                             p_aout->s32_buffer[l_buffer++] +=
1187                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1188                             p_aout->s32_buffer[l_buffer++] +=
1189                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1190                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1191                         }
1192                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1193                     }
1194                     else
1195                     {
1196                         l_buffer = 0;
1197                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1198                         {
1199                             p_aout->s32_buffer[l_buffer++] +=
1200                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1201                             p_aout->s32_buffer[l_buffer++] +=
1202                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1203                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1204                         }
1205                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1206                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1207                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1208                     }
1209                     break;
1210
1211                 case AOUT_INTF_STEREO_FIFO:
1212                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1213                     {
1214                         l_buffer = 0;
1215                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1216                         {
1217                             p_aout->s32_buffer[l_buffer++] +=
1218                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1219                             p_aout->s32_buffer[l_buffer++] +=
1220                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1221                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1222                         }
1223                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1224                     }
1225                     else
1226                     {
1227                         l_buffer = 0;
1228                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1229                         {
1230                             p_aout->s32_buffer[l_buffer++] +=
1231                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1232                             p_aout->s32_buffer[l_buffer++] +=
1233                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1234                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1235                         }
1236                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1237                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1238                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1239                     }
1240                     break;
1241
1242                 case AOUT_ADEC_MONO_FIFO:
1243                     if ( p_aout->fifo[i_fifo].b_die )
1244                     {
1245                         free( p_aout->fifo[i_fifo].buffer );
1246                         free( p_aout->fifo[i_fifo].date );
1247                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1248                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1249                         continue;
1250                     }
1251
1252                     l_units = p_aout->l_units;
1253                     l_buffer = 0;
1254                     while ( l_units > 0 )
1255                     {
1256                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1257                         {
1258                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1259                             {
1260                                 break;
1261                             }
1262                         }
1263
1264                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1265                         {
1266                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1267                             while ( l_buffer < l_buffer_limit )
1268                             {
1269                                 p_aout->s32_buffer[l_buffer++] +=
1270                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1271                                 p_aout->s32_buffer[l_buffer++] +=
1272                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1273
1274                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1275                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1276                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1277                                 {
1278                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1279                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1280                                 }
1281                             }
1282                             p_aout->fifo[i_fifo].l_units -= l_units;
1283                             break;
1284                         }
1285                         else
1286                         {
1287                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1288                             /* p_aout->b_stereo == 1 */
1289                             while ( l_buffer < l_buffer_limit )
1290                             {
1291                                 p_aout->s32_buffer[l_buffer++] +=
1292                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1293                                 p_aout->s32_buffer[l_buffer++] +=
1294                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1295
1296                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1297                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1298                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1299                                 {
1300                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1301                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1302                                 }
1303                             }
1304                             l_units -= p_aout->fifo[i_fifo].l_units;
1305
1306                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1307                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1308                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1309                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1310
1311                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1312                             p_aout->fifo[i_fifo].l_next_frame += 1;
1313                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1314                             p_aout->fifo[i_fifo].b_next_frame = 0;
1315                         }
1316                     }
1317                     break;
1318
1319                 case AOUT_ADEC_STEREO_FIFO:
1320                     if ( p_aout->fifo[i_fifo].b_die )
1321                     {
1322                         free( p_aout->fifo[i_fifo].buffer );
1323                         free( p_aout->fifo[i_fifo].date );
1324                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1325                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1326                         continue;
1327                     }
1328
1329                     l_units = p_aout->l_units;
1330                     l_buffer = 0;
1331                     while ( l_units > 0 )
1332                     {
1333                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1334                         {
1335                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1336                             {
1337                                 break;
1338                             }
1339                         }
1340
1341                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1342                         {
1343                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1344                             while ( l_buffer < l_buffer_limit )
1345                             {
1346                                 p_aout->s32_buffer[l_buffer++] +=
1347                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1348                                 p_aout->s32_buffer[l_buffer++] +=
1349                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1350
1351                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1352                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1353                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1354                                 {
1355                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1356                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1357                                 }
1358                             }
1359                             p_aout->fifo[i_fifo].l_units -= l_units;
1360                             break;
1361                         }
1362                         else
1363                         {
1364                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1365                             /* p_aout->b_stereo == 1 */
1366                             while ( l_buffer < l_buffer_limit )
1367                             {
1368                                 p_aout->s32_buffer[l_buffer++] +=
1369                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1370                                 p_aout->s32_buffer[l_buffer++] +=
1371                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1372
1373                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1374                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1375                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1376                                 {
1377                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1378                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1379                                 }
1380                             }
1381                             l_units -= p_aout->fifo[i_fifo].l_units;
1382
1383                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1384                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1385                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1386                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1387
1388                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1389                             p_aout->fifo[i_fifo].l_next_frame += 1;
1390                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1391                             p_aout->fifo[i_fifo].b_next_frame = 0;
1392                         }
1393                     }
1394                     break;
1395
1396             default:
1397                     intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1398                     break;
1399             }
1400         }
1401         vlc_mutex_unlock( &p_aout->fifos_lock );
1402
1403         l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1404
1405         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1406         {
1407             ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * p_aout->vol / 256 ) ;
1408             p_aout->s32_buffer[l_buffer] = 0;
1409         }
1410
1411         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1412         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1413         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1414         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1415         {
1416             msleep( p_aout->l_msleep );
1417         }
1418     }
1419
1420     vlc_mutex_lock( &p_aout->fifos_lock );
1421     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1422     {
1423         switch ( p_aout->fifo[i_fifo].i_type )
1424         {
1425             case AOUT_EMPTY_FIFO:
1426                 break;
1427
1428             case AOUT_INTF_MONO_FIFO:
1429             case AOUT_INTF_STEREO_FIFO:
1430                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1431                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1432                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1433                 break;
1434
1435             case AOUT_ADEC_MONO_FIFO:
1436             case AOUT_ADEC_STEREO_FIFO:
1437                 free( p_aout->fifo[i_fifo].buffer );
1438                 free( p_aout->fifo[i_fifo].date );
1439                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1440                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1441                 break;
1442
1443             default:
1444                 break;
1445         }
1446     }
1447     vlc_mutex_unlock( &p_aout->fifos_lock );
1448 }
1449
1450 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1451 {
1452 }
1453
1454 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )
1455 {
1456 }