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
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
......
......@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout_internal.h,v 1.20 2002/09/20 23:27:03 massiot Exp $
* $Id: aout_internal.h,v 1.21 2002/09/26 22:40:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -120,6 +120,8 @@ typedef struct aout_mixer_t
void (* pf_do_work)( struct aout_instance_t *,
struct aout_buffer_t * );
/* If b_error == 1, there is no mixer nor audio output pipeline. */
vlc_bool_t b_error;
/* Multiplier used to raise or lower the volume of the sound in
* software. Beware, this creates sound distortion and should be avoided
* as much as possible. This isn't available for non-float32 mixer. */
......@@ -147,8 +149,10 @@ struct aout_input_t
/* Mixer information */
byte_t * p_first_byte_to_mix;
/* Is the input dead ? */
/* If b_error == 1, there is no input pipeline. */
vlc_bool_t b_error;
/* Did we just change the output format ? (expect buffer inconsistencies) */
vlc_bool_t b_changed;
};
/*****************************************************************************
......@@ -186,7 +190,7 @@ struct aout_instance_t
/* Locks : please note that if you need several of these locks, it is
* mandatory (to avoid deadlocks) to take them in the following order :
* p_input->lock, mixer_lock, output_fifo_lock, input_fifos_lock.
* mixer_lock, p_input->lock, output_fifo_lock, input_fifos_lock.
* --Meuuh */
/* When input_fifos_lock is taken, none of the p_input->fifo structures
* can be read or modified by a third-party thread. */
......@@ -214,6 +218,8 @@ struct aout_instance_t
* Prototypes
*****************************************************************************/
/* From input.c : */
int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input );
int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input );
int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer );
......@@ -235,7 +241,7 @@ void aout_FiltersPlay( aout_instance_t * p_aout,
/* From mixer.c : */
int aout_MixerNew( aout_instance_t * p_aout );
void aout_MixerDelete( aout_instance_t * p_aout );
int aout_MixerDelete( aout_instance_t * p_aout );
void aout_MixerRun( aout_instance_t * p_aout );
int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier );
int aout_MixerMultiplierGet( aout_instance_t * p_aout, float * pf_multiplier );
......@@ -247,7 +253,7 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer );
void aout_OutputDelete( aout_instance_t * p_aout );
VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
/* From audio_output.c : */
/* From common.c : */
VLC_EXPORT( int, aout_FormatNbChannels, ( audio_sample_format_t * p_format ) );
void aout_FormatPrepare( audio_sample_format_t * p_format );
void aout_FifoInit( aout_instance_t *, aout_fifo_t *, u32 );
......
......@@ -2,7 +2,7 @@
* audio_output.h : audio output interface
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.66 2002/09/20 23:27:03 massiot Exp $
* $Id: audio_output.h,v 1.67 2002/09/26 22:40:18 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -168,23 +168,23 @@ struct audio_date_t
/*****************************************************************************
* Prototypes
*****************************************************************************/
/* From audio_output.c : */
#define aout_NewInstance(a) __aout_NewInstance(VLC_OBJECT(a))
VLC_EXPORT( aout_instance_t *, __aout_NewInstance, ( vlc_object_t * ) );
VLC_EXPORT( void, aout_DeleteInstance, ( aout_instance_t * ) );
VLC_EXPORT( aout_buffer_t *, aout_BufferNew, ( aout_instance_t *, aout_input_t *, size_t ) );
VLC_EXPORT( void, aout_BufferDelete, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
VLC_EXPORT( int, aout_BufferPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
/* From common.c : */
#define aout_New(a) __aout_New(VLC_OBJECT(a))
VLC_EXPORT( aout_instance_t *, __aout_New, ( vlc_object_t * ) );
VLC_EXPORT( void, aout_Delete, ( aout_instance_t * ) );
VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) );
VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) );
VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) );
VLC_EXPORT( mtime_t, aout_DateGet, ( const audio_date_t * ) );
VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, u32 ) );
/* From input.c : */
#define aout_InputNew(a,b,c) __aout_InputNew(VLC_OBJECT(a),b,c)
VLC_EXPORT( aout_input_t *, __aout_InputNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );
VLC_EXPORT( void, aout_InputDelete, ( aout_instance_t *, aout_input_t * ) );
/* From dec.c : */
#define aout_DecNew(a, b, c) __aout_DecNew(VLC_OBJECT(a), b, c)
VLC_EXPORT( aout_input_t *, __aout_DecNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) );
VLC_EXPORT( int, aout_DecDelete, ( aout_instance_t *, aout_input_t * ) );
VLC_EXPORT( aout_buffer_t *, aout_DecNewBuffer, ( aout_instance_t *, aout_input_t *, size_t ) );
VLC_EXPORT( void, aout_DecDeleteBuffer, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
VLC_EXPORT( int, aout_DecPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
/* From intf.c : */
VLC_EXPORT( int, aout_VolumeGet, ( aout_instance_t *, audio_volume_t * ) );
......@@ -192,4 +192,5 @@ VLC_EXPORT( int, aout_VolumeSet, ( aout_instance_t *, audio_volume_t ) );
VLC_EXPORT( int, aout_VolumeInfos, ( aout_instance_t *, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
......@@ -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
......
......@@ -3,7 +3,7 @@
* with endianness change
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: s16tofloat32swab.c,v 1.3 2002/09/20 23:27:03 massiot Exp $
* $Id: s16tofloat32swab.c,v 1.4 2002/09/26 22:40:19 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
......@@ -115,7 +115,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
#ifndef HAVE_SWAB
p_tmp[0] = ((byte_t *)p_in)[1];
p_tmp[1] = ((byte_t *)p_in)[0];
*p_out = (float)*( *(s16 *)p_tmp ) / 32768.0;
*p_out = (float)( *(s16 *)p_tmp ) / 32768.0;
#else
*p_out = (float)*p_in / 32768.0;
#endif
......
......@@ -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: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -174,7 +174,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
|| (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
{
/* Parameters changed - this should not happen. */
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
p_dec->p_aout_input = NULL;
}
......@@ -186,9 +186,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
p_dec->output_format.i_bytes_per_frame = i_frame_size;
p_dec->output_format.i_frame_length = A52_FRAME_NB;
aout_DateInit( &end_date, i_rate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
if ( p_dec->p_aout_input == NULL )
{
......@@ -206,8 +206,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
continue;
}
p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input,
A52_FRAME_NB );
p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input,
A52_FRAME_NB );
if ( p_buffer == NULL ) return -1;
p_buffer->start_date = aout_DateGet( &end_date );
p_buffer->end_date = aout_DateIncrement( &end_date,
......@@ -219,13 +219,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
i_frame_size - 7 );
if( p_dec->p_fifo->b_die )
{
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
p_buffer );
aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
p_buffer );
break;
}
/* Send the buffer to the mixer. */
aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
}
/* If b_error is set, the spdif thread enters the error loop */
......@@ -247,7 +247,7 @@ static void EndThread( dec_thread_t * p_dec )
{
if ( p_dec->p_aout_input != NULL )
{
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
free( p_dec );
......
......@@ -2,7 +2,7 @@
* a52old.c: A52 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: a52old.c,v 1.6 2002/08/30 22:22:24 massiot Exp $
* $Id: a52old.c,v 1.7 2002/09/26 22:40:20 massiot Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
......@@ -167,7 +167,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
{
/* Delete old output */
msg_Warn( p_a52dec->p_fifo, "opening a new aout" );
aout_InputDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
aout_DecDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
}
/* Set output configuration */
......@@ -175,9 +175,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
output_format.i_channels = 2; /* FIXME ! */
output_format.i_rate = sync_info.sample_rate;
aout_DateInit( &end_date, output_format.i_rate );
p_a52dec->p_aout_input = aout_InputNew( p_a52dec->p_fifo,
&p_a52dec->p_aout,
&output_format );
p_a52dec->p_aout_input = aout_DecNew( p_a52dec->p_fifo,
&p_a52dec->p_aout,
&output_format );
}
if( p_a52dec->p_aout_input == NULL )
......@@ -198,9 +198,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
continue;
}
p_aout_buffer = aout_BufferNew( p_a52dec->p_aout,
p_a52dec->p_aout_input,
A52DEC_FRAME_SIZE );
p_aout_buffer = aout_DecNewBuffer( p_a52dec->p_aout,
p_a52dec->p_aout_input,
A52DEC_FRAME_SIZE );
if( !p_aout_buffer )
{
msg_Err( p_a52dec->p_fifo, "cannot get aout buffer" );
......@@ -215,14 +215,14 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if (decode_frame (p_a52dec, (s16*)p_aout_buffer->p_buffer))
{
b_sync = 0;
aout_BufferDelete( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer );
aout_DecDeleteBuffer( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer );
continue;
}
else
{
aout_BufferPlay( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer );
aout_DecPlay( p_a52dec->p_aout, p_a52dec->p_aout_input,
p_aout_buffer );
}
RealignBits(&p_a52dec->bit_stream);
......@@ -344,7 +344,7 @@ static void EndThread (a52dec_t * p_a52dec)
/* If the audio output fifo was created, we destroy it */
if( p_a52dec->p_aout_input )
{
aout_InputDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
aout_DecDelete( p_a52dec->p_aout, p_a52dec->p_aout_input );
}
/* Free allocated structures */
......
......@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: decoder.c,v 1.2 2002/08/23 14:05:22 sam Exp $
* $Id: decoder.c,v 1.3 2002/09/26 22:40:21 massiot Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -447,15 +447,15 @@ static void DecodeThread( adec_thread_t *p_adec )
if( p_adec->p_aout_input )
{
/* **** Delete the old **** */
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
}
/* **** Create a new audio output **** */
p_adec->output_format.i_channels = faad_frame.channels;
aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
p_adec->p_aout_input = aout_InputNew( p_adec->p_fifo,
&p_adec->p_aout,
&p_adec->output_format );
p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
&p_adec->p_aout,
&p_adec->output_format );
}
if( !p_adec->p_aout_input )
......@@ -473,9 +473,9 @@ static void DecodeThread( adec_thread_t *p_adec )
return;
}
p_aout_buffer = aout_BufferNew( p_adec->p_aout,
p_adec->p_aout_input,
faad_frame.samples / faad_frame.channels );
p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
p_adec->p_aout_input,
faad_frame.samples / faad_frame.channels );
if( !p_aout_buffer )
{
msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
......@@ -490,7 +490,7 @@ static void DecodeThread( adec_thread_t *p_adec )
p_faad_buffer,
p_aout_buffer->i_nb_bytes );
aout_BufferPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
}
......@@ -501,7 +501,7 @@ static void EndThread (adec_thread_t *p_adec)
{
if( p_adec->p_aout_input )
{
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
}
if( p_adec->p_handle )
......
......@@ -2,7 +2,7 @@
* lpcm.c: lpcm decoder module
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: lpcm.c,v 1.1 2002/09/20 23:27:03 massiot Exp $
* $Id: lpcm.c,v 1.2 2002/09/26 22:40:20 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
......@@ -131,9 +131,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
p_dec->output_format.i_rate = 48000;
aout_DateInit( &p_dec->end_date, 48000 );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
if ( p_dec->p_aout_input == NULL )
{
......@@ -175,9 +175,9 @@ void DecodeFrame( dec_thread_t * p_dec )
aout_DateSet( &p_dec->end_date, i_pts );
}
p_aout_buffer = aout_BufferNew( p_dec->p_aout,
p_dec->p_aout_input,
LPCM_FRAME_NB );
p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
p_dec->p_aout_input,
LPCM_FRAME_NB );
if( !p_aout_buffer )
{
......@@ -200,13 +200,13 @@ void DecodeFrame( dec_thread_t * p_dec )
if( p_dec->p_fifo->b_die )
{
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
return;
}
aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
}
/*****************************************************************************
......@@ -216,7 +216,7 @@ static void EndThread( dec_thread_t * p_dec )
{
if( p_dec->p_aout_input != NULL )
{
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
free( p_dec );
......
......@@ -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;
}
......
......@@ -2,7 +2,7 @@
* decoder.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: decoder.c,v 1.3 2002/08/26 23:00:22 massiot Exp $
* $Id: decoder.c,v 1.4 2002/09/26 22:40:23 massiot Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
......@@ -174,7 +174,7 @@ static void DecodeThread( adec_thread_t * p_dec )
{
/* Delete old output */
msg_Warn( p_dec->p_fifo, "opening a new aout" );
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
/* Set output configuration */
......@@ -182,9 +182,9 @@ static void DecodeThread( adec_thread_t * p_dec )
p_dec->output_format.i_channels = ( sync_info.b_stereo ? 2 : 1 );
p_dec->output_format.i_rate = sync_info.sample_rate;
aout_DateInit( &p_dec->end_date, sync_info.sample_rate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout,
&p_dec->output_format );
}
if( p_dec->p_aout_input == NULL )
......@@ -200,9 +200,9 @@ static void DecodeThread( adec_thread_t * p_dec )
return;
}
p_aout_buffer = aout_BufferNew( p_dec->p_aout,
p_dec->p_aout_input,
ADEC_FRAME_NB );
p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
p_dec->p_aout_input,
ADEC_FRAME_NB );
if( !p_aout_buffer )
{
msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
......@@ -216,11 +216,11 @@ static void DecodeThread( adec_thread_t * p_dec )
if( adec_DecodeFrame (p_dec, (float*)p_aout_buffer->p_buffer ) )
{
/* Ouch, failed decoding... We'll have to resync */
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
}
else
{
aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
}
}
}
......@@ -236,7 +236,7 @@ static void EndThread ( adec_thread_t *p_dec )
/* If the audio output fifo was created, we destroy it */
if( p_dec->p_aout_input )
{
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
}
......
......@@ -2,7 +2,7 @@
* mpeg_ts.c : Transport Stream input module for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: ts.c,v 1.5 2002/09/23 23:05:58 massiot Exp $
* $Id: ts.c,v 1.6 2002/09/26 22:40:24 massiot Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
* Johan Bilien <jobi@via.ecp.fr>
......@@ -907,7 +907,6 @@ void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt )
p_new_es->i_stream_id = 0xBD;
break;
case DVD_SPU_ES:
case A52_AUDIO_ES:
if ( !b_vls_compat )
p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
else
......
/*****************************************************************************
* 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 <massiot@via.ecp.fr>
*
......@@ -29,21 +29,18 @@
#include <vlc/vlc.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "audio_output.h"
#include "aout_internal.h"
/*
* Instances management (see also input.c:aout_InputNew())
* 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)
*/
/*****************************************************************************
......
/*****************************************************************************
* 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 @@
* input.c : internal management of input streams for the audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: input.c,v 1.12 2002/09/20 23:27:04 massiot Exp $
* $Id: input.c,v 1.13 2002/09/26 22:40:25 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -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 );
......
......@@ -2,7 +2,7 @@
* intf.c : audio output API towards the interface modules
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: intf.c,v 1.3 2002/09/19 21:56:40 massiot Exp $
* $Id: intf.c,v 1.4 2002/09/26 22:40:25 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -32,6 +32,7 @@
#include "audio_output.h"
#include "aout_internal.h"
/*
* Volume management
*
......@@ -64,7 +65,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock );
......@@ -87,7 +88,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume )
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock );
......@@ -110,7 +111,7 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock );
......@@ -138,7 +139,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps,
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock );
......@@ -177,7 +178,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps,
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
vlc_mutex_unlock( &p_aout->mixer_lock );
......@@ -275,10 +276,82 @@ int aout_VolumeNoneGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
return -1;
}
/* Placeholder for pf_volume_set(). */
int aout_VolumeNoneSet( aout_instance_t * p_aout, audio_volume_t i_volume )
{
return -1;
}
/*
* Pipelines management
*/
/*****************************************************************************
* aout_Restart : re-open the output device and rebuild the input and output
* pipelines
*****************************************************************************
* This function is used whenever the parameters of the output plug-in are
* changed (eg. selecting S/PDIF or PCM).
*****************************************************************************/
int aout_Restart( aout_instance_t * p_aout )
{
int i;
vlc_bool_t b_error = 0;
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->i_nb_inputs == 0 )
{
vlc_mutex_unlock( &p_aout->mixer_lock );
msg_Err( p_aout, "no decoder thread" );
return -1;
}
/* Lock all inputs. */
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
}
aout_MixerDelete( p_aout );
/* Re-open the output plug-in. */
aout_OutputDelete( p_aout );
if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 )
{
/* Release all locks and report the error. */
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
}
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1;
}
if ( aout_MixerNew( p_aout ) == -1 )
{
aout_OutputDelete( p_aout );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
}
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1;
}
/* Re-open all inputs. */
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_input_t * p_input = p_aout->pp_inputs[i];
b_error |= aout_InputNew( p_aout, p_input );
vlc_mutex_unlock( &p_input->lock );
}
vlc_mutex_unlock( &p_aout->mixer_lock );
return b_error;
}
......@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: mixer.c,v 1.15 2002/09/23 23:05:58 massiot Exp $
* $Id: mixer.c,v 1.16 2002/09/26 22:40:25 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -49,6 +49,7 @@ int aout_MixerNew( aout_instance_t * p_aout )
msg_Err( p_aout, "no suitable aout mixer" );
return -1;
}
p_aout->mixer.b_error = 0;
return 0;
}
......@@ -57,22 +58,48 @@ int aout_MixerNew( aout_instance_t * p_aout )
*****************************************************************************
* Please note that you must hold the mixer lock.
*****************************************************************************/
void aout_MixerDelete( aout_instance_t * p_aout )
int aout_MixerDelete( aout_instance_t * p_aout )
{
if ( p_aout->mixer.b_error ) return 0;
module_Unneed( p_aout, p_aout->mixer.p_module );
p_aout->mixer.b_error = 1;
return 0;
}
/*****************************************************************************
* MixBuffer: try to prepare one output buffer
*****************************************************************************
* Please note that you must hold the mixer lock.
*****************************************************************************/
static int MixBuffer( aout_instance_t * p_aout )
{
int i;
int i, i_nb_real_inputs = 0;
aout_buffer_t * p_output_buffer;
mtime_t start_date, end_date;
audio_date_t exact_start_date;
vlc_mutex_lock( &p_aout->mixer_lock );
if ( p_aout->mixer.b_error )
{
/* Free all incoming buffers. */
vlc_mutex_lock( &p_aout->input_fifos_lock );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_input_t * p_input = p_aout->pp_inputs[i];
aout_buffer_t * p_buffer = p_input->fifo.p_first;
if ( p_input->b_error ) continue;
while ( p_buffer != NULL )
{
aout_buffer_t * p_next = p_buffer->p_next;
aout_BufferFree( p_buffer );
p_buffer = p_next;
}
}
vlc_mutex_unlock( &p_aout->input_fifos_lock );
return -1;
}
vlc_mutex_lock( &p_aout->output_fifo_lock );
vlc_mutex_lock( &p_aout->input_fifos_lock );
......@@ -125,7 +152,6 @@ static int MixBuffer( aout_instance_t * p_aout )
{
/* Interrupted before the end... We can't run. */
vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1;
}
}
......@@ -143,6 +169,7 @@ static int MixBuffer( aout_instance_t * p_aout )
vlc_bool_t b_drop_buffers;
if ( p_input->b_error ) continue;
i_nb_real_inputs++;
p_buffer = p_fifo->p_first;
if ( p_buffer == NULL )
......@@ -241,11 +268,10 @@ static int MixBuffer( aout_instance_t * p_aout )
if ( p_buffer == NULL ) break;
}
if ( i < p_aout->i_nb_inputs )
if ( i < p_aout->i_nb_inputs || !i_nb_real_inputs )
{
/* Interrupted before the end... We can't run. */
vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1;
}
......@@ -261,7 +287,6 @@ static int MixBuffer( aout_instance_t * p_aout )
{
msg_Err( p_aout, "out of memory" );
vlc_mutex_unlock( &p_aout->input_fifos_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return -1;
}
/* This is again a bit kludgy - for the S/PDIF mixer. */
......@@ -281,13 +306,13 @@ static int MixBuffer( aout_instance_t * p_aout )
aout_OutputPlay( p_aout, p_output_buffer );
vlc_mutex_unlock( &p_aout->mixer_lock );
return 0;
}
/*****************************************************************************
* aout_MixerRun: entry point for the mixer & post-filters processing
*****************************************************************************
* Please note that you must hold the mixer lock.
*****************************************************************************/
void aout_MixerRun( aout_instance_t * p_aout )
{
......@@ -303,12 +328,17 @@ void aout_MixerRun( aout_instance_t * p_aout )
int aout_MixerMultiplierSet( aout_instance_t * p_aout, float f_multiplier )
{
float f_old = p_aout->mixer.f_multiplier;
vlc_bool_t b_new_mixer = 0;
aout_MixerDelete( p_aout );
if ( !p_aout->mixer.b_error )
{
aout_MixerDelete( p_aout );
b_new_mixer = 1;
}
p_aout->mixer.f_multiplier = f_multiplier;
if ( aout_MixerNew( p_aout ) )
if ( b_new_mixer && aout_MixerNew( p_aout ) )
{
p_aout->mixer.f_multiplier = f_old;
aout_MixerNew( p_aout );
......
......@@ -2,7 +2,7 @@
* output.c : internal management of output streams for the audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: output.c,v 1.14 2002/08/30 23:27:06 massiot Exp $
* $Id: output.c,v 1.15 2002/09/26 22:40:25 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -35,7 +35,7 @@
/*****************************************************************************
* aout_OutputNew : allocate a new output and rework the filter pipeline
*****************************************************************************
* This function is entered with the mixer_lock.
* This function is entered with the mixer lock.
*****************************************************************************/
int aout_OutputNew( aout_instance_t * p_aout,
audio_sample_format_t * p_format )
......@@ -132,7 +132,7 @@ int aout_OutputNew( aout_instance_t * p_aout,
/*****************************************************************************
* aout_OutputDelete : delete the output
*****************************************************************************
* This function is entered with the mixer_lock.
* This function is entered with the mixer lock.
*****************************************************************************/
void aout_OutputDelete( aout_instance_t * p_aout )
{
......@@ -146,7 +146,7 @@ void aout_OutputDelete( aout_instance_t * p_aout )
/*****************************************************************************
* aout_OutputPlay : play a buffer
*****************************************************************************
* This function is entered with the mixer_lock.
* This function is entered with the mixer lock.
*****************************************************************************/
void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{
......@@ -166,6 +166,7 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
* If b_can_sleek is 1, the aout core functions won't try to resample
* new buffers to catch up - that is we suppose that the output plug-in can
* compensate it by itself. S/PDIF outputs should always set b_can_sleek = 1.
* This function is entered with no lock at all :-).
*****************************************************************************/
aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
mtime_t start_date,
......
......@@ -2,7 +2,7 @@
* libvlc.c: main libvlc source
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: libvlc.c,v 1.31 2002/09/17 14:56:13 sam Exp $
* $Id: libvlc.c,v 1.32 2002/09/26 22:40:24 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -677,7 +677,7 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
{
vlc_object_detach( (vlc_object_t *)p_aout );
vlc_object_release( (vlc_object_t *)p_aout );
aout_DeleteInstance( p_aout );
aout_Delete( p_aout );
}
/* Update the handle status */
......
......@@ -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; \
......
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