* Major API change of the audio output. New aout_Dec* functions.
authorChristophe Massiot <massiot@videolan.org>
Thu, 26 Sep 2002 22:40:27 +0000 (22:40 +0000)
committerChristophe Massiot <massiot@videolan.org>
Thu, 26 Sep 2002 22:40:27 +0000 (22:40 +0000)
* Fixed a compile issue in s16tofloat32swab.
* Fixed a typo in demux/mpeg/ts.c.

21 files changed:
Makefile.old
include/aout_internal.h
include/audio_output.h
include/vlc_symbols.h
modules/audio_filter/converter/s16tofloat32swab.c
modules/codec/a52.c
modules/codec/a52old/a52old.c
modules/codec/faad/decoder.c
modules/codec/lpcm.c
modules/codec/mad/libmad.c
modules/codec/mpeg_audio/decoder.c
modules/demux/mpeg/ts.c
src/audio_output/audio_output.c [deleted file]
src/audio_output/common.c [new file with mode: 0644]
src/audio_output/dec.c [new file with mode: 0644]
src/audio_output/input.c
src/audio_output/intf.c
src/audio_output/mixer.c
src/audio_output/output.c
src/libvlc.c
src/misc/modules_plugin.h

index 33ce20e..436b1fe 100644 (file)
@@ -22,7 +22,7 @@ INTERFACE := interface intf_eject
 PLAYLIST := playlist
 INPUT := input input_ext-plugins input_ext-dec input_ext-intf input_dec input_programs input_clock input_info
 VIDEO_OUTPUT := video_output video_text vout_pictures vout_subpictures
-AUDIO_OUTPUT := audio_output filters input mixer output intf
+AUDIO_OUTPUT := common filters input mixer output intf dec
 STREAM_OUTPUT := stream_output
 MISC := mtime modules threads cpu configuration netutils iso_lang messages objects extras
 
index 9dcad7a..a4e9cb6 100644 (file)
@@ -2,7 +2,7 @@
  * aout_internal.h : internal defines for audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout_internal.h,v 1.20 2002/09/20 23:27:03 massiot Exp $
+ * $Id: aout_internal.h,v 1.21 2002/09/26 22:40:18 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -120,6 +120,8 @@ typedef struct aout_mixer_t
     void                 (* pf_do_work)( struct aout_instance_t *,
                                          struct aout_buffer_t * );
 
+    /* If b_error == 1, there is no mixer nor audio output pipeline. */
+    vlc_bool_t              b_error;
     /* Multiplier used to raise or lower the volume of the sound in
      * software. Beware, this creates sound distortion and should be avoided
      * as much as possible. This isn't available for non-float32 mixer. */
@@ -147,8 +149,10 @@ struct aout_input_t
     /* Mixer information */
     byte_t *                p_first_byte_to_mix;
 
-    /* Is the input dead ? */
+    /* If b_error == 1, there is no input pipeline. */
     vlc_bool_t              b_error;
+    /* Did we just change the output format ? (expect buffer inconsistencies) */
+    vlc_bool_t              b_changed;
 };
 
 /*****************************************************************************
@@ -186,7 +190,7 @@ struct aout_instance_t
 
     /* Locks : please note that if you need several of these locks, it is
      * mandatory (to avoid deadlocks) to take them in the following order :
-     * p_input->lock, mixer_lock, output_fifo_lock, input_fifos_lock.
+     * mixer_lock, p_input->lock, output_fifo_lock, input_fifos_lock.
      * --Meuuh */
     /* When input_fifos_lock is taken, none of the p_input->fifo structures
      * can be read or modified by a third-party thread. */
@@ -214,6 +218,8 @@ struct aout_instance_t
  * Prototypes
  *****************************************************************************/
 /* From input.c : */
+int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input );
+int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input );
 int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                     aout_buffer_t * p_buffer );
 
@@ -235,7 +241,7 @@ void aout_FiltersPlay( aout_instance_t * p_aout,
 
 /* From mixer.c : */
 int aout_MixerNew( aout_instance_t * p_aout );
-void aout_MixerDelete( aout_instance_t * p_aout );
+int aout_MixerDelete( aout_instance_t * p_aout );
 void aout_MixerRun( aout_instance_t * p_aout );
 int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier );
 int aout_MixerMultiplierGet( aout_instance_t * p_aout, float * pf_multiplier );
@@ -247,7 +253,7 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer );
 void aout_OutputDelete( aout_instance_t * p_aout );
 VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
 
-/* From audio_output.c : */
+/* From common.c : */
 VLC_EXPORT( int, aout_FormatNbChannels, ( audio_sample_format_t * p_format ) );
 void aout_FormatPrepare( audio_sample_format_t * p_format );
 void aout_FifoInit( aout_instance_t *, aout_fifo_t *, u32 );
index 78124a8..e7909f3 100644 (file)
@@ -2,7 +2,7 @@
  * audio_output.h : audio output interface
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: audio_output.h,v 1.66 2002/09/20 23:27:03 massiot Exp $
+ * $Id: audio_output.h,v 1.67 2002/09/26 22:40:18 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -168,23 +168,23 @@ struct audio_date_t
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-/* From audio_output.c : */
-#define aout_NewInstance(a) __aout_NewInstance(VLC_OBJECT(a))
-VLC_EXPORT( aout_instance_t *, __aout_NewInstance,    ( vlc_object_t * ) );
-VLC_EXPORT( void,              aout_DeleteInstance, ( aout_instance_t * ) );
-VLC_EXPORT( aout_buffer_t *, aout_BufferNew, ( aout_instance_t *, aout_input_t *, size_t ) );
-VLC_EXPORT( void, aout_BufferDelete, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
-VLC_EXPORT( int, aout_BufferPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
+/* From common.c : */
+#define aout_New(a) __aout_New(VLC_OBJECT(a))
+VLC_EXPORT( aout_instance_t *, __aout_New, ( vlc_object_t * ) );
+VLC_EXPORT( void, aout_Delete, ( aout_instance_t * ) );
 VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) );
 VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) );
 VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) );
 VLC_EXPORT( mtime_t, aout_DateGet, ( const audio_date_t * ) );
 VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, u32 ) );
 
-/* From input.c : */
-#define aout_InputNew(a,b,c) __aout_InputNew(VLC_OBJECT(a),b,c)
-VLC_EXPORT( aout_input_t *, __aout_InputNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );
-VLC_EXPORT( void, aout_InputDelete, ( aout_instance_t *, aout_input_t * ) );
+/* From dec.c : */
+#define aout_DecNew(a, b, c) __aout_DecNew(VLC_OBJECT(a), b, c)
+VLC_EXPORT( aout_input_t *, __aout_DecNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );
+VLC_EXPORT( int, aout_DecDelete, ( aout_instance_t *, aout_input_t * ) );
+VLC_EXPORT( aout_buffer_t *, aout_DecNewBuffer, ( aout_instance_t *, aout_input_t *, size_t ) );
+VLC_EXPORT( void, aout_DecDeleteBuffer, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
+VLC_EXPORT( int, aout_DecPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
 
 /* From intf.c : */
 VLC_EXPORT( int, aout_VolumeGet, ( aout_instance_t *, audio_volume_t * ) );
@@ -192,4 +192,5 @@ VLC_EXPORT( int, aout_VolumeSet, ( aout_instance_t *, audio_volume_t ) );
 VLC_EXPORT( int, aout_VolumeInfos, ( aout_instance_t *, audio_volume_t * ) );
 VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, audio_volume_t * ) );
 VLC_EXPORT( int, aout_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
+VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
 
index d302a4b..a7e9b08 100644 (file)
@@ -2,11 +2,11 @@
 
 struct module_symbols_t
 {
-    aout_buffer_t * (* aout_BufferNew_inner) ( aout_instance_t *, aout_input_t *, size_t ) ;
+    aout_buffer_t * (* aout_DecNewBuffer_inner) ( aout_instance_t *, aout_input_t *, size_t ) ;
     aout_buffer_t * (* aout_FifoPop_inner) ( aout_instance_t * p_aout, aout_fifo_t * p_fifo ) ;
     aout_buffer_t * (* aout_OutputNextBuffer_inner) ( aout_instance_t *, mtime_t, vlc_bool_t ) ;
-    aout_input_t * (* __aout_InputNew_inner) ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ;
-    aout_instance_t * (* __aout_NewInstance_inner) ( vlc_object_t * ) ;
+    aout_input_t * (* __aout_DecNew_inner) ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ;
+    aout_instance_t * (* __aout_New_inner) ( vlc_object_t * ) ;
     char * (* __config_GetPsz_inner) (vlc_object_t *, const char *) ;
     char * (* config_GetHomeDir_inner) ( void ) ;
     char * (* input_OffsetToTime_inner) ( input_thread_t *, char *, off_t ) ;
@@ -37,8 +37,10 @@ struct module_symbols_t
     int (* __vlc_thread_create_inner) ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), int, vlc_bool_t ) ;
     int (* __vlc_threads_end_inner) ( vlc_object_t * ) ;
     int (* __vlc_threads_init_inner) ( vlc_object_t * ) ;
-    int (* aout_BufferPlay_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
+    int (* aout_DecDelete_inner) ( aout_instance_t *, aout_input_t * ) ;
+    int (* aout_DecPlay_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
     int (* aout_FormatNbChannels_inner) ( audio_sample_format_t * p_format ) ;
+    int (* aout_Restart_inner) ( aout_instance_t * p_aout ) ;
     int (* aout_VolumeDown_inner) ( aout_instance_t *, int, audio_volume_t * ) ;
     int (* aout_VolumeGet_inner) ( aout_instance_t *, audio_volume_t * ) ;
     int (* aout_VolumeInfos_inner) ( aout_instance_t *, audio_volume_t * ) ;
@@ -111,12 +113,11 @@ struct module_symbols_t
     void (* __vlc_object_yield_inner) ( vlc_object_t * ) ;
     void (* __vlc_thread_join_inner) ( vlc_object_t *, char *, int ) ;
     void (* __vlc_thread_ready_inner) ( vlc_object_t * ) ;
-    void (* aout_BufferDelete_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
     void (* aout_DateInit_inner) ( audio_date_t *, u32 ) ;
     void (* aout_DateMove_inner) ( audio_date_t *, mtime_t ) ;
     void (* aout_DateSet_inner) ( audio_date_t *, mtime_t ) ;
-    void (* aout_DeleteInstance_inner) ( aout_instance_t * ) ;
-    void (* aout_InputDelete_inner) ( aout_instance_t *, aout_input_t * ) ;
+    void (* aout_DecDeleteBuffer_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
+    void (* aout_Delete_inner) ( aout_instance_t * ) ;
     void (* aout_VolumeNoneInit_inner) ( aout_instance_t * ) ;
     void (* aout_VolumeSoftInit_inner) ( aout_instance_t * ) ;
     void (* config_Duplicate_inner) ( module_t *, module_config_t * ) ;
@@ -172,8 +173,8 @@ struct module_symbols_t
 #   define UnalignedGetBits p_symbols->UnalignedGetBits_inner
 #   define UnalignedRemoveBits p_symbols->UnalignedRemoveBits_inner
 #   define UnalignedShowBits p_symbols->UnalignedShowBits_inner
-#   define __aout_InputNew p_symbols->__aout_InputNew_inner
-#   define __aout_NewInstance p_symbols->__aout_NewInstance_inner
+#   define __aout_DecNew p_symbols->__aout_DecNew_inner
+#   define __aout_New p_symbols->__aout_New_inner
 #   define __config_GetFloat p_symbols->__config_GetFloat_inner
 #   define __config_GetInt p_symbols->__config_GetInt_inner
 #   define __config_GetPsz p_symbols->__config_GetPsz_inner
@@ -222,19 +223,20 @@ struct module_symbols_t
 #   define __vlc_threads_end p_symbols->__vlc_threads_end_inner
 #   define __vlc_threads_init p_symbols->__vlc_threads_init_inner
 #   define __vout_CreateThread p_symbols->__vout_CreateThread_inner
-#   define aout_BufferDelete p_symbols->aout_BufferDelete_inner
-#   define aout_BufferNew p_symbols->aout_BufferNew_inner
-#   define aout_BufferPlay p_symbols->aout_BufferPlay_inner
 #   define aout_DateGet p_symbols->aout_DateGet_inner
 #   define aout_DateIncrement p_symbols->aout_DateIncrement_inner
 #   define aout_DateInit p_symbols->aout_DateInit_inner
 #   define aout_DateMove p_symbols->aout_DateMove_inner
 #   define aout_DateSet p_symbols->aout_DateSet_inner
-#   define aout_DeleteInstance p_symbols->aout_DeleteInstance_inner
+#   define aout_DecDelete p_symbols->aout_DecDelete_inner
+#   define aout_DecDeleteBuffer p_symbols->aout_DecDeleteBuffer_inner
+#   define aout_DecNewBuffer p_symbols->aout_DecNewBuffer_inner
+#   define aout_DecPlay p_symbols->aout_DecPlay_inner
+#   define aout_Delete p_symbols->aout_Delete_inner
 #   define aout_FifoPop p_symbols->aout_FifoPop_inner
 #   define aout_FormatNbChannels p_symbols->aout_FormatNbChannels_inner
-#   define aout_InputDelete p_symbols->aout_InputDelete_inner
 #   define aout_OutputNextBuffer p_symbols->aout_OutputNextBuffer_inner
+#   define aout_Restart p_symbols->aout_Restart_inner
 #   define aout_VolumeDown p_symbols->aout_VolumeDown_inner
 #   define aout_VolumeGet p_symbols->aout_VolumeGet_inner
 #   define aout_VolumeInfos p_symbols->aout_VolumeInfos_inner
index 66e0f8a..b5ac29d 100644 (file)
@@ -3,7 +3,7 @@
  *                      with endianness change
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: s16tofloat32swab.c,v 1.3 2002/09/20 23:27:03 massiot Exp $
+ * $Id: s16tofloat32swab.c,v 1.4 2002/09/26 22:40:19 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Henri Fallon <henri@videolan.org>
@@ -115,7 +115,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
 #ifndef HAVE_SWAB
         p_tmp[0] = ((byte_t *)p_in)[1];
         p_tmp[1] = ((byte_t *)p_in)[0];
-        *p_out = (float)*( *(s16 *)p_tmp ) / 32768.0;
+        *p_out = (float)( *(s16 *)p_tmp ) / 32768.0;
 #else
         *p_out = (float)*p_in / 32768.0;
 #endif
index 917b8db..d92ec94 100644 (file)
@@ -2,7 +2,7 @@
  * a52.c: A/52 basic parser
  *****************************************************************************
  * Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.12 2002/09/20 23:27:03 massiot Exp $
+ * $Id: a52.c,v 1.13 2002/09/26 22:40:20 massiot Exp $
  *
  * Authors: St├ęphane Borel <stef@via.ecp.fr>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -174,7 +174,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
                 || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
         {
             /* Parameters changed - this should not happen. */
-            aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+            aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
             p_dec->p_aout_input = NULL;
         }
 
@@ -186,9 +186,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             p_dec->output_format.i_bytes_per_frame = i_frame_size;
             p_dec->output_format.i_frame_length = A52_FRAME_NB;
             aout_DateInit( &end_date, i_rate );
-            p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
-                                                 &p_dec->p_aout,
-                                                 &p_dec->output_format );
+            p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
+                                               &p_dec->p_aout,
+                                               &p_dec->output_format );
 
             if ( p_dec->p_aout_input == NULL )
             {
@@ -206,8 +206,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             continue;
         }
 
-        p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input,
-                                   A52_FRAME_NB );
+        p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input,
+                                      A52_FRAME_NB );
         if ( p_buffer == NULL ) return -1;
         p_buffer->start_date = aout_DateGet( &end_date );
         p_buffer->end_date = aout_DateIncrement( &end_date,
@@ -219,13 +219,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
                   i_frame_size - 7 );
         if( p_dec->p_fifo->b_die )
         {
-            aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
-                               p_buffer );
+            aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
+                                  p_buffer );
             break;
         }
 
         /* Send the buffer to the mixer. */
-        aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
+        aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
     }
 
     /* If b_error is set, the spdif thread enters the error loop */
@@ -247,7 +247,7 @@ static void EndThread( dec_thread_t * p_dec )
 {
     if ( p_dec->p_aout_input != NULL )
     {
-        aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
     }
 
     free( p_dec );
index ad22d79..ebe9d26 100644 (file)
@@ -2,7 +2,7 @@
  * a52old.c: A52 decoder module main file
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: a52old.c,v 1.6 2002/08/30 22:22:24 massiot Exp $
+ * $Id: a52old.c,v 1.7 2002/09/26 22:40:20 massiot Exp $
  *
  * Authors: Michel Lespinasse <walken@zoy.org>
  *
@@ -167,7 +167,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             {
                 /* Delete old output */
                 msg_Warn( p_a52dec->p_fifo, "opening a new aout" );
-                aout_InputDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
+                aout_DecDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
             }
 
             /* Set output configuration */
@@ -175,9 +175,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             output_format.i_channels = 2; /* FIXME ! */
             output_format.i_rate     = sync_info.sample_rate;
             aout_DateInit( &end_date, output_format.i_rate );
-            p_a52dec->p_aout_input = aout_InputNew( p_a52dec->p_fifo,
-                                                    &p_a52dec->p_aout,
-                                                    &output_format );
+            p_a52dec->p_aout_input = aout_DecNew( p_a52dec->p_fifo,
+                                                  &p_a52dec->p_aout,
+                                                  &output_format );
         }
 
         if( p_a52dec->p_aout_input == NULL )
@@ -198,9 +198,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
             continue;
         }
 
-        p_aout_buffer = aout_BufferNew( p_a52dec->p_aout,
-                                        p_a52dec->p_aout_input,
-                                        A52DEC_FRAME_SIZE );
+        p_aout_buffer = aout_DecNewBuffer( p_a52dec->p_aout,
+                                           p_a52dec->p_aout_input,
+                                           A52DEC_FRAME_SIZE );
         if( !p_aout_buffer )
         {
             msg_Err( p_a52dec->p_fifo, "cannot get aout buffer" );
@@ -215,14 +215,14 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
         if (decode_frame (p_a52dec, (s16*)p_aout_buffer->p_buffer))
         {
             b_sync = 0;
-            aout_BufferDelete( p_a52dec->p_aout, p_a52dec->p_aout_input,
-                                                 p_aout_buffer );
+            aout_DecDeleteBuffer( p_a52dec->p_aout, p_a52dec->p_aout_input,
+                                  p_aout_buffer );
             continue;
         }
         else
         {
-            aout_BufferPlay( p_a52dec->p_aout, p_a52dec->p_aout_input,
-                                               p_aout_buffer );
+            aout_DecPlay( p_a52dec->p_aout, p_a52dec->p_aout_input,
+                          p_aout_buffer );
         }
 
         RealignBits(&p_a52dec->bit_stream);
@@ -344,7 +344,7 @@ static void EndThread (a52dec_t * p_a52dec)
     /* If the audio output fifo was created, we destroy it */
     if( p_a52dec->p_aout_input )
     {
-        aout_InputDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
+        aout_DecDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
     }
 
     /* Free allocated structures */
index 4add301..f95e00b 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: AAC decoder using libfaad2
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: decoder.c,v 1.2 2002/08/23 14:05:22 sam Exp $
+ * $Id: decoder.c,v 1.3 2002/09/26 22:40:21 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *      
@@ -447,15 +447,15 @@ static void DecodeThread( adec_thread_t *p_adec )
         if( p_adec->p_aout_input )
         {
             /* **** Delete the old **** */
-            aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
+            aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
         }
 
         /* **** Create a new audio output **** */
         p_adec->output_format.i_channels = faad_frame.channels;
         aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
-        p_adec->p_aout_input = aout_InputNew( p_adec->p_fifo,
-                                              &p_adec->p_aout,
-                                              &p_adec->output_format );
+        p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
+                                            &p_adec->p_aout,
+                                            &p_adec->output_format );
     }
 
     if( !p_adec->p_aout_input )
@@ -473,9 +473,9 @@ static void DecodeThread( adec_thread_t *p_adec )
         return;
     }
 
-    p_aout_buffer = aout_BufferNew( p_adec->p_aout, 
-                                    p_adec->p_aout_input,
-                                    faad_frame.samples / faad_frame.channels );
+    p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout, 
+                                       p_adec->p_aout_input,
+                                       faad_frame.samples / faad_frame.channels );
     if( !p_aout_buffer )
     {
         msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
@@ -490,7 +490,7 @@ static void DecodeThread( adec_thread_t *p_adec )
             p_faad_buffer,
             p_aout_buffer->i_nb_bytes );
 
-    aout_BufferPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
+    aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
 }
 
 
@@ -501,7 +501,7 @@ static void EndThread (adec_thread_t *p_adec)
 {
     if( p_adec->p_aout_input )
     {
-        aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
+        aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
     }
 
     if( p_adec->p_handle )
index 696245d..69782e6 100644 (file)
@@ -2,7 +2,7 @@
  * lpcm.c: lpcm decoder module
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.1 2002/09/20 23:27:03 massiot Exp $
+ * $Id: lpcm.c,v 1.2 2002/09/26 22:40:20 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Henri Fallon <henri@videolan.org>
@@ -131,9 +131,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
     p_dec->output_format.i_rate = 48000;
     
     aout_DateInit( &p_dec->end_date, 48000 );
-    p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
-                                         &p_dec->p_aout,
-                                         &p_dec->output_format );
+    p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
+                                       &p_dec->p_aout,
+                                       &p_dec->output_format );
 
     if ( p_dec->p_aout_input == NULL )
     {
@@ -175,9 +175,9 @@ void DecodeFrame( dec_thread_t * p_dec )
         aout_DateSet( &p_dec->end_date, i_pts );
     }
     
-    p_aout_buffer = aout_BufferNew( p_dec->p_aout,
-                                  p_dec->p_aout_input,
-                                  LPCM_FRAME_NB );
+    p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
+                                       p_dec->p_aout_input,
+                                       LPCM_FRAME_NB );
     
     if( !p_aout_buffer )
     {
@@ -200,13 +200,13 @@ void DecodeFrame( dec_thread_t * p_dec )
 
     if( p_dec->p_fifo->b_die )
     {
-        aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
-                           p_aout_buffer );
+        aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
+                              p_aout_buffer );
         return;
     }
 
-    aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, 
-                     p_aout_buffer );
+    aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, 
+                  p_aout_buffer );
 }
 
 /*****************************************************************************
@@ -216,7 +216,7 @@ static void EndThread( dec_thread_t * p_dec )
 {
     if( p_dec->p_aout_input != NULL )
     {
-        aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
     }
 
     free( p_dec );
index ad4b48e..17894e5 100644 (file)
@@ -155,7 +155,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
            || p_dec->output_format.i_channels != p_pcm->channels) )
     {
         /* Parameters changed - this should not happen. */
-        aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
         p_dec->p_aout_input = NULL;
     }
 
@@ -165,9 +165,9 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
         p_dec->output_format.i_rate = p_pcm->samplerate;
         p_dec->output_format.i_channels = p_pcm->channels;
         aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
-        p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
-                                             &p_dec->p_aout,
-                                             &p_dec->output_format );
+        p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
+                                           &p_dec->p_aout,
+                                           &p_dec->output_format );
 
         if ( p_dec->p_aout_input == NULL )
         {
@@ -199,7 +199,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
         return MAD_FLOW_CONTINUE;
     }
 
-    p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input, i_samples );
+    p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input, i_samples );
 
     if ( p_buffer == NULL )
     {
@@ -233,7 +233,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
                                 p_pcm->channels );
     }
 
-    aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
+    aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
 
     return MAD_FLOW_CONTINUE;
 }
index 5aad370..413168b 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: MPEG audio decoder thread
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: decoder.c,v 1.3 2002/08/26 23:00:22 massiot Exp $
+ * $Id: decoder.c,v 1.4 2002/09/26 22:40:23 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Michel Lespinasse <walken@via.ecp.fr>
@@ -174,7 +174,7 @@ static void DecodeThread( adec_thread_t * p_dec )
             {
                 /* Delete old output */
                 msg_Warn( p_dec->p_fifo, "opening a new aout" );
-                aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+                aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
             }
 
             /* Set output configuration */
@@ -182,9 +182,9 @@ static void DecodeThread( adec_thread_t * p_dec )
             p_dec->output_format.i_channels = ( sync_info.b_stereo ? 2 : 1 );
             p_dec->output_format.i_rate     = sync_info.sample_rate;
             aout_DateInit( &p_dec->end_date, sync_info.sample_rate );
-            p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
-                                                  &p_dec->p_aout,
-                                                  &p_dec->output_format );
+            p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
+                                               &p_dec->p_aout,
+                                               &p_dec->output_format );
         }
 
         if( p_dec->p_aout_input == NULL )
@@ -200,9 +200,9 @@ static void DecodeThread( adec_thread_t * p_dec )
             return;
         }
 
-        p_aout_buffer = aout_BufferNew( p_dec->p_aout,
-                                        p_dec->p_aout_input,
-                                        ADEC_FRAME_NB );
+        p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
+                                           p_dec->p_aout_input,
+                                           ADEC_FRAME_NB );
         if( !p_aout_buffer )
         {
             msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
@@ -216,11 +216,11 @@ static void DecodeThread( adec_thread_t * p_dec )
         if( adec_DecodeFrame (p_dec, (float*)p_aout_buffer->p_buffer ) )
         {
             /* Ouch, failed decoding... We'll have to resync */
-            aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
+            aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
         }
         else
         {
-            aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
+            aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
         }
     }
 }
@@ -236,7 +236,7 @@ static void EndThread ( adec_thread_t *p_dec )
     /* If the audio output fifo was created, we destroy it */
     if( p_dec->p_aout_input )
     {
-        aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+        aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
         
     }
 
index 748f0eb..13b0a28 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg_ts.c : Transport Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: ts.c,v 1.5 2002/09/23 23:05:58 massiot Exp $
+ * $Id: ts.c,v 1.6 2002/09/26 22:40:24 massiot Exp $
  *
  * Authors: Henri Fallon <henri@via.ecp.fr>
  *          Johan Bilien <jobi@via.ecp.fr>
@@ -907,7 +907,6 @@ void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt )
                     p_new_es->i_stream_id = 0xBD;
                     break;
                 case DVD_SPU_ES:
-                case A52_AUDIO_ES:
                     if ( !b_vls_compat )
                         p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
                     else
diff --git a/src/audio_output/audio_output.c b/src/audio_output/audio_output.c
deleted file mode 100644 (file)
index c9d4b86..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/*****************************************************************************
- * audio_output.c : audio output instance miscellaneous functions
- *****************************************************************************
- * Copyright (C) 2002 VideoLAN
- * $Id: audio_output.c,v 1.103 2002/09/20 23:27:04 massiot Exp $
- *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                            /* calloc(), malloc(), free() */
-#include <string.h>
-
-#include <vlc/vlc.h>
-
-#ifdef HAVE_ALLOCA_H
-#   include <alloca.h>
-#endif
-
-#include "audio_output.h"
-#include "aout_internal.h"
-
-/*
- * Instances management (see also input.c:aout_InputNew())
- */
-
-/*****************************************************************************
- * aout_NewInstance: initialize aout structure
- *****************************************************************************/
-aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent )
-{
-    aout_instance_t * p_aout;
-
-    /* Allocate descriptor. */
-    p_aout = vlc_object_create( p_parent, VLC_OBJECT_AOUT );
-    if( p_aout == NULL )
-    {
-        return NULL;
-    }
-
-    /* Initialize members. */
-    vlc_mutex_init( p_parent, &p_aout->input_fifos_lock );
-    vlc_mutex_init( p_parent, &p_aout->mixer_lock );
-    vlc_mutex_init( p_parent, &p_aout->output_fifo_lock );
-    p_aout->i_nb_inputs = 0;
-    p_aout->mixer.f_multiplier = 1.0;
-
-    vlc_object_attach( p_aout, p_parent->p_vlc );
-
-    return p_aout;
-}
-
-/*****************************************************************************
- * aout_DeleteInstance: destroy aout structure
- *****************************************************************************/
-void aout_DeleteInstance( aout_instance_t * p_aout )
-{
-    vlc_mutex_destroy( &p_aout->input_fifos_lock );
-    vlc_mutex_destroy( &p_aout->mixer_lock );
-    vlc_mutex_destroy( &p_aout->output_fifo_lock );
-
-    /* Free structure. */
-    vlc_object_destroy( p_aout );
-}
-
-
-/*
- * Buffer management (interface to the decoders)
- */
-
-/*****************************************************************************
- * aout_BufferNew : ask for a new empty buffer
- *****************************************************************************/
-aout_buffer_t * aout_BufferNew( aout_instance_t * p_aout,
-                                aout_input_t * p_input,
-                                size_t i_nb_samples )
-{
-    aout_buffer_t * p_buffer;
-    mtime_t duration = (1000000 * (mtime_t)i_nb_samples)
-                        / p_input->input.i_rate;
-
-    /* This necessarily allocates in the heap. */
-    aout_BufferAlloc( &p_input->input_alloc, duration, NULL, p_buffer );
-    p_buffer->i_nb_samples = i_nb_samples;
-    p_buffer->i_nb_bytes = i_nb_samples * p_input->input.i_bytes_per_frame
-                              / p_input->input.i_frame_length;
-
-    if ( p_buffer == NULL )
-    {
-        msg_Err( p_aout, "NULL buffer !" );
-    }
-    else
-    {
-        p_buffer->start_date = p_buffer->end_date = 0;
-    }
-
-    return p_buffer;
-}
-
-/*****************************************************************************
- * aout_BufferDelete : destroy an undecoded buffer
- *****************************************************************************/
-void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input,
-                        aout_buffer_t * p_buffer )
-{
-    aout_BufferFree( p_buffer );
-}
-
-/*****************************************************************************
- * aout_BufferPlay : filter & mix the decoded buffer
- *****************************************************************************/
-int aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                     aout_buffer_t * p_buffer )
-{
-    if ( p_buffer->start_date == 0 )
-    {
-        msg_Warn( p_aout, "non-dated buffer received" );
-        aout_BufferFree( p_buffer );
-    }
-    else
-    {
-        p_buffer->end_date = p_buffer->start_date
-                                + (mtime_t)(p_buffer->i_nb_samples * 1000000)
-                                    / p_input->input.i_rate;
-    }
-
-    /* If the buffer is too early, wait a while. */
-    mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME );
-
-    if ( aout_InputPlay( p_aout, p_input, p_buffer ) == -1 ) return -1;
-
-    /* Run the mixer if it is able to run. */
-    aout_MixerRun( p_aout );
-}
-
-
-/*
- * Formats management
- */
-
-/*****************************************************************************
- * aout_FormatNbChannels : return the number of channels
- *****************************************************************************/
-int aout_FormatNbChannels( audio_sample_format_t * p_format )
-{
-    int i_nb;
-
-    switch ( p_format->i_channels & AOUT_CHAN_MASK )
-    {
-    case AOUT_CHAN_CHANNEL1:
-    case AOUT_CHAN_CHANNEL2:
-    case AOUT_CHAN_MONO:
-        i_nb = 1;
-        break;
-
-    case AOUT_CHAN_CHANNEL:
-    case AOUT_CHAN_STEREO:
-    case AOUT_CHAN_DOLBY:
-        i_nb = 2;
-        break;
-
-    case AOUT_CHAN_3F:
-    case AOUT_CHAN_2F1R:
-        i_nb = 3;
-        break;
-
-    case AOUT_CHAN_3F1R:
-    case AOUT_CHAN_2F2R:
-        i_nb = 4;
-        break;
-
-    case AOUT_CHAN_3F2R:
-        i_nb = 5;
-        break;
-
-    default:
-        i_nb = 0;
-    }
-
-    if ( p_format->i_channels & AOUT_CHAN_LFE )
-        return i_nb + 1;
-    else
-        return i_nb;
-}
-
-/*****************************************************************************
- * aout_FormatPrepare : compute the number of bytes per frame & frame length
- *****************************************************************************/
-void aout_FormatPrepare( audio_sample_format_t * p_format )
-{
-    int i_result;
-
-    switch ( p_format->i_format )
-    {
-    case AOUT_FMT_U8:
-    case AOUT_FMT_S8:
-        i_result = 1;
-        break;
-
-    case AOUT_FMT_U16_LE:
-    case AOUT_FMT_U16_BE:
-    case AOUT_FMT_S16_LE:
-    case AOUT_FMT_S16_BE:
-        i_result = 2;
-        break;
-
-    case AOUT_FMT_FLOAT32:
-    case AOUT_FMT_FIXED32:
-        i_result = 4;
-        break;
-
-    case AOUT_FMT_SPDIF:
-    case AOUT_FMT_A52:
-    case AOUT_FMT_DTS:
-        /* For these formats the caller has to indicate the parameters
-         * by hand. */
-        return;
-
-    default:
-        i_result = 0; /* will segfault much sooner... */
-    }
-
-    p_format->i_bytes_per_frame = i_result * aout_FormatNbChannels( p_format );
-    p_format->i_frame_length = 1;
-}
-
-
-/*
- * FIFO management (internal) - please understand that solving race conditions
- * is _your_ job, ie. in the audio output you should own the mixer lock
- * before calling any of these functions.
- */
-
-/*****************************************************************************
- * aout_FifoInit : initialize the members of a FIFO
- *****************************************************************************/
-void aout_FifoInit( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
-                    u32 i_rate )
-{
-    p_fifo->p_first = NULL;
-    p_fifo->pp_last = &p_fifo->p_first;
-    aout_DateInit( &p_fifo->end_date, i_rate );
-}
-
-/*****************************************************************************
- * aout_FifoPush : push a packet into the FIFO
- *****************************************************************************/
-void aout_FifoPush( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
-                    aout_buffer_t * p_buffer )
-{
-    *p_fifo->pp_last = p_buffer;
-    p_fifo->pp_last = &p_buffer->p_next;
-    *p_fifo->pp_last = NULL;
-    /* Enforce the continuity of the stream. */
-    if ( aout_DateGet( &p_fifo->end_date ) )
-    {
-        p_buffer->start_date = aout_DateGet( &p_fifo->end_date );
-        p_buffer->end_date = aout_DateIncrement( &p_fifo->end_date,
-                                                 p_buffer->i_nb_samples ); 
-    }
-    else
-    {
-        aout_DateSet( &p_fifo->end_date, p_buffer->end_date );
-    }
-}
-
-/*****************************************************************************
- * aout_FifoSet : set end_date and trash all buffers (because they aren't
- * properly dated)
- *****************************************************************************/
-void aout_FifoSet( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
-                   mtime_t date )
-{
-    aout_buffer_t * p_buffer;
-
-    aout_DateSet( &p_fifo->end_date, date );
-    p_buffer = p_fifo->p_first;
-    while ( p_buffer != NULL )
-    {
-        aout_buffer_t * p_next = p_buffer->p_next;
-        aout_BufferFree( p_buffer );
-        p_buffer = p_next;
-    }
-    p_fifo->p_first = NULL;
-    p_fifo->pp_last = &p_fifo->p_first;
-}
-
-/*****************************************************************************
- * aout_FifoMoveDates : Move forwards or backwards all dates in the FIFO
- *****************************************************************************/
-void aout_FifoMoveDates( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
-                         mtime_t difference )
-{
-    aout_buffer_t * p_buffer;
-
-    aout_DateMove( &p_fifo->end_date, difference );
-    p_buffer = p_fifo->p_first;
-    while ( p_buffer != NULL )
-    {
-        p_buffer->start_date += difference;
-        p_buffer->end_date += difference;
-        p_buffer = p_buffer->p_next;
-    }
-}
-
-/*****************************************************************************
- * aout_FifoNextStart : return the current end_date
- *****************************************************************************/
-mtime_t aout_FifoNextStart( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
-{
-    return aout_DateGet( &p_fifo->end_date );
-}
-
-/*****************************************************************************
- * aout_FifoPop : get the next buffer out of the FIFO
- *****************************************************************************/
-aout_buffer_t * aout_FifoPop( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
-{
-    aout_buffer_t * p_buffer;
-    p_buffer = p_fifo->p_first;
-    if ( p_buffer == NULL ) return NULL;
-    p_fifo->p_first = p_buffer->p_next;
-    if ( p_fifo->p_first == NULL )
-    {
-        p_fifo->pp_last = &p_fifo->p_first;
-    }
-
-    return p_buffer;
-}
-
-/*****************************************************************************
- * aout_FifoDestroy : destroy a FIFO and its buffers
- *****************************************************************************/
-void aout_FifoDestroy( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
-{
-    aout_buffer_t * p_buffer;
-
-    p_buffer = p_fifo->p_first;
-    while ( p_buffer != NULL )
-    {
-        aout_buffer_t * p_next = p_buffer->p_next;
-        aout_BufferFree( p_buffer );
-        p_buffer = p_next;
-    }
-}
-
-
-/*
- * Date management (internal and external)
- */
-
-/*****************************************************************************
- * aout_DateInit : set the divider of an audio_date_t
- *****************************************************************************/
-void aout_DateInit( audio_date_t * p_date, u32 i_divider )
-{
-    p_date->date = 0;
-    p_date->i_divider = i_divider;
-    p_date->i_remainder = 0;
-}
-
-/*****************************************************************************
- * aout_DateSet : set the date of an audio_date_t
- *****************************************************************************/
-void aout_DateSet( audio_date_t * p_date, mtime_t new_date )
-{
-    p_date->date = new_date;
-    p_date->i_remainder = 0;
-}
-
-/*****************************************************************************
- * aout_DateMove : move forwards or backwards the date of an audio_date_t
- *****************************************************************************/
-void aout_DateMove( audio_date_t * p_date, mtime_t difference )
-{
-    p_date->date += difference;
-}
-
-/*****************************************************************************
- * aout_DateGet : get the date of an audio_date_t
- *****************************************************************************/
-mtime_t aout_DateGet( const audio_date_t * p_date )
-{
-    return p_date->date;
-}
-
-/*****************************************************************************
- * aout_DateIncrement : increment the date and return the result, taking
- * into account rounding errors
- *****************************************************************************/
-mtime_t aout_DateIncrement( audio_date_t * p_date, u32 i_nb_samples )
-{
-    mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000;
-    p_date->date += i_dividend / p_date->i_divider;
-    p_date->i_remainder += i_dividend % p_date->i_divider;
-    if ( p_date->i_remainder >= p_date->i_divider )
-    {
-        /* This is Bresenham algorithm. */
-        p_date->date++;
-        p_date->i_remainder -= p_date->i_divider;
-    }
-    return p_date->date;
-}
-
diff --git a/src/audio_output/common.c b/src/audio_output/common.c
new file mode 100644 (file)
index 0000000..1bccddc
--- /dev/null
@@ -0,0 +1,348 @@
+/*****************************************************************************
+ * common.c : audio output management of common data structures
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: common.c,v 1.1 2002/09/26 22:40:25 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                            /* calloc(), malloc(), free() */
+#include <string.h>
+
+#include <vlc/vlc.h>
+
+#include "audio_output.h"
+#include "aout_internal.h"
+
+
+/*
+ * Instances management (internal and external)
+ */
+
+/*****************************************************************************
+ * aout_New: initialize aout structure
+ *****************************************************************************/
+aout_instance_t * __aout_New( vlc_object_t * p_parent )
+{
+    aout_instance_t * p_aout;
+
+    /* Allocate descriptor. */
+    p_aout = vlc_object_create( p_parent, VLC_OBJECT_AOUT );
+    if( p_aout == NULL )
+    {
+        return NULL;
+    }
+
+    /* Initialize members. */
+    vlc_mutex_init( p_parent, &p_aout->input_fifos_lock );
+    vlc_mutex_init( p_parent, &p_aout->mixer_lock );
+    vlc_mutex_init( p_parent, &p_aout->output_fifo_lock );
+    p_aout->i_nb_inputs = 0;
+    p_aout->mixer.f_multiplier = 1.0;
+    p_aout->mixer.b_error = 1;
+
+    vlc_object_attach( p_aout, p_parent->p_vlc );
+
+    return p_aout;
+}
+
+/*****************************************************************************
+ * aout_Delete: destroy aout structure
+ *****************************************************************************/
+void aout_Delete( aout_instance_t * p_aout )
+{
+    vlc_mutex_destroy( &p_aout->input_fifos_lock );
+    vlc_mutex_destroy( &p_aout->mixer_lock );
+    vlc_mutex_destroy( &p_aout->output_fifo_lock );
+
+    /* Free structure. */
+    vlc_object_destroy( p_aout );
+}
+
+
+/*
+ * Formats management (internal and external)
+ */
+
+/*****************************************************************************
+ * aout_FormatNbChannels : return the number of channels
+ *****************************************************************************/
+int aout_FormatNbChannels( audio_sample_format_t * p_format )
+{
+    int i_nb;
+
+    switch ( p_format->i_channels & AOUT_CHAN_MASK )
+    {
+    case AOUT_CHAN_CHANNEL1:
+    case AOUT_CHAN_CHANNEL2:
+    case AOUT_CHAN_MONO:
+        i_nb = 1;
+        break;
+
+    case AOUT_CHAN_CHANNEL:
+    case AOUT_CHAN_STEREO:
+    case AOUT_CHAN_DOLBY:
+        i_nb = 2;
+        break;
+
+    case AOUT_CHAN_3F:
+    case AOUT_CHAN_2F1R:
+        i_nb = 3;
+        break;
+
+    case AOUT_CHAN_3F1R:
+    case AOUT_CHAN_2F2R:
+        i_nb = 4;
+        break;
+
+    case AOUT_CHAN_3F2R:
+        i_nb = 5;
+        break;
+
+    default:
+        i_nb = 0;
+    }
+
+    if ( p_format->i_channels & AOUT_CHAN_LFE )
+        return i_nb + 1;
+    else
+        return i_nb;
+}
+
+/*****************************************************************************
+ * aout_FormatPrepare : compute the number of bytes per frame & frame length
+ *****************************************************************************/
+void aout_FormatPrepare( audio_sample_format_t * p_format )
+{
+    int i_result;
+
+    switch ( p_format->i_format )
+    {
+    case AOUT_FMT_U8:
+    case AOUT_FMT_S8:
+        i_result = 1;
+        break;
+
+    case AOUT_FMT_U16_LE:
+    case AOUT_FMT_U16_BE:
+    case AOUT_FMT_S16_LE:
+    case AOUT_FMT_S16_BE:
+        i_result = 2;
+        break;
+
+    case AOUT_FMT_FLOAT32:
+    case AOUT_FMT_FIXED32:
+        i_result = 4;
+        break;
+
+    case AOUT_FMT_SPDIF:
+    case AOUT_FMT_A52:
+    case AOUT_FMT_DTS:
+        /* For these formats the caller has to indicate the parameters
+         * by hand. */
+        return;
+
+    default:
+        i_result = 0; /* will segfault much sooner... */
+    }
+
+    p_format->i_bytes_per_frame = i_result * aout_FormatNbChannels( p_format );
+    p_format->i_frame_length = 1;
+}
+
+
+/*
+ * FIFO management (internal) - please understand that solving race conditions
+ * is _your_ job, ie. in the audio output you should own the mixer lock
+ * before calling any of these functions.
+ */
+
+/*****************************************************************************
+ * aout_FifoInit : initialize the members of a FIFO
+ *****************************************************************************/
+void aout_FifoInit( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
+                    u32 i_rate )
+{
+    p_fifo->p_first = NULL;
+    p_fifo->pp_last = &p_fifo->p_first;
+    aout_DateInit( &p_fifo->end_date, i_rate );
+}
+
+/*****************************************************************************
+ * aout_FifoPush : push a packet into the FIFO
+ *****************************************************************************/
+void aout_FifoPush( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
+                    aout_buffer_t * p_buffer )
+{
+    *p_fifo->pp_last = p_buffer;
+    p_fifo->pp_last = &p_buffer->p_next;
+    *p_fifo->pp_last = NULL;
+    /* Enforce the continuity of the stream. */
+    if ( aout_DateGet( &p_fifo->end_date ) )
+    {
+        p_buffer->start_date = aout_DateGet( &p_fifo->end_date );
+        p_buffer->end_date = aout_DateIncrement( &p_fifo->end_date,
+                                                 p_buffer->i_nb_samples ); 
+    }
+    else
+    {
+        aout_DateSet( &p_fifo->end_date, p_buffer->end_date );
+    }
+}
+
+/*****************************************************************************
+ * aout_FifoSet : set end_date and trash all buffers (because they aren't
+ * properly dated)
+ *****************************************************************************/
+void aout_FifoSet( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
+                   mtime_t date )
+{
+    aout_buffer_t * p_buffer;
+
+    aout_DateSet( &p_fifo->end_date, date );
+    p_buffer = p_fifo->p_first;
+    while ( p_buffer != NULL )
+    {
+        aout_buffer_t * p_next = p_buffer->p_next;
+        aout_BufferFree( p_buffer );
+        p_buffer = p_next;
+    }
+    p_fifo->p_first = NULL;
+    p_fifo->pp_last = &p_fifo->p_first;
+}
+
+/*****************************************************************************
+ * aout_FifoMoveDates : Move forwards or backwards all dates in the FIFO
+ *****************************************************************************/
+void aout_FifoMoveDates( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
+                         mtime_t difference )
+{
+    aout_buffer_t * p_buffer;
+
+    aout_DateMove( &p_fifo->end_date, difference );
+    p_buffer = p_fifo->p_first;
+    while ( p_buffer != NULL )
+    {
+        p_buffer->start_date += difference;
+        p_buffer->end_date += difference;
+        p_buffer = p_buffer->p_next;
+    }
+}
+
+/*****************************************************************************
+ * aout_FifoNextStart : return the current end_date
+ *****************************************************************************/
+mtime_t aout_FifoNextStart( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
+{
+    return aout_DateGet( &p_fifo->end_date );
+}
+
+/*****************************************************************************
+ * aout_FifoPop : get the next buffer out of the FIFO
+ *****************************************************************************/
+aout_buffer_t * aout_FifoPop( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
+{
+    aout_buffer_t * p_buffer;
+    p_buffer = p_fifo->p_first;
+    if ( p_buffer == NULL ) return NULL;
+    p_fifo->p_first = p_buffer->p_next;
+    if ( p_fifo->p_first == NULL )
+    {
+        p_fifo->pp_last = &p_fifo->p_first;
+    }
+
+    return p_buffer;
+}
+
+/*****************************************************************************
+ * aout_FifoDestroy : destroy a FIFO and its buffers
+ *****************************************************************************/
+void aout_FifoDestroy( aout_instance_t * p_aout, aout_fifo_t * p_fifo )
+{
+    aout_buffer_t * p_buffer;
+
+    p_buffer = p_fifo->p_first;
+    while ( p_buffer != NULL )
+    {
+        aout_buffer_t * p_next = p_buffer->p_next;
+        aout_BufferFree( p_buffer );
+        p_buffer = p_next;
+    }
+}
+
+
+/*
+ * Date management (internal and external)
+ */
+
+/*****************************************************************************
+ * aout_DateInit : set the divider of an audio_date_t
+ *****************************************************************************/
+void aout_DateInit( audio_date_t * p_date, u32 i_divider )
+{
+    p_date->date = 0;
+    p_date->i_divider = i_divider;
+    p_date->i_remainder = 0;
+}
+
+/*****************************************************************************
+ * aout_DateSet : set the date of an audio_date_t
+ *****************************************************************************/
+void aout_DateSet( audio_date_t * p_date, mtime_t new_date )
+{
+    p_date->date = new_date;
+    p_date->i_remainder = 0;
+}
+
+/*****************************************************************************
+ * aout_DateMove : move forwards or backwards the date of an audio_date_t
+ *****************************************************************************/
+void aout_DateMove( audio_date_t * p_date, mtime_t difference )
+{
+    p_date->date += difference;
+}
+
+/*****************************************************************************
+ * aout_DateGet : get the date of an audio_date_t
+ *****************************************************************************/
+mtime_t aout_DateGet( const audio_date_t * p_date )
+{
+    return p_date->date;
+}
+
+/*****************************************************************************
+ * aout_DateIncrement : increment the date and return the result, taking
+ * into account rounding errors
+ *****************************************************************************/
+mtime_t aout_DateIncrement( audio_date_t * p_date, u32 i_nb_samples )
+{
+    mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000;
+    p_date->date += i_dividend / p_date->i_divider;
+    p_date->i_remainder += i_dividend % p_date->i_divider;
+    if ( p_date->i_remainder >= p_date->i_divider )
+    {
+        /* This is Bresenham algorithm. */
+        p_date->date++;
+        p_date->i_remainder -= p_date->i_divider;
+    }
+    return p_date->date;
+}
+
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
new file mode 100644 (file)
index 0000000..7824b86
--- /dev/null
@@ -0,0 +1,321 @@
+/*****************************************************************************
+ * dec.c : audio output API towards decoders
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: dec.c,v 1.1 2002/09/26 22:40:25 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                            /* calloc(), malloc(), free() */
+#include <string.h>
+
+#include <vlc/vlc.h>
+
+#ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#endif
+
+#include "audio_output.h"
+#include "aout_internal.h"
+
+/*
+ * Creation/Deletion
+ */
+
+/*****************************************************************************
+ * aout_DecNew : create a decoder
+ *****************************************************************************/
+static aout_input_t * DecNew( aout_instance_t * p_aout,
+                              audio_sample_format_t * p_format )
+{
+    aout_input_t * p_input;
+
+    /* We can only be called by the decoder, so no need to lock
+     * p_input->lock. */
+    vlc_mutex_lock( &p_aout->mixer_lock );
+
+    if ( p_aout->i_nb_inputs >= AOUT_MAX_INPUTS )
+    {
+        msg_Err( p_aout, "too many inputs already (%d)", p_aout->i_nb_inputs );
+        return NULL;
+    }
+
+    p_input = malloc(sizeof(aout_input_t));
+    if ( p_input == NULL )
+    {
+        msg_Err( p_aout, "out of memory" );
+        return NULL;
+    }
+
+    vlc_mutex_init( p_aout, &p_input->lock );
+
+    p_input->b_changed = 0;
+    p_input->b_error = 1;
+    memcpy( &p_input->input, p_format,
+            sizeof(audio_sample_format_t) );
+    aout_FormatPrepare( &p_input->input );
+
+    p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input;
+    p_aout->i_nb_inputs++;
+
+    if ( p_aout->mixer.b_error )
+    {
+        int i;
+
+        /* Recreate the output using the new format. */
+        if ( aout_OutputNew( p_aout, p_format ) < 0 )
+        {
+            for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
+            {
+                vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+                aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
+                vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+            }
+            vlc_mutex_unlock( &p_aout->mixer_lock );
+            return p_input;
+        }
+
+        /* Create other input streams. */
+        for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
+        {
+            vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+            aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
+            aout_InputNew( p_aout, p_aout->pp_inputs[i] );
+            vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+        }
+    }
+    else
+    {
+        aout_MixerDelete( p_aout );
+    }
+
+    if ( aout_MixerNew( p_aout ) == -1 )
+    {
+        aout_OutputDelete( p_aout );
+        vlc_mutex_unlock( &p_aout->mixer_lock );
+        return NULL;
+    }
+
+    aout_MixerNew( p_aout );
+
+    aout_InputNew( p_aout, p_input );
+
+    vlc_mutex_unlock( &p_aout->mixer_lock );
+
+    return p_input;
+}
+
+aout_input_t * __aout_DecNew( vlc_object_t * p_this,
+                              aout_instance_t ** pp_aout,
+                              audio_sample_format_t * p_format )
+{
+    if ( *pp_aout == NULL )
+    {
+        /* Create an audio output if there is none. */
+        *pp_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+
+        if( *pp_aout == NULL )
+        {
+            msg_Dbg( p_this, "no aout present, spawning one" );
+
+            *pp_aout = aout_New( p_this );
+            /* Everything failed, I'm a loser, I just wanna die */
+            if( *pp_aout == NULL )
+            {
+                return NULL;
+            }
+        }
+        else
+        {
+            vlc_object_release( *pp_aout );
+        }
+    }
+
+    return DecNew( *pp_aout, p_format );
+}
+
+/*****************************************************************************
+ * aout_DecDelete : delete a decoder
+ *****************************************************************************/
+int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input )
+{
+    int i_input;
+
+    /* This function can only be called by the decoder itself, so no need
+     * to lock p_input->lock. */
+    vlc_mutex_lock( &p_aout->mixer_lock );
+
+    for ( i_input = 0; i_input < p_aout->i_nb_inputs; i_input++ )
+    {
+        if ( p_aout->pp_inputs[i_input] == p_input )
+        {
+            break;
+        }
+    }
+
+    if ( i_input == p_aout->i_nb_inputs )
+    {
+        msg_Err( p_aout, "cannot find an input to delete" );
+        return -1;
+    }
+
+    /* Remove the input from the list. */
+    memmove( &p_aout->pp_inputs[i_input], &p_aout->pp_inputs[i_input + 1],
+             (AOUT_MAX_INPUTS - i_input - 1) * sizeof(aout_input_t *) );
+    p_aout->i_nb_inputs--;
+
+    aout_InputDelete( p_aout, p_input );
+
+    vlc_mutex_destroy( &p_input->lock );
+    free( p_input );
+
+    if ( !p_aout->i_nb_inputs )
+    {
+        aout_OutputDelete( p_aout );
+        aout_MixerDelete( p_aout );
+    }
+
+    vlc_mutex_unlock( &p_aout->mixer_lock );
+
+    return 0;
+}
+
+
+/*
+ * Buffer management
+ */
+
+/*****************************************************************************
+ * aout_DecNewBuffer : ask for a new empty buffer
+ *****************************************************************************/
+aout_buffer_t * aout_DecNewBuffer( aout_instance_t * p_aout,
+                                   aout_input_t * p_input,
+                                   size_t i_nb_samples )
+{
+    aout_buffer_t * p_buffer;
+    mtime_t duration;
+
+    vlc_mutex_lock( &p_input->lock );
+
+    if ( p_input->b_error )
+    {
+        vlc_mutex_unlock( &p_input->lock );
+        return NULL;
+    }
+
+    duration = (1000000 * (mtime_t)i_nb_samples) / p_input->input.i_rate;
+
+    /* This necessarily allocates in the heap. */
+    aout_BufferAlloc( &p_input->input_alloc, duration, NULL, p_buffer );
+    p_buffer->i_nb_samples = i_nb_samples;
+    p_buffer->i_nb_bytes = i_nb_samples * p_input->input.i_bytes_per_frame
+                              / p_input->input.i_frame_length;
+
+    /* Suppose the decoder doesn't have more than one buffered buffer */
+    p_input->b_changed = 0;
+
+    vlc_mutex_unlock( &p_input->lock );
+
+    if ( p_buffer == NULL )
+    {
+        msg_Err( p_aout, "NULL buffer !" );
+    }
+    else
+    {
+        p_buffer->start_date = p_buffer->end_date = 0;
+    }
+
+    return p_buffer;
+}
+
+/*****************************************************************************
+ * aout_DecDeleteBuffer : destroy an undecoded buffer
+ *****************************************************************************/
+void aout_DecDeleteBuffer( aout_instance_t * p_aout, aout_input_t * p_input,
+                           aout_buffer_t * p_buffer )
+{
+    aout_BufferFree( p_buffer );
+}
+
+/*****************************************************************************
+ * aout_DecPlay : filter & mix the decoded buffer
+ *****************************************************************************/
+int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
+                  aout_buffer_t * p_buffer )
+{
+    if ( p_buffer->start_date == 0 )
+    {
+        msg_Warn( p_aout, "non-dated buffer received" );
+        aout_BufferFree( p_buffer );
+        return -1;
+    }
+
+    p_buffer->end_date = p_buffer->start_date
+                            + (mtime_t)(p_buffer->i_nb_samples * 1000000)
+                                / p_input->input.i_rate;
+
+    vlc_mutex_lock( &p_input->lock );
+
+    if ( p_input->b_error )
+    {
+        vlc_mutex_unlock( &p_input->lock );
+        aout_BufferFree( p_buffer );
+        return -1;
+    }
+
+    if ( p_input->b_changed )
+    {
+        /* Maybe the allocation size has changed. Re-allocate a buffer. */
+        aout_buffer_t * p_new_buffer;
+        mtime_t duration = (1000000 * (mtime_t)p_buffer->i_nb_samples)
+                            / p_input->input.i_rate;
+
+        aout_BufferAlloc( &p_input->input_alloc, duration, NULL, p_new_buffer );
+        p_aout->p_vlc->pf_memcpy( p_new_buffer->p_buffer, p_buffer->p_buffer,
+                                  p_buffer->i_nb_bytes );
+        p_new_buffer->i_nb_samples = p_buffer->i_nb_samples;
+        p_new_buffer->i_nb_bytes = p_buffer->i_nb_bytes;
+        p_new_buffer->start_date = p_buffer->start_date;
+        p_new_buffer->end_date = p_buffer->end_date;
+        aout_BufferFree( p_buffer );
+        p_buffer = p_new_buffer;
+        p_input->b_changed = 0;
+    }
+
+    /* If the buffer is too early, wait a while. */
+    mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME );
+
+    if ( aout_InputPlay( p_aout, p_input, p_buffer ) == -1 )
+    {
+        vlc_mutex_unlock( &p_input->lock );
+        return -1;
+    }
+
+    vlc_mutex_unlock( &p_input->lock );
+
+    /* Run the mixer if it is able to run. */
+    vlc_mutex_lock( &p_aout->mixer_lock );
+    aout_MixerRun( p_aout );
+    vlc_mutex_unlock( &p_aout->mixer_lock );
+
+    return 0;
+}
+
index 8c3dcd8..18b42ef 100644 (file)
@@ -2,7 +2,7 @@
  * input.c : internal management of input streams for the audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: input.c,v 1.12 2002/09/20 23:27:04 massiot Exp $
+ * $Id: input.c,v 1.13 2002/09/26 22:40:25 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
 /*****************************************************************************
  * aout_InputNew : allocate a new input and rework the filter pipeline
  *****************************************************************************/
-static aout_input_t * InputNew( aout_instance_t * p_aout,
-                                audio_sample_format_t * p_format )
+int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input )
 {
-    aout_input_t * p_input;
-
-    vlc_mutex_lock( &p_aout->mixer_lock );
-
-    if ( p_aout->i_nb_inputs >= AOUT_MAX_INPUTS )
-    {
-        msg_Err( p_aout, "too many inputs already (%d)", p_aout->i_nb_inputs );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
-        return NULL;
-    }
-
-    p_input = malloc(sizeof(aout_input_t));
-    if ( p_input == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
-        return NULL;
-    }
-
-    vlc_mutex_init( p_aout, &p_input->lock );
-    vlc_mutex_lock( &p_input->lock );
-
-    if ( p_aout->i_nb_inputs == 0 )
-    {
-        /* Recreate the output using the new format. */
-        if ( aout_OutputNew( p_aout, p_format ) < 0 )
-        {
-            vlc_mutex_unlock( &p_input->lock );
-            vlc_mutex_destroy( &p_input->lock );
-            free( p_input );
-            vlc_mutex_unlock( &p_aout->mixer_lock );
-            return NULL;
-        }
-    }
-    else
-    {
-        aout_MixerDelete( p_aout );
-    }
-
-    p_input->b_error = 0;
-    memcpy( &p_input->input, p_format,
-            sizeof(audio_sample_format_t) );
-    aout_FormatPrepare( &p_input->input );
-
     /* Prepare FIFO. */
     aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
     p_input->p_first_byte_to_mix = NULL;
 
-    p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input;
-    p_aout->i_nb_inputs++;
-
-    if ( aout_MixerNew( p_aout ) < 0 )
-    {
-        p_aout->i_nb_inputs--;
-
-        if ( !p_aout->i_nb_inputs )
-        {
-            aout_OutputDelete( p_aout );
-        }
-        else
-        {
-            aout_MixerNew( p_aout );
-        }
-
-        aout_FifoDestroy( p_aout, &p_input->fifo );
-        vlc_mutex_unlock( &p_input->lock );
-        vlc_mutex_destroy( &p_input->lock );
-        free( p_input );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
-
-        return NULL;
-    }
-
-    vlc_mutex_unlock( &p_aout->mixer_lock );
-
     /* Create filters. */
     if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
                                      &p_input->i_nb_filters, &p_input->input,
@@ -124,25 +52,10 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
     {
         msg_Err( p_aout, "couldn't set an input pipeline" );
 
-        p_aout->i_nb_inputs--;
-
-        aout_MixerDelete( p_aout );
-        if ( !p_aout->i_nb_inputs )
-        {
-            aout_OutputDelete( p_aout );
-        }
-        else
-        {
-            aout_MixerNew( p_aout );
-        }
-
         aout_FifoDestroy( p_aout, &p_input->fifo );
-        vlc_mutex_unlock( &p_input->lock );
-        vlc_mutex_destroy( &p_input->lock );
-        free( p_input );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
+        p_input->b_error = 1;
 
-        return NULL;
+        return -1;
     }
 
     /* Prepare hints for the buffer allocator. */
@@ -162,149 +75,43 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
     /* Allocate in the heap, it is more convenient for the decoder. */
     p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
 
-    vlc_mutex_unlock( &p_input->lock );
-
-    msg_Dbg( p_aout, "input 0x%x created", p_input );
-    return p_input;
-}
-
-aout_input_t * __aout_InputNew( vlc_object_t * p_this,
-                                aout_instance_t ** pp_aout,
-                                audio_sample_format_t * p_format )
-{
-    /* Create an audio output if there is none. */
-    *pp_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
-
-    if( *pp_aout == NULL )
-    {
-        msg_Dbg( p_this, "no aout present, spawning one" );
-
-        *pp_aout = aout_NewInstance( p_this );
-        /* Everything failed, I'm a loser, I just wanna die */
-        if( *pp_aout == NULL )
-        {
-            return NULL;
-        }
-    }
-    else
-    {
-        vlc_object_release( *pp_aout );
-    }
+    p_input->b_error = 0;
 
-    return InputNew( *pp_aout, p_format );
+    return 0;
 }
 
 /*****************************************************************************
  * aout_InputDelete : delete an input
- *****************************************************************************/
-void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
-{
-    int i_input;
-
-    vlc_mutex_lock( &p_aout->mixer_lock );
-    vlc_mutex_lock( &p_input->lock );
-
-    for ( i_input = 0; i_input < p_aout->i_nb_inputs; i_input++ )
-    {
-        if ( p_aout->pp_inputs[i_input] == p_input )
-        {
-            break;
-        }
-    }
-
-    if ( i_input == p_aout->i_nb_inputs )
-    {
-        msg_Err( p_aout, "cannot find an input to delete" );
-        return;
-    }
-
-    /* Remove the input from the list. */
-    memmove( &p_aout->pp_inputs[i_input], &p_aout->pp_inputs[i_input + 1],
-             (AOUT_MAX_INPUTS - i_input - 1) * sizeof(aout_input_t *) );
-    p_aout->i_nb_inputs--;
-
-    if ( !p_aout->i_nb_inputs )
-    {
-        aout_OutputDelete( p_aout );
-        aout_MixerDelete( p_aout );
-    }
-
-    vlc_mutex_unlock( &p_aout->mixer_lock );
-
-    aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
-                                 p_input->i_nb_filters );
-    aout_FifoDestroy( p_aout, &p_input->fifo );
-
-    vlc_mutex_unlock( &p_input->lock );
-    vlc_mutex_destroy( &p_input->lock );
-    free( p_input );
-
-    msg_Dbg( p_aout, "input 0x%x destroyed", p_input );
-}
-
-/*****************************************************************************
- * aout_InputChange : recreate the pipeline framework, in case the output
- *                    device has changed
  *****************************************************************************
- * You must own p_input->lock and the mixer lock before entering this function.
- * It returns -1 if the input pipeline couldn't be created. Please remember
- * to call aout_MixerNew() afterwards.
+ * This function must be entered with the mixer lock.
  *****************************************************************************/
-int aout_InputChange( aout_instance_t * p_aout, aout_input_t * p_input )
+int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
 {
+    if ( p_input->b_error ) return 0;
+
     aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
                                  p_input->i_nb_filters );
     aout_FifoDestroy( p_aout, &p_input->fifo );
 
-    aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
-    p_input->p_first_byte_to_mix = NULL;
-
-    /* Create filters. */
-    if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
-                                     &p_input->i_nb_filters, &p_input->input,
-                                     &p_aout->mixer.mixer ) < 0 )
-    {
-        p_input->b_error = 1;
-
-        return -1;
-    }
-
-    /* Prepare hints for the buffer allocator. */
-    p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
-    p_input->input_alloc.i_bytes_per_sec = -1;
-
-    aout_FiltersHintBuffers( p_aout, p_input->pp_filters,
-                             p_input->i_nb_filters,
-                             &p_input->input_alloc );
-
-    /* i_bytes_per_sec is still == -1 if no filters */
-    p_input->input_alloc.i_bytes_per_sec = __MAX(
-                                    p_input->input_alloc.i_bytes_per_sec,
-                                    p_input->input.i_bytes_per_frame
-                                     * p_input->input.i_rate
-                                     / p_input->input.i_frame_length );
-    /* Allocate in the heap, it is more convenient for the decoder. */
-    p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
-
     return 0;
 }
 
 /*****************************************************************************
  * aout_InputPlay : play a buffer
+ *****************************************************************************
+ * This function must be entered with the input lock.
  *****************************************************************************/
 int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                     aout_buffer_t * p_buffer )
 {
     mtime_t start_date, duration;
 
-    vlc_mutex_lock( &p_input->lock );
-
-    if ( p_input->b_error ) return -1;
-
     /* We don't care if someone changes the start date behind our back after
      * this. We'll deal with that when pushing the buffer, and compensate
      * with the next incoming buffer. */
+    vlc_mutex_lock( &p_aout->input_fifos_lock );
     start_date = aout_FifoNextStart( p_aout, &p_input->fifo );
+    vlc_mutex_unlock( &p_aout->input_fifos_lock );
 
     if ( start_date != 0 && start_date < mdate() )
     {
@@ -420,12 +227,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                           &p_buffer );
     }
 
-    vlc_mutex_unlock( &p_input->lock );
-
-    vlc_mutex_lock( &p_aout->input_fifos_lock );
     /* Adding the start date will be managed by aout_FifoPush(). */
     p_buffer->start_date = start_date;
     p_buffer->end_date = start_date + duration;
+
+    vlc_mutex_lock( &p_aout->input_fifos_lock );
     aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
     vlc_mutex_unlock( &p_aout->input_fifos_lock );
 
index cc82727..17e59ba 100644 (file)
@@ -2,7 +2,7 @@
  * intf.c : audio output API towards the interface modules
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: intf.c,v 1.3 2002/09/19 21:56:40 massiot Exp $
+ * $Id: intf.c,v 1.4 2002/09/26 22:40:25 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -32,6 +32,7 @@
 #include "audio_output.h"
 #include "aout_internal.h"
 
+
 /*
  * Volume management
  *
@@ -64,7 +65,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
 
     vlc_mutex_lock( &p_aout->mixer_lock );
 
-    if ( p_aout->i_nb_inputs == 0 )
+    if ( p_aout->mixer.b_error )
     {
         /* The output module is destroyed. */
         vlc_mutex_unlock( &p_aout->mixer_lock );
@@ -87,7 +88,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume )
 
     vlc_mutex_lock( &p_aout->mixer_lock );
 
-    if ( p_aout->i_nb_inputs == 0 )
+    if ( p_aout->mixer.b_error )
     {
         /* The output module is destroyed. */
         vlc_mutex_unlock( &p_aout->mixer_lock );
@@ -110,7 +111,7 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
 
     vlc_mutex_lock( &p_aout->mixer_lock );
 
-    if ( p_aout->i_nb_inputs == 0 )
+    if ( p_aout->mixer.b_error )
     {
         /* The output module is destroyed. */
         vlc_mutex_unlock( &p_aout->mixer_lock );
@@ -138,7 +139,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps,
 
     vlc_mutex_lock( &p_aout->mixer_lock );
 
-    if ( p_aout->i_nb_inputs == 0 )
+    if ( p_aout->mixer.b_error )
     {
         /* The output module is destroyed. */
         vlc_mutex_unlock( &p_aout->mixer_lock );
@@ -177,7 +178,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps,
 
     vlc_mutex_lock( &p_aout->mixer_lock );
 
-    if ( p_aout->i_nb_inputs == 0 )
+    if ( p_aout->mixer.b_error )
     {
         /* The output module is destroyed. */
         vlc_mutex_unlock( &p_aout->mixer_lock );
@@ -275,10 +276,82 @@ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
     return -1;
 }
 
-
 /* Placeholder for pf_volume_set(). */
 int aout_VolumeNoneSet( aout_instance_t * p_aout, audio_volume_t i_volume )
 {
     return -1;
 }
 
+
+/*
+ * Pipelines management
+ */
+
+/*****************************************************************************
+ * aout_Restart : re-open the output device and rebuild the input and output
+ *                pipelines
+ *****************************************************************************
+ * This function is used whenever the parameters of the output plug-in are
+ * changed (eg. selecting S/PDIF or PCM).
+ *****************************************************************************/
+int aout_Restart( aout_instance_t * p_aout )
+{
+    int i;
+    vlc_bool_t b_error = 0;
+
+    vlc_mutex_lock( &p_aout->mixer_lock );
+
+    if ( p_aout->i_nb_inputs == 0 )
+    {
+        vlc_mutex_unlock( &p_aout->mixer_lock );
+        msg_Err( p_aout, "no decoder thread" );
+        return -1;
+    }
+
+    /* Lock all inputs. */
+    for ( i = 0; i < p_aout->i_nb_inputs; i++ )
+    {
+        vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+        aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
+    }
+
+    aout_MixerDelete( p_aout );
+
+    /* Re-open the output plug-in. */
+    aout_OutputDelete( p_aout );
+    if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 )
+    {
+        /* Release all locks and report the error. */
+        for ( i = 0; i < p_aout->i_nb_inputs; i++ )
+        {
+            vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+        }
+        vlc_mutex_unlock( &p_aout->mixer_lock );
+        return -1;
+    }
+
+    if ( aout_MixerNew( p_aout ) == -1 )
+    {
+        aout_OutputDelete( p_aout );
+        for ( i = 0; i < p_aout->i_nb_inputs; i++ )
+        {
+            vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+        }
+        vlc_mutex_unlock( &p_aout->mixer_lock );
+        return -1;
+    }
+
+    /* Re-open all inputs. */
+    for ( i = 0; i < p_aout->i_nb_inputs; i++ )
+    {
+        aout_input_t * p_input = p_aout->pp_inputs[i];
+
+        b_error |= aout_InputNew( p_aout, p_input );
+        vlc_mutex_unlock( &p_input->lock );
+    }
+
+    vlc_mutex_unlock( &p_aout->mixer_lock );
+
+    return b_error;
+}
+
index 589346f..d07b49b 100644 (file)
@@ -2,7 +2,7 @@
  * mixer.c : audio output mixing operations
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: mixer.c,v 1.15 2002/09/23 23:05:58 massiot Exp $
+ * $Id: mixer.c,v 1.16 2002/09/26 22:40:25 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -49,6 +49,7 @@ int aout_MixerNew( aout_instance_t * p_aout )
         msg_Err( p_aout, "no suitable aout mixer" );
         return -1;
     }
+    p_aout->mixer.b_error = 0;
     return 0;
 }
 
@@ -57,22 +58,48 @@ int aout_MixerNew( aout_instance_t * p_aout )
  *****************************************************************************
  * Please note that you must hold the mixer lock.
  *****************************************************************************/
-void aout_MixerDelete( aout_instance_t * p_aout )
+int aout_MixerDelete( aout_instance_t * p_aout )
 {
+    if ( p_aout->mixer.b_error ) return 0;
     module_Unneed( p_aout, p_aout->mixer.p_module );
+    p_aout->mixer.b_error = 1;
+
+    return 0;
 }
 
 /*****************************************************************************
  * MixBuffer: try to prepare one output buffer
+ *****************************************************************************
+ * Please note that you must hold the mixer lock.
  *****************************************************************************/
 static int MixBuffer( aout_instance_t * p_aout )
 {
-    int             i;
+    int             i, i_nb_real_inputs = 0;
     aout_buffer_t * p_output_buffer;
     mtime_t start_date, end_date;
     audio_date_t exact_start_date;
 
-    vlc_mutex_lock( &p_aout->mixer_lock );
+    if ( p_aout->mixer.b_error )
+    {
+        /* Free all incoming buffers. */
+        vlc_mutex_lock( &p_aout->input_fifos_lock );
+        for ( i = 0; i < p_aout->i_nb_inputs; i++ )
+        {
+            aout_input_t * p_input = p_aout->pp_inputs[i];
+            aout_buffer_t * p_buffer = p_input->fifo.p_first;
+            if ( p_input->b_error ) continue;
+            while ( p_buffer != NULL )
+            {
+                aout_buffer_t * p_next = p_buffer->p_next;
+                aout_BufferFree( p_buffer );
+                p_buffer = p_next;
+            }
+        }
+        vlc_mutex_unlock( &p_aout->input_fifos_lock );
+        return -1;
+    }
+
+
     vlc_mutex_lock( &p_aout->output_fifo_lock );
     vlc_mutex_lock( &p_aout->input_fifos_lock );
 
@@ -125,7 +152,6 @@ static int MixBuffer( aout_instance_t * p_aout )
         {
             /* Interrupted before the end... We can't run. */
             vlc_mutex_unlock( &p_aout->input_fifos_lock );
-            vlc_mutex_unlock( &p_aout->mixer_lock );
             return -1;
         }
     }
@@ -143,6 +169,7 @@ static int MixBuffer( aout_instance_t * p_aout )
         vlc_bool_t b_drop_buffers;
 
         if ( p_input->b_error ) continue;
+        i_nb_real_inputs++;
 
         p_buffer = p_fifo->p_first;
         if ( p_buffer == NULL )
@@ -241,11 +268,10 @@ static int MixBuffer( aout_instance_t * p_aout )
         if ( p_buffer == NULL ) break;
     }
 
-    if ( i < p_aout->i_nb_inputs )
+    if ( i < p_aout->i_nb_inputs || !i_nb_real_inputs )
     {
         /* Interrupted before the end... We can't run. */
         vlc_mutex_unlock( &p_aout->input_fifos_lock );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
         return -1;
     }
 
@@ -261,7 +287,6 @@ static int MixBuffer( aout_instance_t * p_aout )
     {
         msg_Err( p_aout, "out of memory" );
         vlc_mutex_unlock( &p_aout->input_fifos_lock );
-        vlc_mutex_unlock( &p_aout->mixer_lock );
         return -1;
     }
     /* This is again a bit kludgy - for the S/PDIF mixer. */
@@ -281,13 +306,13 @@ static int MixBuffer( aout_instance_t * p_aout )
 
     aout_OutputPlay( p_aout, p_output_buffer );
 
-    vlc_mutex_unlock( &p_aout->mixer_lock );
-
     return 0;
 }
 
 /*****************************************************************************
  * aout_MixerRun: entry point for the mixer & post-filters processing
+ *****************************************************************************
+ * Please note that you must hold the mixer lock.
  *****************************************************************************/
 void aout_MixerRun( aout_instance_t * p_aout )
 {
@@ -303,12 +328,17 @@ void aout_MixerRun( aout_instance_t * p_aout )
 int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier )
 {
     float f_old = p_aout->mixer.f_multiplier;
+    vlc_bool_t b_new_mixer = 0;
 
-    aout_MixerDelete( p_aout );
+    if ( !p_aout->mixer.b_error )
+    {
+        aout_MixerDelete( p_aout );
+        b_new_mixer = 1;
+    }
 
     p_aout->mixer.f_multiplier = f_multiplier;
 
-    if ( aout_MixerNew( p_aout ) )
+    if ( b_new_mixer && aout_MixerNew( p_aout ) )
     {
         p_aout->mixer.f_multiplier = f_old;
         aout_MixerNew( p_aout );
index e3f5014..0a0a603 100644 (file)
@@ -2,7 +2,7 @@
  * output.c : internal management of output streams for the audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: output.c,v 1.14 2002/08/30 23:27:06 massiot Exp $
+ * $Id: output.c,v 1.15 2002/09/26 22:40:25 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -35,7 +35,7 @@
 /*****************************************************************************
  * aout_OutputNew : allocate a new output and rework the filter pipeline
  *****************************************************************************
- * This function is entered with the mixer_lock.
+ * This function is entered with the mixer lock.
  *****************************************************************************/
 int aout_OutputNew( aout_instance_t * p_aout,
                     audio_sample_format_t * p_format )
@@ -132,7 +132,7 @@ int aout_OutputNew( aout_instance_t * p_aout,
 /*****************************************************************************
  * aout_OutputDelete : delete the output
  *****************************************************************************
- * This function is entered with the mixer_lock.
+ * This function is entered with the mixer lock.
  *****************************************************************************/
 void aout_OutputDelete( aout_instance_t * p_aout )
 {
@@ -146,7 +146,7 @@ void aout_OutputDelete( aout_instance_t * p_aout )
 /*****************************************************************************
  * aout_OutputPlay : play a buffer
  *****************************************************************************
- * This function is entered with the mixer_lock.
+ * This function is entered with the mixer lock.
  *****************************************************************************/
 void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
 {
@@ -166,6 +166,7 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
  * If b_can_sleek is 1, the aout core functions won't try to resample
  * new buffers to catch up - that is we suppose that the output plug-in can
  * compensate it by itself. S/PDIF outputs should always set b_can_sleek = 1.
+ * This function is entered with no lock at all :-).
  *****************************************************************************/
 aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
                                        mtime_t start_date,
index 04b0906..2a505fd 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.c: main libvlc source
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.c,v 1.31 2002/09/17 14:56:13 sam Exp $
+ * $Id: libvlc.c,v 1.32 2002/09/26 22:40:24 massiot Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -677,7 +677,7 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
         {
             vlc_object_detach( (vlc_object_t *)p_aout );
             vlc_object_release( (vlc_object_t *)p_aout );
-            aout_DeleteInstance( p_aout );
+            aout_Delete( p_aout );
         }
 
         /* Update the handle status */
index 087a4cb..84441f7 100644 (file)
@@ -184,23 +184,24 @@ static const char * module_error( char *psz_buffer )
     (p_symbols)->aout_FifoPop_inner = aout_FifoPop; \
     (p_symbols)->aout_VolumeSoftInit_inner = aout_VolumeSoftInit; \
     (p_symbols)->aout_VolumeNoneInit_inner = aout_VolumeNoneInit; \
-    (p_symbols)->__aout_NewInstance_inner = __aout_NewInstance; \
-    (p_symbols)->aout_DeleteInstance_inner = aout_DeleteInstance; \
-    (p_symbols)->aout_BufferNew_inner = aout_BufferNew; \
-    (p_symbols)->aout_BufferDelete_inner = aout_BufferDelete; \
-    (p_symbols)->aout_BufferPlay_inner = aout_BufferPlay; \
+    (p_symbols)->__aout_New_inner = __aout_New; \
+    (p_symbols)->aout_Delete_inner = aout_Delete; \
     (p_symbols)->aout_DateInit_inner = aout_DateInit; \
     (p_symbols)->aout_DateSet_inner = aout_DateSet; \
     (p_symbols)->aout_DateMove_inner = aout_DateMove; \
     (p_symbols)->aout_DateGet_inner = aout_DateGet; \
     (p_symbols)->aout_DateIncrement_inner = aout_DateIncrement; \
-    (p_symbols)->__aout_InputNew_inner = __aout_InputNew; \
-    (p_symbols)->aout_InputDelete_inner = aout_InputDelete; \
+    (p_symbols)->__aout_DecNew_inner = __aout_DecNew; \
+    (p_symbols)->aout_DecDelete_inner = aout_DecDelete; \
+    (p_symbols)->aout_DecNewBuffer_inner = aout_DecNewBuffer; \
+    (p_symbols)->aout_DecDeleteBuffer_inner = aout_DecDeleteBuffer; \
+    (p_symbols)->aout_DecPlay_inner = aout_DecPlay; \
     (p_symbols)->aout_VolumeGet_inner = aout_VolumeGet; \
     (p_symbols)->aout_VolumeSet_inner = aout_VolumeSet; \
     (p_symbols)->aout_VolumeInfos_inner = aout_VolumeInfos; \
     (p_symbols)->aout_VolumeUp_inner = aout_VolumeUp; \
     (p_symbols)->aout_VolumeDown_inner = aout_VolumeDown; \
+    (p_symbols)->aout_Restart_inner = aout_Restart; \
     (p_symbols)->__config_GetInt_inner = __config_GetInt; \
     (p_symbols)->__config_PutInt_inner = __config_PutInt; \
     (p_symbols)->__config_GetFloat_inner = __config_GetFloat; \