Commit 7a58ef70 authored by Christophe Massiot's avatar Christophe Massiot

* 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.
parent cc35b1d0
...@@ -22,7 +22,7 @@ INTERFACE := interface intf_eject ...@@ -22,7 +22,7 @@ INTERFACE := interface intf_eject
PLAYLIST := playlist PLAYLIST := playlist
INPUT := input input_ext-plugins input_ext-dec input_ext-intf input_dec input_programs input_clock input_info 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 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 STREAM_OUTPUT := stream_output
MISC := mtime modules threads cpu configuration netutils iso_lang messages objects extras MISC := mtime modules threads cpu configuration netutils iso_lang messages objects extras
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output * aout_internal.h : internal defines for audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -120,6 +120,8 @@ typedef struct aout_mixer_t ...@@ -120,6 +120,8 @@ typedef struct aout_mixer_t
void (* pf_do_work)( struct aout_instance_t *, void (* pf_do_work)( struct aout_instance_t *,
struct aout_buffer_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 /* Multiplier used to raise or lower the volume of the sound in
* software. Beware, this creates sound distortion and should be avoided * software. Beware, this creates sound distortion and should be avoided
* as much as possible. This isn't available for non-float32 mixer. */ * as much as possible. This isn't available for non-float32 mixer. */
...@@ -147,8 +149,10 @@ struct aout_input_t ...@@ -147,8 +149,10 @@ struct aout_input_t
/* Mixer information */ /* Mixer information */
byte_t * p_first_byte_to_mix; 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; 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 ...@@ -186,7 +190,7 @@ struct aout_instance_t
/* Locks : please note that if you need several of these locks, it is /* Locks : please note that if you need several of these locks, it is
* mandatory (to avoid deadlocks) to take them in the following order : * 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 */ * --Meuuh */
/* When input_fifos_lock is taken, none of the p_input->fifo structures /* When input_fifos_lock is taken, none of the p_input->fifo structures
* can be read or modified by a third-party thread. */ * can be read or modified by a third-party thread. */
...@@ -214,6 +218,8 @@ struct aout_instance_t ...@@ -214,6 +218,8 @@ struct aout_instance_t
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
/* From input.c : */ /* 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, int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer ); aout_buffer_t * p_buffer );
...@@ -235,7 +241,7 @@ void aout_FiltersPlay( aout_instance_t * p_aout, ...@@ -235,7 +241,7 @@ void aout_FiltersPlay( aout_instance_t * p_aout,
/* From mixer.c : */ /* From mixer.c : */
int aout_MixerNew( aout_instance_t * p_aout ); 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 ); void aout_MixerRun( aout_instance_t * p_aout );
int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier ); int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier );
int aout_MixerMultiplierGet( aout_instance_t * p_aout, float * pf_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 ); ...@@ -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 ); void aout_OutputDelete( aout_instance_t * p_aout );
VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) ); 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 ) ); VLC_EXPORT( int, aout_FormatNbChannels, ( audio_sample_format_t * p_format ) );
void aout_FormatPrepare( 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 ); void aout_FifoInit( aout_instance_t *, aout_fifo_t *, u32 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.h : audio output interface * audio_output.h : audio output interface
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -168,23 +168,23 @@ struct audio_date_t ...@@ -168,23 +168,23 @@ struct audio_date_t
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
/* From audio_output.c : */ /* From common.c : */
#define aout_NewInstance(a) __aout_NewInstance(VLC_OBJECT(a)) #define aout_New(a) __aout_New(VLC_OBJECT(a))
VLC_EXPORT( aout_instance_t *, __aout_NewInstance, ( vlc_object_t * ) ); VLC_EXPORT( aout_instance_t *, __aout_New, ( vlc_object_t * ) );
VLC_EXPORT( void, aout_DeleteInstance, ( aout_instance_t * ) ); VLC_EXPORT( void, aout_Delete, ( 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 * ) );
VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) ); VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) );
VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) ); VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) );
VLC_EXPORT( void, aout_DateMove, ( 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_DateGet, ( const audio_date_t * ) );
VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, u32 ) ); VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, u32 ) );
/* From input.c : */ /* From dec.c : */
#define aout_InputNew(a,b,c) __aout_InputNew(VLC_OBJECT(a),b,c) #define aout_DecNew(a, b, c) __aout_DecNew(VLC_OBJECT(a), b, c)
VLC_EXPORT( aout_input_t *, __aout_InputNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ); VLC_EXPORT( aout_input_t *, __aout_DecNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );
VLC_EXPORT( void, aout_InputDelete, ( aout_instance_t *, aout_input_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 : */ /* From intf.c : */
VLC_EXPORT( int, aout_VolumeGet, ( aout_instance_t *, audio_volume_t * ) ); 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 ) ); ...@@ -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_VolumeInfos, ( aout_instance_t *, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, 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_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
struct module_symbols_t 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_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_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_input_t * (* __aout_DecNew_inner) ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ;
aout_instance_t * (* __aout_NewInstance_inner) ( vlc_object_t * ) ; aout_instance_t * (* __aout_New_inner) ( vlc_object_t * ) ;
char * (* __config_GetPsz_inner) (vlc_object_t *, const char *) ; char * (* __config_GetPsz_inner) (vlc_object_t *, const char *) ;
char * (* config_GetHomeDir_inner) ( void ) ; char * (* config_GetHomeDir_inner) ( void ) ;
char * (* input_OffsetToTime_inner) ( input_thread_t *, char *, off_t ) ; char * (* input_OffsetToTime_inner) ( input_thread_t *, char *, off_t ) ;
...@@ -37,8 +37,10 @@ struct module_symbols_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_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_end_inner) ( vlc_object_t * ) ;
int (* __vlc_threads_init_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_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_VolumeDown_inner) ( aout_instance_t *, int, audio_volume_t * ) ;
int (* aout_VolumeGet_inner) ( aout_instance_t *, audio_volume_t * ) ; int (* aout_VolumeGet_inner) ( aout_instance_t *, audio_volume_t * ) ;
int (* aout_VolumeInfos_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 ...@@ -111,12 +113,11 @@ struct module_symbols_t
void (* __vlc_object_yield_inner) ( vlc_object_t * ) ; void (* __vlc_object_yield_inner) ( vlc_object_t * ) ;
void (* __vlc_thread_join_inner) ( vlc_object_t *, char *, int ) ; void (* __vlc_thread_join_inner) ( vlc_object_t *, char *, int ) ;
void (* __vlc_thread_ready_inner) ( vlc_object_t * ) ; 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_DateInit_inner) ( audio_date_t *, u32 ) ;
void (* aout_DateMove_inner) ( audio_date_t *, mtime_t ) ; void (* aout_DateMove_inner) ( audio_date_t *, mtime_t ) ;
void (* aout_DateSet_inner) ( audio_date_t *, mtime_t ) ; void (* aout_DateSet_inner) ( audio_date_t *, mtime_t ) ;
void (* aout_DeleteInstance_inner) ( aout_instance_t * ) ; void (* aout_DecDeleteBuffer_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
void (* aout_InputDelete_inner) ( aout_instance_t *, aout_input_t * ) ; void (* aout_Delete_inner) ( aout_instance_t * ) ;
void (* aout_VolumeNoneInit_inner) ( aout_instance_t * ) ; void (* aout_VolumeNoneInit_inner) ( aout_instance_t * ) ;
void (* aout_VolumeSoftInit_inner) ( aout_instance_t * ) ; void (* aout_VolumeSoftInit_inner) ( aout_instance_t * ) ;
void (* config_Duplicate_inner) ( module_t *, module_config_t * ) ; void (* config_Duplicate_inner) ( module_t *, module_config_t * ) ;
...@@ -172,8 +173,8 @@ struct module_symbols_t ...@@ -172,8 +173,8 @@ struct module_symbols_t
# define UnalignedGetBits p_symbols->UnalignedGetBits_inner # define UnalignedGetBits p_symbols->UnalignedGetBits_inner
# define UnalignedRemoveBits p_symbols->UnalignedRemoveBits_inner # define UnalignedRemoveBits p_symbols->UnalignedRemoveBits_inner
# define UnalignedShowBits p_symbols->UnalignedShowBits_inner # define UnalignedShowBits p_symbols->UnalignedShowBits_inner
# define __aout_InputNew p_symbols->__aout_InputNew_inner # define __aout_DecNew p_symbols->__aout_DecNew_inner
# define __aout_NewInstance p_symbols->__aout_NewInstance_inner # define __aout_New p_symbols->__aout_New_inner
# define __config_GetFloat p_symbols->__config_GetFloat_inner # define __config_GetFloat p_symbols->__config_GetFloat_inner
# define __config_GetInt p_symbols->__config_GetInt_inner # define __config_GetInt p_symbols->__config_GetInt_inner
# define __config_GetPsz p_symbols->__config_GetPsz_inner # define __config_GetPsz p_symbols->__config_GetPsz_inner
...@@ -222,19 +223,20 @@ struct module_symbols_t ...@@ -222,19 +223,20 @@ struct module_symbols_t
# define __vlc_threads_end p_symbols->__vlc_threads_end_inner # define __vlc_threads_end p_symbols->__vlc_threads_end_inner
# define __vlc_threads_init p_symbols->__vlc_threads_init_inner # define __vlc_threads_init p_symbols->__vlc_threads_init_inner
# define __vout_CreateThread p_symbols->__vout_CreateThread_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_DateGet p_symbols->aout_DateGet_inner
# define aout_DateIncrement p_symbols->aout_DateIncrement_inner # define aout_DateIncrement p_symbols->aout_DateIncrement_inner
# define aout_DateInit p_symbols->aout_DateInit_inner # define aout_DateInit p_symbols->aout_DateInit_inner
# define aout_DateMove p_symbols->aout_DateMove_inner # define aout_DateMove p_symbols->aout_DateMove_inner
# define aout_DateSet p_symbols->aout_DateSet_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_FifoPop p_symbols->aout_FifoPop_inner
# define aout_FormatNbChannels p_symbols->aout_FormatNbChannels_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_OutputNextBuffer p_symbols->aout_OutputNextBuffer_inner
# define aout_Restart p_symbols->aout_Restart_inner
# define aout_VolumeDown p_symbols->aout_VolumeDown_inner # define aout_VolumeDown p_symbols->aout_VolumeDown_inner
# define aout_VolumeGet p_symbols->aout_VolumeGet_inner # define aout_VolumeGet p_symbols->aout_VolumeGet_inner
# define aout_VolumeInfos p_symbols->aout_VolumeInfos_inner # define aout_VolumeInfos p_symbols->aout_VolumeInfos_inner
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* with endianness change * with endianness change
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -115,7 +115,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -115,7 +115,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
#ifndef HAVE_SWAB #ifndef HAVE_SWAB
p_tmp[0] = ((byte_t *)p_in)[1]; p_tmp[0] = ((byte_t *)p_in)[1];
p_tmp[1] = ((byte_t *)p_in)[0]; 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 #else
*p_out = (float)*p_in / 32768.0; *p_out = (float)*p_in / 32768.0;
#endif #endif
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52.c: A/52 basic parser * a52.c: A/52 basic parser
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2002 VideoLAN * 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: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -174,7 +174,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -174,7 +174,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
|| (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) ) || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
{ {
/* Parameters changed - this should not happen. */ /* 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; p_dec->p_aout_input = NULL;
} }
...@@ -186,9 +186,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -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_bytes_per_frame = i_frame_size;
p_dec->output_format.i_frame_length = A52_FRAME_NB; p_dec->output_format.i_frame_length = A52_FRAME_NB;
aout_DateInit( &end_date, i_rate ); aout_DateInit( &end_date, i_rate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo, p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
&p_dec->output_format ); &p_dec->output_format );
if ( p_dec->p_aout_input == NULL ) if ( p_dec->p_aout_input == NULL )
{ {
...@@ -206,8 +206,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -206,8 +206,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
continue; continue;
} }
p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input, p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input,
A52_FRAME_NB ); A52_FRAME_NB );
if ( p_buffer == NULL ) return -1; if ( p_buffer == NULL ) return -1;
p_buffer->start_date = aout_DateGet( &end_date ); p_buffer->start_date = aout_DateGet( &end_date );
p_buffer->end_date = aout_DateIncrement( &end_date, p_buffer->end_date = aout_DateIncrement( &end_date,
...@@ -219,13 +219,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -219,13 +219,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
i_frame_size - 7 ); i_frame_size - 7 );
if( p_dec->p_fifo->b_die ) if( p_dec->p_fifo->b_die )
{ {
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input, aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
p_buffer ); p_buffer );
break; break;
} }
/* Send the buffer to the mixer. */ /* 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 */ /* If b_error is set, the spdif thread enters the error loop */
...@@ -247,7 +247,7 @@ static void EndThread( dec_thread_t * p_dec ) ...@@ -247,7 +247,7 @@ static void EndThread( dec_thread_t * p_dec )
{ {
if ( p_dec->p_aout_input != NULL ) 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 ); free( p_dec );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52old.c: A52 decoder module main file * a52old.c: A52 decoder module main file
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Lespinasse <walken@zoy.org>
* *
...@@ -167,7 +167,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -167,7 +167,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
{ {
/* Delete old output */ /* Delete old output */
msg_Warn( p_a52dec->p_fifo, "opening a new aout" ); 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 */ /* Set output configuration */
...@@ -175,9 +175,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -175,9 +175,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
output_format.i_channels = 2; /* FIXME ! */ output_format.i_channels = 2; /* FIXME ! */
output_format.i_rate = sync_info.sample_rate; output_format.i_rate = sync_info.sample_rate;
aout_DateInit( &end_date, output_format.i_rate ); aout_DateInit( &end_date, output_format.i_rate );
p_a52dec->p_aout_input = aout_InputNew( p_a52dec->p_fifo, p_a52dec->p_aout_input = aout_DecNew( p_a52dec->p_fifo,
&p_a52dec->p_aout, &p_a52dec->p_aout,
&output_format ); &output_format );
} }
if( p_a52dec->p_aout_input == NULL ) if( p_a52dec->p_aout_input == NULL )
...@@ -198,9 +198,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -198,9 +198,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
continue; continue;
} }
p_aout_buffer = aout_BufferNew( p_a52dec->p_aout, p_aout_buffer = aout_DecNewBuffer( p_a52dec->p_aout,
p_a52dec->p_aout_input, p_a52dec->p_aout_input,
A52DEC_FRAME_SIZE ); A52DEC_FRAME_SIZE );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
msg_Err( p_a52dec->p_fifo, "cannot get aout buffer" ); msg_Err( p_a52dec->p_fifo, "cannot get aout buffer" );
...@@ -215,14 +215,14 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -215,14 +215,14 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if (decode_frame (p_a52dec, (s16*)p_aout_buffer->p_buffer)) if (decode_frame (p_a52dec, (s16*)p_aout_buffer->p_buffer))
{ {
b_sync = 0; b_sync = 0;
aout_BufferDelete( p_a52dec->p_aout, p_a52dec->p_aout_input, aout_DecDeleteBuffer( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer ); p_aout_buffer );
continue; continue;
} }
else else
{ {
aout_BufferPlay( p_a52dec->p_aout, p_a52dec->p_aout_input, aout_DecPlay( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer ); p_aout_buffer );
} }
RealignBits(&p_a52dec->bit_stream); RealignBits(&p_a52dec->bit_stream);
...@@ -344,7 +344,7 @@ static void EndThread (a52dec_t * p_a52dec) ...@@ -344,7 +344,7 @@ static void EndThread (a52dec_t * p_a52dec)
/* If the audio output fifo was created, we destroy it */ /* If the audio output fifo was created, we destroy it */
if( p_a52dec->p_aout_input ) 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 */ /* Free allocated structures */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2 * decoder.c: AAC decoder using libfaad2
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -447,15 +447,15 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -447,15 +447,15 @@ static void DecodeThread( adec_thread_t *p_adec )
if( p_adec->p_aout_input ) if( p_adec->p_aout_input )
{ {
/* **** Delete the old **** */ /* **** 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 **** */ /* **** Create a new audio output **** */
p_adec->output_format.i_channels = faad_frame.channels; p_adec->output_format.i_channels = faad_frame.channels;
aout_DateInit( &p_adec->date, p_adec->output_format.i_rate ); 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_input = aout_DecNew( p_adec->p_fifo,
&p_adec->p_aout, &p_adec->p_aout,
&p_adec->output_format ); &p_adec->output_format );
} }
if( !p_adec->p_aout_input ) if( !p_adec->p_aout_input )
...@@ -473,9 +473,9 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -473,9 +473,9 @@ static void DecodeThread( adec_thread_t *p_adec )
return; return;
} }
p_aout_buffer = aout_BufferNew( p_adec->p_aout, p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
p_adec->p_aout_input, p_adec->p_aout_input,
faad_frame.samples / faad_frame.channels ); faad_frame.samples / faad_frame.channels );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
msg_Err( p_adec->p_fifo, "cannot get aout buffer" ); msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
...@@ -490,7 +490,7 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -490,7 +490,7 @@ static void DecodeThread( adec_thread_t *p_adec )
p_faad_buffer, p_faad_buffer,
p_aout_buffer->i_nb_bytes ); 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) ...@@ -501,7 +501,7 @@ static void EndThread (adec_thread_t *p_adec)
{ {
if( p_adec->p_aout_input ) 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 ) if( p_adec->p_handle )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* lpcm.c: lpcm decoder module * lpcm.c: lpcm decoder module
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -131,9 +131,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) ...@@ -131,9 +131,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
p_dec->output_format.i_rate = 48000; p_dec->output_format.i_rate = 48000;
aout_DateInit( &p_dec->end_date, 48000 ); aout_DateInit( &p_dec->end_date, 48000 );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo, p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
&p_dec->output_format ); &p_dec->output_format );
if ( p_dec->p_aout_input == NULL ) if ( p_dec->p_aout_input == NULL )
{ {
...@@ -175,9 +175,9 @@ void DecodeFrame( dec_thread_t * p_dec ) ...@@ -175,9 +175,9 @@ void DecodeFrame( dec_thread_t * p_dec )
aout_DateSet( &p_dec->end_date, i_pts ); aout_DateSet( &p_dec->end_date, i_pts );
} }
p_aout_buffer = aout_BufferNew( p_dec->p_aout, p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
p_dec->p_aout_input, p_dec->p_aout_input,
LPCM_FRAME_NB ); LPCM_FRAME_NB );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
...@@ -200,13 +200,13 @@ void DecodeFrame( dec_thread_t * p_dec ) ...@@ -200,13 +200,13 @@ void DecodeFrame( dec_thread_t * p_dec )
if( p_dec->p_fifo->b_die ) if( p_dec->p_fifo->b_die )
{ {
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input, aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer ); p_aout_buffer );
return; return;
} }
aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer ); p_aout_buffer );
} }
/***************************************************************************** /*****************************************************************************
...@@ -216,7 +216,7 @@ static void EndThread( dec_thread_t * p_dec ) ...@@ -216,7 +216,7 @@ static void EndThread( dec_thread_t * p_dec )
{ {
if( p_dec->p_aout_input != NULL ) 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 ); free( p_dec );
......
...@@ -155,7 +155,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header, ...@@ -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) ) || p_dec->output_format.i_channels != p_pcm->channels) )
{ {
/* Parameters changed - this should not happen. */ /* 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; p_dec->p_aout_input = NULL;
} }
...@@ -165,9 +165,9 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header, ...@@ -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_rate = p_pcm->samplerate;
p_dec->output_format.i_channels = p_pcm->channels; p_dec->output_format.i_channels = p_pcm->channels;
aout_DateInit( &p_dec->end_date, p_pcm->samplerate ); aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo, p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
&p_dec->output_format ); &p_dec->output_format );
if ( p_dec->p_aout_input == NULL ) 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, ...@@ -199,7 +199,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
return MAD_FLOW_CONTINUE; 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 ) if ( p_buffer == NULL )
{ {
...@@ -233,7 +233,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header, ...@@ -233,7 +233,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
p_pcm->channels ); 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; return MAD_FLOW_CONTINUE;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: MPEG audio decoder thread * decoder.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -174,7 +174,7 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -174,7 +174,7 @@ static void DecodeThread( adec_thread_t * p_dec )
{ {
/* Delete old output */ /* Delete old output */
msg_Warn( p_dec->p_fifo, "opening a new aout" ); 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 */ /* Set output configuration */
...@@ -182,9 +182,9 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -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_channels = ( sync_info.b_stereo ? 2 : 1 );
p_dec->output_format.i_rate = sync_info.sample_rate; p_dec->output_format.i_rate = sync_info.sample_rate;
aout_DateInit( &p_dec->end_date, 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_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
&p_dec->output_format ); &p_dec->output_format );
} }
if( p_dec->p_aout_input == NULL ) if( p_dec->p_aout_input == NULL )
...@@ -200,9 +200,9 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -200,9 +200,9 @@ static void DecodeThread( adec_thread_t * p_dec )
return; return;
} }
p_aout_buffer = aout_BufferNew( p_dec->p_aout, p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
p_dec->p_aout_input, p_dec->p_aout_input,
ADEC_FRAME_NB ); ADEC_FRAME_NB );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
msg_Err( p_dec->p_fifo, "cannot get aout buffer" ); msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
...@@ -216,11 +216,11 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -216,11 +216,11 @@ static void DecodeThread( adec_thread_t * p_dec )
if( adec_DecodeFrame (p_dec, (float*)p_aout_buffer->p_buffer ) ) if( adec_DecodeFrame (p_dec, (float*)p_aout_buffer->p_buffer ) )
{ {
/* Ouch, failed decoding... We'll have to resync */ /* 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 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 ) ...@@ -236,7 +236,7 @@ static void EndThread ( adec_thread_t *p_dec )
/* If the audio output fifo was created, we destroy it */ /* If the audio output fifo was created, we destroy it */
if( p_dec->p_aout_input ) 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 );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg_ts.c : Transport Stream input module for vlc * mpeg_ts.c : Transport Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * 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> * Authors: Henri Fallon <henri@via.ecp.fr>
* Johan Bilien <jobi@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 ) ...@@ -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; p_new_es->i_stream_id = 0xBD;
break; break;
case DVD_SPU_ES: case DVD_SPU_ES:
case A52_AUDIO_ES:
if ( !b_vls_compat ) if ( !b_vls_compat )
p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' '); p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
else else
......
/***************************************************************************** /*****************************************************************************
* audio_output.c : audio output instance miscellaneous functions * common.c : audio output management of common data structures
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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 <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -29,21 +29,18 @@ ...@@ -29,21 +29,18 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "audio_output.h" #include "audio_output.h"
#include "aout_internal.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; aout_instance_t * p_aout;
...@@ -60,6 +57,7 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent ) ...@@ -60,6 +57,7 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent )
vlc_mutex_init( p_parent, &p_aout->output_fifo_lock ); vlc_mutex_init( p_parent, &p_aout->output_fifo_lock );
p_aout->i_nb_inputs = 0; p_aout->i_nb_inputs = 0;
p_aout->mixer.f_multiplier = 1.0; p_aout->mixer.f_multiplier = 1.0;
p_aout->mixer.b_error = 1;
vlc_object_attach( p_aout, p_parent->p_vlc ); vlc_object_attach( p_aout, p_parent->p_vlc );
...@@ -67,9 +65,9 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent ) ...@@ -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->input_fifos_lock );
vlc_mutex_destroy( &p_aout->mixer_lock ); vlc_mutex_destroy( &p_aout->mixer_lock );
...@@ -81,77 +79,7 @@ void aout_DeleteInstance( aout_instance_t * p_aout ) ...@@ -81,77 +79,7 @@ void aout_DeleteInstance( aout_instance_t * p_aout )
/* /*
* Buffer management (interface to the decoders) * Formats management (internal and external)
*/
/*****************************************************************************
* 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
*/ */
/***************************************************************************** /*****************************************************************************
......
/*****************************************************************************
* 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;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input.c : internal management of input streams for the audio output * input.c : internal management of input streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -39,84 +39,12 @@ ...@@ -39,84 +39,12 @@
/***************************************************************************** /*****************************************************************************
* aout_InputNew : allocate a new input and rework the filter pipeline * aout_InputNew : allocate a new input and rework the filter pipeline
*****************************************************************************/ *****************************************************************************/
static aout_input_t * InputNew( aout_instance_t * p_aout, int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input )
audio_sample_format_t * p_format )
{ {
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. */ /* Prepare FIFO. */
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate ); aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
p_input->p_first_byte_to_mix = NULL; 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. */ /* Create filters. */
if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
&p_input->i_nb_filters, &p_input->input, &p_input->i_nb_filters, &p_input->input,
...@@ -124,25 +52,10 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -124,25 +52,10 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{ {
msg_Err( p_aout, "couldn't set an input pipeline" ); 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 ); aout_FifoDestroy( p_aout, &p_input->fifo );
vlc_mutex_unlock( &p_input->lock ); p_input->b_error = 1;
vlc_mutex_destroy( &p_input->lock );
free( p_input );
vlc_mutex_unlock( &p_aout->mixer_lock );
return NULL; return -1;
} }
/* Prepare hints for the buffer allocator. */ /* Prepare hints for the buffer allocator. */
...@@ -162,149 +75,43 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -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. */ /* Allocate in the heap, it is more convenient for the decoder. */
p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP; p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
vlc_mutex_unlock( &p_input->lock ); p_input->b_error = 0;
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 );
}
return InputNew( *pp_aout, p_format ); return 0;
} }
/***************************************************************************** /*****************************************************************************
* aout_InputDelete : delete an input * 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. * This function must be entered with the mixer lock.
* It returns -1 if the input pipeline couldn't be created. Please remember
* to call aout_MixerNew() afterwards.
*****************************************************************************/ *****************************************************************************/
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, aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
p_input->i_nb_filters ); p_input->i_nb_filters );
aout_FifoDestroy( p_aout, &p_input->fifo ); 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; return 0;
} }
/***************************************************************************** /*****************************************************************************
* aout_InputPlay : play a buffer * 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, int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer ) aout_buffer_t * p_buffer )
{ {
mtime_t start_date, duration; 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 /* 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 * this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */ * with the next incoming buffer. */
vlc_mutex_lock( &p_aout->input_fifos_lock );
start_date = aout_FifoNextStart( p_aout, &p_input->fifo ); start_date = aout_FifoNextStart( p_aout, &p_input->fifo );
vlc_mutex_unlock( &p_aout->input_fifos_lock );
if ( start_date != 0 && start_date < mdate() ) if ( start_date != 0 && start_date < mdate() )
{ {
...@@ -420,12 +227,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -420,12 +227,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
&p_buffer ); &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(). */ /* Adding the start date will be managed by aout_FifoPush(). */
p_buffer->start_date = start_date; p_buffer->start_date = start_date;
p_buffer->end_date = start_date + duration; p_buffer->end_date = start_date + duration;
vlc_mutex_lock( &p_aout->input_fifos_lock );
aout_FifoPush( p_aout, &p_input->fifo, p_buffer ); aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* intf.c : audio output API towards the interface modules * intf.c : audio output API towards the interface modules
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "audio_output.h" #include "audio_output.h"
#include "aout_internal.h" #include "aout_internal.h"
/* /*
* Volume management * Volume management
* *
...@@ -64,7 +65,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) ...@@ -64,7 +65,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
vlc_mutex_lock( &p_aout->mixer_lock ); 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. */ /* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
...@@ -87,7 +88,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume ) ...@@ -87,7 +88,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume )
vlc_mutex_lock( &p_aout->mixer_lock ); 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. */ /* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
...@@ -110,7 +111,7 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft ) ...@@ -110,7 +111,7 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
vlc_mutex_lock( &p_aout->mixer_lock ); 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. */ /* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
...@@ -138,7 +139,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps, ...@@ -138,7 +139,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps,
vlc_mutex_lock( &p_aout->mixer_lock ); 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. */ /* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
...@@ -177,7 +178,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps, ...@@ -177,7 +178,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps,
vlc_mutex_lock( &p_aout->mixer_lock ); 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. */ /* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
...@@ -275,10 +276,82 @@ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume ) ...@@ -275,10 +276,82 @@ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
return -1; return -1;
} }
/* Placeholder for pf_volume_set(). */ /* Placeholder for pf_volume_set(). */
int aout_VolumeNoneSet( aout_instance_t * p_aout, audio_volume_t i_volume ) int aout_VolumeNoneSet( aout_instance_t * p_aout, audio_volume_t i_volume )
{ {
return -1; 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;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations * mixer.c : audio output mixing operations
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -49,6 +49,7 @@ int aout_MixerNew( aout_instance_t * p_aout ) ...@@ -49,6 +49,7 @@ int aout_MixerNew( aout_instance_t * p_aout )
msg_Err( p_aout, "no suitable aout mixer" ); msg_Err( p_aout, "no suitable aout mixer" );
return -1; return -1;
} }
p_aout->mixer.b_error = 0;
return 0; return 0;
} }
...@@ -57,22 +58,48 @@ int aout_MixerNew( aout_instance_t * p_aout ) ...@@ -57,22 +58,48 @@ int aout_MixerNew( aout_instance_t * p_aout )
***************************************************************************** *****************************************************************************
* Please note that you must hold the mixer lock. * 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 ); module_Unneed( p_aout, p_aout->mixer.p_module );
p_aout->mixer.b_error = 1;
return 0;
} }
/***************************************************************************** /*****************************************************************************
* MixBuffer: try to prepare one output buffer * MixBuffer: try to prepare one output buffer
*****************************************************************************
* Please note that you must hold the mixer lock.
*****************************************************************************/ *****************************************************************************/
static int MixBuffer( aout_instance_t * p_aout ) static int MixBuffer( aout_instance_t * p_aout )
{ {
int i; int i, i_nb_real_inputs = 0;
aout_buffer_t * p_output_buffer; aout_buffer_t * p_output_buffer;
mtime_t start_date, end_date; mtime_t start_date, end_date;
audio_date_t exact_start_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->output_fifo_lock );
vlc_mutex_lock( &p_aout->input_fifos_lock ); vlc_mutex_lock( &p_aout->input_fifos_lock );
...@@ -125,7 +152,6 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -125,7 +152,6 @@ static int MixBuffer( aout_instance_t * p_aout )
{ {
/* Interrupted before the end... We can't run. */ /* Interrupted before the end... We can't run. */
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1; return -1;
} }
} }
...@@ -143,6 +169,7 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -143,6 +169,7 @@ static int MixBuffer( aout_instance_t * p_aout )
vlc_bool_t b_drop_buffers; vlc_bool_t b_drop_buffers;
if ( p_input->b_error ) continue; if ( p_input->b_error ) continue;
i_nb_real_inputs++;
p_buffer = p_fifo->p_first; p_buffer = p_fifo->p_first;
if ( p_buffer == NULL ) if ( p_buffer == NULL )
...@@ -241,11 +268,10 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -241,11 +268,10 @@ static int MixBuffer( aout_instance_t * p_aout )
if ( p_buffer == NULL ) break; 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. */ /* Interrupted before the end... We can't run. */
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1; return -1;
} }
...@@ -261,7 +287,6 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -261,7 +287,6 @@ static int MixBuffer( aout_instance_t * p_aout )
{ {
msg_Err( p_aout, "out of memory" ); msg_Err( p_aout, "out of memory" );
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1; return -1;
} }
/* This is again a bit kludgy - for the S/PDIF mixer. */ /* This is again a bit kludgy - for the S/PDIF mixer. */
...@@ -281,13 +306,13 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -281,13 +306,13 @@ static int MixBuffer( aout_instance_t * p_aout )
aout_OutputPlay( p_aout, p_output_buffer ); aout_OutputPlay( p_aout, p_output_buffer );
vlc_mutex_unlock( &p_aout->mixer_lock );
return 0; return 0;
} }
/***************************************************************************** /*****************************************************************************
* aout_MixerRun: entry point for the mixer & post-filters processing * 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 ) void aout_MixerRun( aout_instance_t * p_aout )
{ {
...@@ -303,12 +328,17 @@ 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 ) int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier )
{ {
float f_old = p_aout->mixer.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; 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; p_aout->mixer.f_multiplier = f_old;
aout_MixerNew( p_aout ); aout_MixerNew( p_aout );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* output.c : internal management of output streams for the audio output * output.c : internal management of output streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
/***************************************************************************** /*****************************************************************************
* aout_OutputNew : allocate a new output and rework the filter pipeline * 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, int aout_OutputNew( aout_instance_t * p_aout,
audio_sample_format_t * p_format ) audio_sample_format_t * p_format )
...@@ -132,7 +132,7 @@ int aout_OutputNew( aout_instance_t * p_aout, ...@@ -132,7 +132,7 @@ int aout_OutputNew( aout_instance_t * p_aout,
/***************************************************************************** /*****************************************************************************
* aout_OutputDelete : delete the output * 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 ) void aout_OutputDelete( aout_instance_t * p_aout )
{ {
...@@ -146,7 +146,7 @@ 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 * 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 ) 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 ) ...@@ -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 * 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 * 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. * 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, aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
mtime_t start_date, mtime_t start_date,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libvlc.c: main libvlc source * libvlc.c: main libvlc source
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2002 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -677,7 +677,7 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc ) ...@@ -677,7 +677,7 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
{ {
vlc_object_detach( (vlc_object_t *)p_aout ); vlc_object_detach( (vlc_object_t *)p_aout );
vlc_object_release( (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 */ /* Update the handle status */
......
...@@ -184,23 +184,24 @@ static const char * module_error( char *psz_buffer ) ...@@ -184,23 +184,24 @@ static const char * module_error( char *psz_buffer )
(p_symbols)->aout_FifoPop_inner = aout_FifoPop; \ (p_symbols)->aout_FifoPop_inner = aout_FifoPop; \
(p_symbols)->aout_VolumeSoftInit_inner = aout_VolumeSoftInit; \ (p_symbols)->aout_VolumeSoftInit_inner = aout_VolumeSoftInit; \
(p_symbols)->aout_VolumeNoneInit_inner = aout_VolumeNoneInit; \ (p_symbols)->aout_VolumeNoneInit_inner = aout_VolumeNoneInit; \
(p_symbols)->__aout_NewInstance_inner = __aout_NewInstance; \ (p_symbols)->__aout_New_inner = __aout_New; \
(p_symbols)->aout_DeleteInstance_inner = aout_DeleteInstance; \ (p_symbols)->aout_Delete_inner = aout_Delete; \
(p_symbols)->aout_BufferNew_inner = aout_BufferNew; \
(p_symbols)->aout_BufferDelete_inner = aout_BufferDelete; \
(p_symbols)->aout_BufferPlay_inner = aout_BufferPlay; \
(p_symbols)->aout_DateInit_inner = aout_DateInit; \ (p_symbols)->aout_DateInit_inner = aout_DateInit; \
(p_symbols)->aout_DateSet_inner = aout_DateSet; \ (p_symbols)->aout_DateSet_inner = aout_DateSet; \
(p_symbols)->aout_DateMove_inner = aout_DateMove; \ (p_symbols)->aout_DateMove_inner = aout_DateMove; \
(p_symbols)->aout_DateGet_inner = aout_DateGet; \ (p_symbols)->aout_DateGet_inner = aout_DateGet; \
(p_symbols)->aout_DateIncrement_inner = aout_DateIncrement; \ (p_symbols)->aout_DateIncrement_inner = aout_DateIncrement; \
(p_symbols)->__aout_InputNew_inner = __aout_InputNew; \ (p_symbols)->__aout_DecNew_inner = __aout_DecNew; \
(p_symbols)->aout_InputDelete_inner = aout_InputDelete; \ (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_VolumeGet_inner = aout_VolumeGet; \
(p_symbols)->aout_VolumeSet_inner = aout_VolumeSet; \ (p_symbols)->aout_VolumeSet_inner = aout_VolumeSet; \
(p_symbols)->aout_VolumeInfos_inner = aout_VolumeInfos; \ (p_symbols)->aout_VolumeInfos_inner = aout_VolumeInfos; \
(p_symbols)->aout_VolumeUp_inner = aout_VolumeUp; \ (p_symbols)->aout_VolumeUp_inner = aout_VolumeUp; \
(p_symbols)->aout_VolumeDown_inner = aout_VolumeDown; \ (p_symbols)->aout_VolumeDown_inner = aout_VolumeDown; \
(p_symbols)->aout_Restart_inner = aout_Restart; \
(p_symbols)->__config_GetInt_inner = __config_GetInt; \ (p_symbols)->__config_GetInt_inner = __config_GetInt; \
(p_symbols)->__config_PutInt_inner = __config_PutInt; \ (p_symbols)->__config_PutInt_inner = __config_PutInt; \
(p_symbols)->__config_GetFloat_inner = __config_GetFloat; \ (p_symbols)->__config_GetFloat_inner = __config_GetFloat; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment