1 /*****************************************************************************
2 * audio_output.c : audio output thread
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
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.
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 GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *****************************************************************************/
26 * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
28 * - Faire les optimisations dans les fonctions threads :
29 * = Stocker les "petits calculs" dans des variables au lieu de les refaire
31 * = Utiliser des tables pour les gros calculs
32 * - Faire une structure différente pour intf/adec fifo
36 /*****************************************************************************
38 *****************************************************************************/
39 #include <unistd.h> /* getpid() */
41 #include <stdio.h> /* "intf_msg.h" */
42 #include <stdlib.h> /* calloc(), malloc(), free() */
47 #include "mtime.h" /* mtime_t, mdate(), msleep() */
50 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
52 #include "audio_output.h"
55 /*****************************************************************************
57 *****************************************************************************/
59 static int aout_SpawnThread( aout_thread_t * p_aout );
61 /* Creating as much aout_Thread functions as configurations is one solution,
62 * examining the different cases in the Thread loop of an unique function is
63 * another. I chose the first solution. */
64 void aout_Thread_S8_Mono ( aout_thread_t * p_aout );
65 void aout_Thread_U8_Mono ( aout_thread_t * p_aout );
66 void aout_Thread_S16_Mono ( aout_thread_t * p_aout );
67 void aout_Thread_U16_Mono ( aout_thread_t * p_aout );
68 void aout_Thread_S8_Stereo ( aout_thread_t * p_aout );
69 void aout_Thread_U8_Stereo ( aout_thread_t * p_aout );
70 void aout_Thread_S16_Stereo ( aout_thread_t * p_aout );
71 void aout_Thread_U16_Stereo ( aout_thread_t * p_aout );
73 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
74 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
76 /*****************************************************************************
77 * aout_CreateThread: initialize audio thread
78 *****************************************************************************/
79 aout_thread_t *aout_CreateThread( int *pi_status )
81 aout_thread_t * p_aout; /* thread descriptor */
84 int i_status; /* thread status */
87 /* Allocate descriptor */
88 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
94 /* Request an interface plugin */
95 psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
97 if( RequestPlugin( &p_aout->aout_plugin, "aout", psz_method ) )
99 intf_ErrMsg( "error: could not open audio plugin aout_%s.so\n", psz_method );
105 p_aout->p_sys_open = GetPluginFunction( p_aout->aout_plugin, "aout_SysOpen" );
106 p_aout->p_sys_reset = GetPluginFunction( p_aout->aout_plugin, "aout_SysReset" );
107 p_aout->p_sys_setformat = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetFormat" );
108 p_aout->p_sys_setchannels = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetChannels" );
109 p_aout->p_sys_setrate = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetRate" );
110 p_aout->p_sys_getbufinfo = GetPluginFunction( p_aout->aout_plugin, "aout_SysGetBufInfo" );
111 p_aout->p_sys_playsamples = GetPluginFunction( p_aout->aout_plugin, "aout_SysPlaySamples" );
112 p_aout->p_sys_close = GetPluginFunction( p_aout->aout_plugin, "aout_SysClose" );
115 * Initialize audio device
117 if ( p_aout->p_sys_open( p_aout ) )
119 TrashPlugin( p_aout->aout_plugin );
124 p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
125 for i_channels == 1 or 2 ??*/
127 if ( p_aout->p_sys_reset( p_aout ) )
129 p_aout->p_sys_close( p_aout );
130 TrashPlugin( p_aout->aout_plugin );
134 if ( p_aout->p_sys_setformat( p_aout ) )
136 p_aout->p_sys_close( p_aout );
137 TrashPlugin( p_aout->aout_plugin );
141 if ( p_aout->p_sys_setchannels( p_aout ) )
143 p_aout->p_sys_close( p_aout );
144 TrashPlugin( p_aout->aout_plugin );
148 if ( p_aout->p_sys_setrate( p_aout ) )
150 p_aout->p_sys_close( p_aout );
151 TrashPlugin( p_aout->aout_plugin );
156 /* FIXME: maybe it would be cleaner to change SpawnThread prototype
157 * see vout to handle status correctly ?? however, it is not critical since
158 * this thread is only called in main and all calls are blocking */
159 if( aout_SpawnThread( p_aout ) )
161 p_aout->p_sys_close( p_aout );
162 TrashPlugin( p_aout->aout_plugin );
170 /*****************************************************************************
172 *****************************************************************************/
173 static int aout_SpawnThread( aout_thread_t * p_aout )
177 void * aout_thread = NULL;
179 intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
181 /* We want the audio output thread to live */
184 /* Initialize the fifos lock */
185 vlc_mutex_init( &p_aout->fifos_lock );
186 /* Initialize audio fifos : set all fifos as empty and initialize locks */
187 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
189 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
190 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
191 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
194 /* Compute the size (in audio units) of the audio output buffer. Although
195 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
196 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
197 p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
198 p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
200 /* Make aout_thread point to the right thread function, and compute the
201 * byte size of the audio output buffer */
202 switch ( p_aout->i_channels )
204 /* Audio output is mono */
206 switch ( p_aout->i_format )
209 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
210 aout_thread = (void *)aout_Thread_U8_Mono;
214 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
215 aout_thread = (void *)aout_Thread_S8_Mono;
218 case AOUT_FMT_U16_LE:
219 case AOUT_FMT_U16_BE:
220 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
221 aout_thread = (void *)aout_Thread_U16_Mono;
224 case AOUT_FMT_S16_LE:
225 case AOUT_FMT_S16_BE:
226 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
227 aout_thread = (void *)aout_Thread_S16_Mono;
231 intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
237 /* Audio output is stereo */
239 switch ( p_aout->i_format )
242 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
243 aout_thread = (void *)aout_Thread_U8_Stereo;
247 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
248 aout_thread = (void *)aout_Thread_S8_Stereo;
251 case AOUT_FMT_U16_LE:
252 case AOUT_FMT_U16_BE:
253 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
254 aout_thread = (void *)aout_Thread_U16_Stereo;
257 case AOUT_FMT_S16_LE:
258 case AOUT_FMT_S16_BE:
259 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
260 aout_thread = (void *)aout_Thread_S16_Stereo;
264 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
271 intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
272 p_aout->i_channels );
276 /* Allocate the memory needed by the audio output buffers, and set to zero
277 * the s32 buffer's memory */
278 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
280 intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
283 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
285 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
286 free( p_aout->buffer );
290 /* Before launching the thread, we try to predict the date of the first
291 * audio unit in the first output buffer */
292 p_aout->date = mdate() - 1000000;
294 /* Launch the thread */
295 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
297 intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
298 free( p_aout->buffer );
299 free( p_aout->s32_buffer );
303 intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
307 /*****************************************************************************
309 *****************************************************************************/
310 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
312 /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
314 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
316 /* Ask thread to kill itself and wait until it's done */
318 vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
320 /* Free the allocated memory */
321 free( p_aout->buffer );
322 free( p_aout->s32_buffer );
324 /* Free the structure */
325 p_aout->p_sys_close( p_aout );
326 intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
329 TrashPlugin( p_aout->aout_plugin );
335 /*****************************************************************************
337 *****************************************************************************/
338 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
342 /* Take the fifos lock */
343 vlc_mutex_lock( &p_aout->fifos_lock );
345 /* Looking for a free fifo structure */
346 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
348 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
353 if ( i_fifo == AOUT_MAX_FIFOS )
355 intf_ErrMsg("aout error: no empty fifo available\n");
356 vlc_mutex_unlock( &p_aout->fifos_lock );
360 /* Initialize the new fifo structure */
361 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
363 case AOUT_INTF_MONO_FIFO:
364 case AOUT_INTF_STEREO_FIFO:
365 p_aout->fifo[i_fifo].b_die = 0;
367 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
368 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
369 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
371 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
373 p_aout->fifo[i_fifo].l_unit = 0;
374 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
375 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
378 case AOUT_ADEC_MONO_FIFO:
379 case AOUT_ADEC_STEREO_FIFO:
380 p_aout->fifo[i_fifo].b_die = 0;
382 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
383 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
384 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
386 p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
387 /* Allocate the memory needed to store the audio frames. As the
388 * fifo is a rotative fifo, we must be able to find out whether the
389 * fifo is full or empty, that's why we must in fact allocate memory
390 * for (AOUT_FIFO_SIZE+1) audio frames. */
391 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
393 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
394 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
395 vlc_mutex_unlock( &p_aout->fifos_lock );
399 /* Allocate the memory needed to store the dates of the frames */
400 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
402 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
403 free( p_aout->fifo[i_fifo].buffer );
404 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
405 vlc_mutex_unlock( &p_aout->fifos_lock );
409 /* Set the fifo's buffer as empty (the first frame that is to be
410 * played is also the first frame that is not to be played) */
411 p_aout->fifo[i_fifo].l_start_frame = 0;
412 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
413 p_aout->fifo[i_fifo].l_end_frame = 0;
415 /* Waiting for the audio decoder to compute enough frames to work
416 * out the fifo's current rate (as soon as the decoder has decoded
417 * enough frames, the members of the fifo structure that are not
418 * initialized now will be calculated) */
419 p_aout->fifo[i_fifo].b_start_frame = 0;
420 p_aout->fifo[i_fifo].b_next_frame = 0;
424 intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
425 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
426 vlc_mutex_unlock( &p_aout->fifos_lock );
430 /* Release the fifos lock */
431 vlc_mutex_unlock( &p_aout->fifos_lock );
433 /* Return the pointer to the fifo structure */
434 intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
435 return( &p_aout->fifo[i_fifo] );
438 /*****************************************************************************
440 *****************************************************************************/
441 void aout_DestroyFifo( aout_fifo_t * p_fifo )
443 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
447 /* Here are the local macros */
449 #define UPDATE_INCREMENT( increment, integer ) \
450 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
452 (integer) += (increment).l_euclidean_integer + 1; \
453 (increment).l_remainder -= (increment).l_euclidean_denominator; \
457 (integer) += (increment).l_euclidean_integer; \
460 /* Following functions are local */
462 /*****************************************************************************
463 * InitializeIncrement
464 *****************************************************************************/
465 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
467 p_increment->l_remainder = -l_denominator;
469 p_increment->l_euclidean_integer = 0;
470 while ( l_numerator >= l_denominator )
472 p_increment->l_euclidean_integer++;
473 l_numerator -= l_denominator;
476 p_increment->l_euclidean_remainder = l_numerator;
478 p_increment->l_euclidean_denominator = l_denominator;
481 /*****************************************************************************
483 *****************************************************************************/
484 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
486 long l_units, l_rate;
488 /* We take the lock */
489 vlc_mutex_lock( &p_fifo->data_lock );
491 /* Are we looking for a dated start frame ? */
492 if ( !p_fifo->b_start_frame )
494 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
496 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
498 p_fifo->b_start_frame = 1;
499 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
500 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
503 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
506 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
508 vlc_mutex_unlock( &p_fifo->data_lock );
513 /* We are looking for the next dated frame */
514 /* FIXME : is the output fifo full ?? */
515 while ( !p_fifo->b_next_frame )
517 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
519 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
521 p_fifo->b_next_frame = 1;
524 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
527 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
529 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
532 vlc_mutex_unlock( &p_fifo->data_lock );
538 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
540 l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
541 // fprintf( stderr, "aout debug: %lli (%li);\n", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
543 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
545 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
546 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
547 * p_aout->l_rate) / l_rate) + 1;
549 /* We release the lock before leaving */
550 vlc_mutex_unlock( &p_fifo->data_lock );
554 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
558 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
562 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
566 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
569 long l_buffer, l_buffer_limit;
570 long l_units, l_bytes;
572 intf_DbgMsg("adec debug: ********aout_Thread_U8_Stereo********\n");
573 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
575 /* As the s32_buffer was created with calloc(), we don't have to set this
576 * memory to zero and we can immediately jump into the thread's loop */
577 while ( !p_aout->b_die )
579 vlc_mutex_lock( &p_aout->fifos_lock );
580 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
582 switch ( p_aout->fifo[i_fifo].i_type )
584 case AOUT_EMPTY_FIFO:
587 case AOUT_INTF_MONO_FIFO:
588 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
591 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
593 p_aout->s32_buffer[l_buffer++] +=
594 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
595 p_aout->s32_buffer[l_buffer++] +=
596 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
597 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
599 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
604 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
606 p_aout->s32_buffer[l_buffer++] +=
607 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
608 p_aout->s32_buffer[l_buffer++] +=
609 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
610 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
612 free( p_aout->fifo[i_fifo].buffer ); /* !! */
613 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
614 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
618 case AOUT_INTF_STEREO_FIFO:
619 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
622 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
624 p_aout->s32_buffer[l_buffer++] +=
625 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
626 p_aout->s32_buffer[l_buffer++] +=
627 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
628 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
630 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
635 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
637 p_aout->s32_buffer[l_buffer++] +=
638 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
639 p_aout->s32_buffer[l_buffer++] +=
640 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
641 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
643 free( p_aout->fifo[i_fifo].buffer ); /* !! */
644 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
645 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
649 case AOUT_ADEC_MONO_FIFO:
650 if ( p_aout->fifo[i_fifo].b_die )
652 free( p_aout->fifo[i_fifo].buffer );
653 free( p_aout->fifo[i_fifo].date );
654 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
655 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
659 l_units = p_aout->l_units;
661 while ( l_units > 0 )
663 if ( !p_aout->fifo[i_fifo].b_next_frame )
665 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
671 if ( p_aout->fifo[i_fifo].l_units > l_units )
673 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
674 while ( l_buffer < l_buffer_limit )
676 p_aout->s32_buffer[l_buffer++] +=
677 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
678 p_aout->s32_buffer[l_buffer++] +=
679 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
681 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
682 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
683 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
685 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
686 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
689 p_aout->fifo[i_fifo].l_units -= l_units;
694 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
695 /* p_aout->b_stereo == 1 */
696 while ( l_buffer < l_buffer_limit )
698 p_aout->s32_buffer[l_buffer++] +=
699 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
700 p_aout->s32_buffer[l_buffer++] +=
701 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
703 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
704 if ( 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)) )
707 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
708 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
711 l_units -= p_aout->fifo[i_fifo].l_units;
713 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
714 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
715 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
716 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
718 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
719 p_aout->fifo[i_fifo].l_next_frame += 1;
720 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
721 p_aout->fifo[i_fifo].b_next_frame = 0;
726 case AOUT_ADEC_STEREO_FIFO:
727 if ( p_aout->fifo[i_fifo].b_die )
729 free( p_aout->fifo[i_fifo].buffer );
730 free( p_aout->fifo[i_fifo].date );
731 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
732 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
736 l_units = p_aout->l_units;
738 while ( l_units > 0 )
740 if ( !p_aout->fifo[i_fifo].b_next_frame )
742 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
748 if ( p_aout->fifo[i_fifo].l_units > l_units )
750 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
751 while ( l_buffer < l_buffer_limit )
753 p_aout->s32_buffer[l_buffer++] +=
754 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
755 p_aout->s32_buffer[l_buffer++] +=
756 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
758 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
759 if ( 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)) )
762 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
763 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
766 p_aout->fifo[i_fifo].l_units -= l_units;
771 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
772 /* p_aout->b_stereo == 1 */
773 while ( l_buffer < l_buffer_limit )
775 p_aout->s32_buffer[l_buffer++] +=
776 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
777 p_aout->s32_buffer[l_buffer++] +=
778 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
780 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
781 if ( 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)) )
784 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
785 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
788 l_units -= p_aout->fifo[i_fifo].l_units;
790 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
791 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
792 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
793 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
795 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
796 p_aout->fifo[i_fifo].l_next_frame += 1;
797 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
798 p_aout->fifo[i_fifo].b_next_frame = 0;
804 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
808 vlc_mutex_unlock( &p_aout->fifos_lock );
810 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
812 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
814 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[l_buffer] / 256) + 128 );
815 p_aout->s32_buffer[l_buffer] = 0;
817 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
818 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
819 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
820 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
822 msleep( p_aout->l_msleep );
826 vlc_mutex_lock( &p_aout->fifos_lock );
827 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
829 switch ( p_aout->fifo[i_fifo].i_type )
831 case AOUT_EMPTY_FIFO:
834 case AOUT_INTF_MONO_FIFO:
835 case AOUT_INTF_STEREO_FIFO:
836 free( p_aout->fifo[i_fifo].buffer ); /* !! */
837 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
838 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
841 case AOUT_ADEC_MONO_FIFO:
842 case AOUT_ADEC_STEREO_FIFO:
843 free( p_aout->fifo[i_fifo].buffer );
844 free( p_aout->fifo[i_fifo].date );
845 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
846 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
853 vlc_mutex_unlock( &p_aout->fifos_lock );
857 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
861 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
864 long l_buffer, l_buffer_limit;
865 long l_units, l_bytes;
867 intf_DbgMsg("adec debug: ********aout_Thread_S16_Stereo********\n");
868 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
870 /* As the s32_buffer was created with calloc(), we don't have to set this
871 * memory to zero and we can immediately jump into the thread's loop */
872 while ( !p_aout->b_die )
874 vlc_mutex_lock( &p_aout->fifos_lock );
875 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
877 switch ( p_aout->fifo[i_fifo].i_type )
879 case AOUT_EMPTY_FIFO:
882 case AOUT_INTF_MONO_FIFO:
883 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
886 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
888 p_aout->s32_buffer[l_buffer++] +=
889 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
890 p_aout->s32_buffer[l_buffer++] +=
891 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
892 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
894 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
899 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
901 p_aout->s32_buffer[l_buffer++] +=
902 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
903 p_aout->s32_buffer[l_buffer++] +=
904 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
905 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
907 free( p_aout->fifo[i_fifo].buffer ); /* !! */
908 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
909 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
913 case AOUT_INTF_STEREO_FIFO:
914 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
917 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
919 p_aout->s32_buffer[l_buffer++] +=
920 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
921 p_aout->s32_buffer[l_buffer++] +=
922 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
923 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
925 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
930 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
932 p_aout->s32_buffer[l_buffer++] +=
933 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
934 p_aout->s32_buffer[l_buffer++] +=
935 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
936 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
938 free( p_aout->fifo[i_fifo].buffer ); /* !! */
939 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
940 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
944 case AOUT_ADEC_MONO_FIFO:
945 if ( p_aout->fifo[i_fifo].b_die )
947 free( p_aout->fifo[i_fifo].buffer );
948 free( p_aout->fifo[i_fifo].date );
949 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
950 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
954 l_units = p_aout->l_units;
956 while ( l_units > 0 )
958 if ( !p_aout->fifo[i_fifo].b_next_frame )
960 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
966 if ( p_aout->fifo[i_fifo].l_units > l_units )
968 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
969 while ( l_buffer < l_buffer_limit )
971 p_aout->s32_buffer[l_buffer++] +=
972 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
973 p_aout->s32_buffer[l_buffer++] +=
974 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
976 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
977 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
978 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
980 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
981 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
984 p_aout->fifo[i_fifo].l_units -= l_units;
989 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
990 /* p_aout->b_stereo == 1 */
991 while ( l_buffer < l_buffer_limit )
993 p_aout->s32_buffer[l_buffer++] +=
994 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
995 p_aout->s32_buffer[l_buffer++] +=
996 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
998 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
999 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1000 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1002 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1003 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1006 l_units -= p_aout->fifo[i_fifo].l_units;
1008 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1009 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1010 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1011 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1013 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1014 p_aout->fifo[i_fifo].l_next_frame += 1;
1015 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1016 p_aout->fifo[i_fifo].b_next_frame = 0;
1021 case AOUT_ADEC_STEREO_FIFO:
1022 if ( p_aout->fifo[i_fifo].b_die )
1024 free( p_aout->fifo[i_fifo].buffer );
1025 free( p_aout->fifo[i_fifo].date );
1026 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1027 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1031 l_units = p_aout->l_units;
1033 while ( l_units > 0 )
1035 if ( !p_aout->fifo[i_fifo].b_next_frame )
1037 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1043 if ( p_aout->fifo[i_fifo].l_units > l_units )
1045 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1046 while ( l_buffer < l_buffer_limit )
1048 p_aout->s32_buffer[l_buffer++] +=
1049 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1050 p_aout->s32_buffer[l_buffer++] +=
1051 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1053 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1054 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1055 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1057 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1058 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1061 p_aout->fifo[i_fifo].l_units -= l_units;
1066 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1067 /* p_aout->b_stereo == 1 */
1068 while ( l_buffer < l_buffer_limit )
1070 p_aout->s32_buffer[l_buffer++] +=
1071 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1072 p_aout->s32_buffer[l_buffer++] +=
1073 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1075 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1076 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1077 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1079 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1080 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1083 l_units -= p_aout->fifo[i_fifo].l_units;
1085 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1086 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1087 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1088 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1090 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1091 p_aout->fifo[i_fifo].l_next_frame += 1;
1092 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1093 p_aout->fifo[i_fifo].b_next_frame = 0;
1099 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1103 vlc_mutex_unlock( &p_aout->fifos_lock );
1105 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1107 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1109 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS );
1110 p_aout->s32_buffer[l_buffer] = 0;
1113 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1114 p_aout->date = -1000000 + mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1115 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1116 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1118 msleep( p_aout->l_msleep );
1122 vlc_mutex_lock( &p_aout->fifos_lock );
1123 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1125 switch ( p_aout->fifo[i_fifo].i_type )
1127 case AOUT_EMPTY_FIFO:
1130 case AOUT_INTF_MONO_FIFO:
1131 case AOUT_INTF_STEREO_FIFO:
1132 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1133 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1134 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1137 case AOUT_ADEC_MONO_FIFO:
1138 case AOUT_ADEC_STEREO_FIFO:
1139 free( p_aout->fifo[i_fifo].buffer );
1140 free( p_aout->fifo[i_fifo].date );
1141 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1142 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1149 vlc_mutex_unlock( &p_aout->fifos_lock );
1152 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1156 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )