From 7a58ef70ff4c51288388703728752bce3f253c96 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Thu, 26 Sep 2002 22:40:27 +0000 Subject: [PATCH] * Major API change of the audio output. New aout_Dec* functions. * Fixed a compile issue in s16tofloat32swab. * Fixed a typo in demux/mpeg/ts.c. --- Makefile.old | 2 +- include/aout_internal.h | 16 +- include/audio_output.h | 25 +- include/vlc_symbols.h | 30 +- .../audio_filter/converter/s16tofloat32swab.c | 4 +- modules/codec/a52.c | 22 +- modules/codec/a52old/a52old.c | 26 +- modules/codec/faad/decoder.c | 20 +- modules/codec/lpcm.c | 24 +- modules/codec/mad/libmad.c | 12 +- modules/codec/mpeg_audio/decoder.c | 22 +- modules/demux/mpeg/ts.c | 3 +- src/audio_output/{audio_output.c => common.c} | 92 +---- src/audio_output/dec.c | 321 ++++++++++++++++++ src/audio_output/input.c | 226 +----------- src/audio_output/intf.c | 87 ++++- src/audio_output/mixer.c | 54 ++- src/audio_output/output.c | 9 +- src/libvlc.c | 4 +- src/misc/modules_plugin.h | 15 +- 20 files changed, 591 insertions(+), 423 deletions(-) rename src/audio_output/{audio_output.c => common.c} (78%) create mode 100644 src/audio_output/dec.c diff --git a/Makefile.old b/Makefile.old index 33ce20ea64..436b1fe0cf 100644 --- a/Makefile.old +++ b/Makefile.old @@ -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 diff --git a/include/aout_internal.h b/include/aout_internal.h index 9dcad7af44..a4e9cb61fd 100644 --- a/include/aout_internal.h +++ b/include/aout_internal.h @@ -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 * @@ -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 ); diff --git a/include/audio_output.h b/include/audio_output.h index 78124a8708..e7909f3088 100644 --- a/include/audio_output.h +++ b/include/audio_output.h @@ -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 * @@ -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 ) ); diff --git a/include/vlc_symbols.h b/include/vlc_symbols.h index d302a4b0d6..a7e9b087f9 100644 --- a/include/vlc_symbols.h +++ b/include/vlc_symbols.h @@ -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 diff --git a/modules/audio_filter/converter/s16tofloat32swab.c b/modules/audio_filter/converter/s16tofloat32swab.c index 66e0f8a653..b5ac29d08f 100644 --- a/modules/audio_filter/converter/s16tofloat32swab.c +++ b/modules/audio_filter/converter/s16tofloat32swab.c @@ -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 * Henri Fallon @@ -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 diff --git a/modules/codec/a52.c b/modules/codec/a52.c index 917b8dbcfb..d92ec9425e 100644 --- a/modules/codec/a52.c +++ b/modules/codec/a52.c @@ -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 * Christophe Massiot @@ -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 ); diff --git a/modules/codec/a52old/a52old.c b/modules/codec/a52old/a52old.c index ad22d7944a..ebe9d269a6 100644 --- a/modules/codec/a52old/a52old.c +++ b/modules/codec/a52old/a52old.c @@ -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 * @@ -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 */ diff --git a/modules/codec/faad/decoder.c b/modules/codec/faad/decoder.c index 4add301b90..f95e00be22 100644 --- a/modules/codec/faad/decoder.c +++ b/modules/codec/faad/decoder.c @@ -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 * @@ -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 ) diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c index 696245dd49..69782e674e 100644 --- a/modules/codec/lpcm.c +++ b/modules/codec/lpcm.c @@ -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 * Henri Fallon @@ -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 ); diff --git a/modules/codec/mad/libmad.c b/modules/codec/mad/libmad.c index ad4b48ef2b..17894e5394 100644 --- a/modules/codec/mad/libmad.c +++ b/modules/codec/mad/libmad.c @@ -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; } diff --git a/modules/codec/mpeg_audio/decoder.c b/modules/codec/mpeg_audio/decoder.c index 5aad3705b2..413168b85c 100644 --- a/modules/codec/mpeg_audio/decoder.c +++ b/modules/codec/mpeg_audio/decoder.c @@ -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 * Michel Lespinasse @@ -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 ); } diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c index 748f0ebbe9..13b0a28b44 100644 --- a/modules/demux/mpeg/ts.c +++ b/modules/demux/mpeg/ts.c @@ -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 * Johan Bilien @@ -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/common.c similarity index 78% rename from src/audio_output/audio_output.c rename to src/audio_output/common.c index c9d4b867cd..1bccddc50d 100644 --- a/src/audio_output/audio_output.c +++ b/src/audio_output/common.c @@ -1,8 +1,8 @@ /***************************************************************************** - * audio_output.c : audio output instance miscellaneous functions + * common.c : audio output management of common data structures ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: audio_output.c,v 1.103 2002/09/20 23:27:04 massiot Exp $ + * $Id: common.c,v 1.1 2002/09/26 22:40:25 massiot Exp $ * * Authors: Christophe Massiot * @@ -29,21 +29,18 @@ #include -#ifdef HAVE_ALLOCA_H -# include -#endif - #include "audio_output.h" #include "aout_internal.h" + /* - * Instances management (see also input.c:aout_InputNew()) + * Instances management (internal and external) */ /***************************************************************************** - * aout_NewInstance: initialize aout structure + * aout_New: initialize aout structure *****************************************************************************/ -aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent ) +aout_instance_t * __aout_New( vlc_object_t * p_parent ) { aout_instance_t * p_aout; @@ -60,6 +57,7 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent ) 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 ); @@ -67,9 +65,9 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent ) } /***************************************************************************** - * aout_DeleteInstance: destroy aout structure + * aout_Delete: destroy aout structure *****************************************************************************/ -void aout_DeleteInstance( aout_instance_t * p_aout ) +void aout_Delete( aout_instance_t * p_aout ) { vlc_mutex_destroy( &p_aout->input_fifos_lock ); vlc_mutex_destroy( &p_aout->mixer_lock ); @@ -81,77 +79,7 @@ void aout_DeleteInstance( aout_instance_t * 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 + * Formats management (internal and external) */ /***************************************************************************** diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c new file mode 100644 index 0000000000..7824b86f03 --- /dev/null +++ b/src/audio_output/dec.c @@ -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 + * + * 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 /* calloc(), malloc(), free() */ +#include + +#include + +#ifdef HAVE_ALLOCA_H +# include +#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; +} + diff --git a/src/audio_output/input.c b/src/audio_output/input.c index 8c3dcd8f0f..18b42ef15f 100644 --- a/src/audio_output/input.c +++ b/src/audio_output/input.c @@ -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 * @@ -39,84 +39,12 @@ /***************************************************************************** * 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 ); diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c index cc82727057..17e59ba268 100644 --- a/src/audio_output/intf.c +++ b/src/audio_output/intf.c @@ -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 * @@ -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; +} + diff --git a/src/audio_output/mixer.c b/src/audio_output/mixer.c index 589346f93c..d07b49bbd7 100644 --- a/src/audio_output/mixer.c +++ b/src/audio_output/mixer.c @@ -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 * @@ -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 ); diff --git a/src/audio_output/output.c b/src/audio_output/output.c index e3f50144ee..0a0a6031af 100644 --- a/src/audio_output/output.c +++ b/src/audio_output/output.c @@ -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 * @@ -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, diff --git a/src/libvlc.c b/src/libvlc.c index 04b0906e9c..2a505fd568 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -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 * Samuel Hocevar @@ -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 */ diff --git a/src/misc/modules_plugin.h b/src/misc/modules_plugin.h index 087a4cba9b..84441f7a14 100644 --- a/src/misc/modules_plugin.h +++ b/src/misc/modules_plugin.h @@ -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; \ -- 2.20.1