Commit 5ffbc97e authored by Christophe Massiot's avatar Christophe Massiot

* ./configure: Fixed double detection of gethostbyname.

* Major changes in the handling of dates in the audio output ; still buggy,
but differently.
* Fixed a major bug in the aout pre-filters, preventing to run any other
decoder than liba52.
* p_aout->output.pf_play now has only one argument.
parent 91b103c2
This diff is collapsed.
......@@ -147,10 +147,8 @@ AC_CHECK_FUNC(send,,[
http_LDFLAGS="${http_LDFLAGS} -lsocket"
)])
AC_CHECK_FUNC(gethostbyname,,[
AC_CHECK_LIB(nsl,gethostbyname,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lnsl")
])
AC_CHECK_FUNC(gethostbyname,,[
AC_CHECK_LIB(bind,gethostbyname,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lbind")
AC_CHECK_LIB(nsl,gethostbyname,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lnsl",[
AC_CHECK_LIB(bind,gethostbyname,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lbind")])
])
have_nanosleep=0
AC_CHECK_FUNC(nanosleep,have_nanosleep=1,[
......
......@@ -3,18 +3,24 @@
MAX_TEX_RECURSION=4
# For Debian :
XML_DECL=/usr/lib/sgml/declaration/xml.decl
HTML_SS=/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/html/docbook.dsl
PRINT_SS=/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/print/docbook.dsl
#XML_DECL=/usr/lib/sgml/declaration/xml.decl
#HTML_SS=/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/html/docbook.dsl
#PRINT_SS=/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/print/docbook.dsl
# For RedHat :
#XML_DECL=/usr/lib/sgml/stylesheets/nwalsh-modular/dtds/decls/xml.dcl
#HTML_SS=/usr/lib/sgml/stylesheets/nwalsh-modular/html/docbook.dsl
#PRINT_SS=/usr/lib/sgml/stylesheets/nwalsh-modular/print/docbook.dsl
# For Mac OS X :
#XML_DECL=/usr/lib/sgml/declaration/xml.decl
HTML_SS=/sw/share/sgml/dsssl/docbook-dsssl-nwalsh/html/docbook.dsl
PRINT_SS=/sw/share/sgml/dsssl/docbook-dsssl-nwalsh/print/docbook.dsl
all: manual
JADE=jade
#JADE=jade
JADE=openjade
manual: manual.txt manual.ps manual.html
......
......@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout_internal.h,v 1.5 2002/08/14 00:43:51 massiot Exp $
* $Id: aout_internal.h,v 1.6 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -27,8 +27,7 @@
typedef struct aout_alloc_t
{
int i_alloc_type;
int i_bytes_per_sec; /* -1 if only the alloc_type is
* relevant. */
int i_bytes_per_sec;
} aout_alloc_t;
#define AOUT_ALLOC_NONE 0
......@@ -86,6 +85,7 @@ typedef struct aout_fifo_t
vlc_mutex_t lock;
struct aout_buffer_t * p_first;
struct aout_buffer_t ** pp_last;
mtime_t end_date;
} aout_fifo_t;
static inline void aout_FifoInit( struct aout_instance_t * p_aout,
......@@ -94,6 +94,7 @@ static inline void aout_FifoInit( struct aout_instance_t * p_aout,
vlc_mutex_init( (vlc_object_t *)p_aout, &p_fifo->lock );
p_fifo->p_first = NULL;
p_fifo->pp_last = &p_fifo->p_first;
p_fifo->end_date = 0;
}
static inline void aout_FifoPush( struct aout_instance_t * p_aout,
......@@ -104,10 +105,42 @@ static inline void aout_FifoPush( struct aout_instance_t * p_aout,
*p_fifo->pp_last = p_buffer;
p_fifo->pp_last = &p_buffer->p_next;
*p_fifo->pp_last = NULL;
/* Enforce continuity of the stream. */
if ( p_fifo->end_date )
{
mtime_t duration = p_buffer->end_date - p_buffer->start_date;
p_buffer->start_date = p_fifo->end_date;
p_buffer->end_date = p_fifo->end_date =
p_buffer->start_date + duration;
}
else
{
p_fifo->end_date = p_buffer->end_date;
}
vlc_mutex_unlock( &p_fifo->lock );
}
static inline mtime_t aout_FifoNextStart( struct aout_instance_t * p_aout,
aout_fifo_t * p_fifo )
{
mtime_t end_date;
vlc_mutex_lock( &p_fifo->lock );
end_date = p_fifo->end_date;
vlc_mutex_unlock( &p_fifo->lock );
return end_date;
}
/* This function supposes there is one buffer in p_fifo. */
/* Reinit the end_date (for instance after a pause). */
static inline void aout_FifoSet( struct aout_instance_t * p_aout,
aout_fifo_t * p_fifo, mtime_t date )
{
vlc_mutex_lock( &p_fifo->lock );
p_fifo->end_date = date;
vlc_mutex_unlock( &p_fifo->lock );
}
/* This function supposes there is at least one buffer in p_fifo. */
static inline aout_buffer_t * aout_FifoPop( struct aout_instance_t * p_aout,
aout_fifo_t * p_fifo )
{
......@@ -164,8 +197,7 @@ typedef struct aout_filter_t
*****************************************************************************/
typedef struct aout_mixer_t
{
audio_sample_format_t input;
audio_sample_format_t output;
audio_sample_format_t mixer;
aout_alloc_t output_alloc;
module_t * p_module;
......@@ -188,7 +220,7 @@ struct aout_input_t
aout_fifo_t fifo;
mtime_t next_packet_date;
/* Mixer information */
byte_t * p_first_byte_to_mix;
};
......@@ -204,12 +236,11 @@ typedef struct aout_output_t
int i_nb_filters;
aout_fifo_t fifo;
mtime_t last_date;
struct module_t * p_module;
struct aout_sys_t * p_sys;
int (* pf_setformat)( aout_instance_t * );
void (* pf_play)( aout_instance_t *, aout_buffer_t * );
void (* pf_play)( aout_instance_t * );
int i_nb_samples;
} aout_output_t;
......@@ -229,8 +260,8 @@ struct aout_instance_t
int i_nb_inputs;
/* Mixer */
vlc_mutex_t mixer_lock;
vlc_cond_t mixer_signal;
vlc_cond_t mixer_signal; /* the associated mutex is
* p_aout->output.fifo.lock */
vlc_bool_t b_mixer_active;
aout_mixer_t mixer;
......@@ -247,8 +278,8 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
aout_filter_t ** pp_filters,
int * pi_nb_filters,
audio_sample_format_t * p_input_format,
audio_sample_format_t * p_output_format );
const audio_sample_format_t * p_input_format,
const audio_sample_format_t * p_output_format );
void aout_FiltersDestroyPipeline( aout_instance_t * p_aout,
aout_filter_t ** pp_filters,
int i_nb_filters );
......
......@@ -2,7 +2,7 @@
* audio_output.h : audio output interface
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.59 2002/08/14 00:43:51 massiot Exp $
* $Id: audio_output.h,v 1.60 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -32,7 +32,12 @@ struct audio_sample_format_t
int i_rate;
int i_channels;
/* Optional - for A52, SPDIF and DTS types */
int i_bytes_per_sec;
int i_bytes_per_frame;
int i_frame_length;
/* Please note that it may be completely arbitrary - buffers are not
* obliged to contain a integral number of so-called "frames". It's
* just here for the division :
* i_nb_samples * i_bytes_per_frame / i_frame_length */
};
#define AOUT_FMT_MU_LAW 0x00000001
......@@ -56,6 +61,12 @@ struct audio_sample_format_t
&& ((p_first)->i_channels == (p_second)->i_channels \
|| (p_first)->i_channels == -1 || (p_second)->i_channels == -1) )
/* Check if i_rate == i_rate and i_channels == i_channels */
#define AOUT_FMTS_SIMILAR( p_first, p_second ) ( \
((p_first)->i_rate == (p_second)->i_rate) \
&& ((p_first)->i_channels == (p_second)->i_channels \
|| (p_first)->i_channels == -1 || (p_second)->i_channels == -1) )
#ifdef WORDS_BIGENDIAN
# define AOUT_FMT_S16_NE AOUT_FMT_S16_BE
# define AOUT_FMT_U16_NE AOUT_FMT_U16_BE
......@@ -103,7 +114,7 @@ struct aout_buffer_t
{
byte_t * p_buffer;
int i_alloc_type;
/* i_size is the real size of the buffer (normally unused), i_nb_bytes
/* i_size is the real size of the buffer (used for debug ONLY), i_nb_bytes
* is the number of significative bytes in it. */
size_t i_size, i_nb_bytes;
int i_nb_samples;
......@@ -125,7 +136,7 @@ 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( void, aout_BufferPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
VLC_EXPORT( int, aout_FormatToByterate, ( audio_sample_format_t * p_format ) );
VLC_EXPORT( void, aout_FormatPrepare, ( audio_sample_format_t * p_format ) );
/* From input.c : */
#define aout_InputNew(a,b,c) __aout_InputNew(VLC_OBJECT(a),b,c)
......
......@@ -139,6 +139,10 @@
* will cause the calling thread to sleep */
#define AOUT_MAX_PREPARE_TIME (mtime_t)(.5*CLOCK_FREQ)
/* Max acceptable delay between the coded PTS and the actual presentation
* time, without resampling */
#define AOUT_PTS_TOLERANCE (mtime_t)(.03*CLOCK_FREQ)
/*****************************************************************************
* Video configuration
*****************************************************************************/
......
/* include/defs.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* include/defs.h.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
#undef C_ALLOCA
......
......@@ -36,7 +36,6 @@ struct module_symbols_t
int (* __vlc_thread_create_inner) ( vlc_object_t *, char *, int, char *, void * ( * ) ( void * ), vlc_bool_t ) ;
int (* __vlc_threads_end_inner) ( vlc_object_t * ) ;
int (* __vlc_threads_init_inner) ( vlc_object_t * ) ;
int (* aout_FormatToByterate_inner) ( audio_sample_format_t * p_format ) ;
int (* input_AccessInit_inner) ( input_thread_t * ) ;
int (* input_AddInfo_inner) ( input_info_category_t *, char *, char *, ... ) ;
int (* input_ChangeArea_inner) ( input_thread_t *, input_area_t * ) ;
......@@ -104,6 +103,7 @@ struct module_symbols_t
void (* aout_BufferDelete_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
void (* aout_BufferPlay_inner) ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ;
void (* aout_DeleteInstance_inner) ( aout_instance_t * ) ;
void (* aout_FormatPrepare_inner) ( audio_sample_format_t * p_format ) ;
void (* aout_InputDelete_inner) ( aout_instance_t *, aout_input_t * ) ;
void (* config_Duplicate_inner) ( module_t *, module_config_t * ) ;
void (* config_SetCallbacks_inner) ( module_config_t *, module_config_t * ) ;
......@@ -211,7 +211,7 @@ struct module_symbols_t
# define aout_BufferNew p_symbols->aout_BufferNew_inner
# define aout_BufferPlay p_symbols->aout_BufferPlay_inner
# define aout_DeleteInstance p_symbols->aout_DeleteInstance_inner
# define aout_FormatToByterate p_symbols->aout_FormatToByterate_inner
# define aout_FormatPrepare p_symbols->aout_FormatPrepare_inner
# define aout_InputDelete p_symbols->aout_InputDelete_inner
# define aout_OutputNextBuffer p_symbols->aout_OutputNextBuffer_inner
# define config_Duplicate p_symbols->config_Duplicate_inner
......
......@@ -2,7 +2,7 @@
* fixed32float32.c : converter from fixed32 to float32 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: fixed32tofloat32.c,v 1.4 2002/08/13 16:11:15 sam Exp $
* $Id: fixed32tofloat32.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -64,8 +64,7 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
......@@ -73,8 +72,6 @@ static int Create( vlc_object_t *p_this )
p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1;
printf( "fixed32tofloat32 spawned.\n" );
return 0;
}
......
......@@ -2,7 +2,7 @@
* fixed32tos16.c : converter from fixed32 to signed 16 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: fixed32tos16.c,v 1.3 2002/08/13 16:11:15 sam Exp $
* $Id: fixed32tos16.c,v 1.4 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -64,8 +64,7 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
......@@ -73,7 +72,6 @@ static int Create( vlc_object_t *p_this )
p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1;
printf( "fixed32tos16 spawned.\n" );
return 0;
}
......
......@@ -2,7 +2,7 @@
* float32tos16.c : converter from float32 to signed 16 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32tos16.c,v 1.7 2002/08/14 00:23:59 massiot Exp $
* $Id: float32tos16.c,v 1.8 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -64,13 +64,11 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1;
......
......@@ -2,7 +2,7 @@
* float32tos8.c : converter from float32 to signed 8 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32tos8.c,v 1.2 2002/08/14 00:23:59 massiot Exp $
* $Id: float32tos8.c,v 1.3 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Xavier Maillard <zedek@fxgsproject.org>
*
......@@ -64,13 +64,11 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1;
......
......@@ -2,7 +2,7 @@
* float32tou16.c : converter from float32 to unsigned 16 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32tou16.c,v 1.2 2002/08/14 00:23:59 massiot Exp $
* $Id: float32tou16.c,v 1.3 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Xavier Maillard <zedek@fxgsproject.org>
*
......@@ -64,8 +64,7 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
......
......@@ -2,7 +2,7 @@
* float32tou8.c : converter from float32 to unsigned 8 bits integer
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32tou8.c,v 1.2 2002/08/14 00:23:59 massiot Exp $
* $Id: float32tou8.c,v 1.3 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Xavier Maillard <zedek@fxgsproject.org>
*
......@@ -64,13 +64,11 @@ static int Create( vlc_object_t *p_this )
return -1;
}
if ( p_filter->input.i_rate != p_filter->output.i_rate
|| p_filter->input.i_channels != p_filter->output.i_channels )
if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
{
return -1;
}
p_filter->pf_do_work = DoWork;
p_filter->b_in_place = 1;
......
......@@ -2,7 +2,7 @@
* spdif.c : dummy mixer for S/PDIF output (1 input only)
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: spdif.c,v 1.3 2002/08/14 00:23:59 massiot Exp $
* $Id: spdif.c,v 1.4 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -56,7 +56,7 @@ static int Create( vlc_object_t *p_this )
{
aout_instance_t * p_aout = (aout_instance_t *)p_this;
if ( !AOUT_FMT_NON_LINEAR(&p_aout->mixer.output) )
if ( !AOUT_FMT_NON_LINEAR(&p_aout->mixer.mixer) )
{
return -1;
}
......
......@@ -2,7 +2,7 @@
* trivial.c : trivial mixer plug-in (1 input, no downmixing)
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: trivial.c,v 1.4 2002/08/12 22:12:50 massiot Exp $
* $Id: trivial.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -56,8 +56,8 @@ static int Create( vlc_object_t *p_this )
{
aout_instance_t * p_aout = (aout_instance_t *)p_this;
if ( p_aout->mixer.output.i_format != AOUT_FMT_FLOAT32
&& p_aout->mixer.output.i_format != AOUT_FMT_FIXED32 )
if ( p_aout->mixer.mixer.i_format != AOUT_FMT_FLOAT32
&& p_aout->mixer.mixer.i_format != AOUT_FMT_FIXED32 )
{
return -1;
}
......@@ -67,6 +67,7 @@ static int Create( vlc_object_t *p_this )
return 0;
}
#if 0
/*****************************************************************************
* SparseCopy: trivially downmix or upmix a buffer
*****************************************************************************/
......@@ -85,6 +86,7 @@ static void SparseCopy( u32 * p_dest, const u32 * p_src, size_t i_len,
p_dest += i_output_stride;
}
}
#endif
/*****************************************************************************
* DoWork: mix a new output buffer
......@@ -92,14 +94,9 @@ static void SparseCopy( u32 * p_dest, const u32 * p_src, size_t i_len,
static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{
aout_input_t * p_input = p_aout->pp_inputs[0];
if ( p_input->input.i_channels == p_aout->mixer.output.i_channels )
{
int i_nb_bytes = p_buffer->i_nb_samples * sizeof(u32)
* p_input->input.i_channels;
byte_t * p_in = (p_input->p_first_byte_to_mix == NULL) ?
p_input->fifo.p_first->p_buffer :
p_input->p_first_byte_to_mix;
* p_aout->mixer.mixer.i_channels;
byte_t * p_in = p_input->p_first_byte_to_mix;
byte_t * p_out = p_buffer->p_buffer;
for ( ; ; )
......@@ -108,7 +105,7 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
- p_in)
+ p_input->fifo.p_first->i_nb_samples
* sizeof(u32)
* p_input->input.i_channels;
* p_aout->mixer.mixer.i_channels;
if ( i_available_bytes < i_nb_bytes )
{
......@@ -131,73 +128,11 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
}
else
{
if ( i_nb_bytes > 0 )
p_aout->p_vlc->pf_memcpy( p_out, p_in, i_nb_bytes );
p_input->p_first_byte_to_mix = p_in + i_nb_bytes;
break;
}
}
}
else
{
/* Downmixing or upmixing. */
int i_nb_samples = p_buffer->i_nb_samples;
u32 * p_in = (p_input->p_first_byte_to_mix == NULL) ?
(u32 *)p_input->fifo.p_first->p_buffer :
(u32 *)p_input->p_first_byte_to_mix;
u32 * p_out = (u32 *)p_buffer->p_buffer;
if ( p_input->input.i_channels < p_aout->mixer.output.i_channels )
{
/* Zero out the destination buffer, to avoid static on unavailable
* channels. */
memset( p_buffer->p_buffer, 0,
p_buffer->i_nb_samples * sizeof(u32)
* p_aout->mixer.output.i_channels );
}
for ( ; ; )
{
ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer
- (byte_t *)p_in)
+ p_input->fifo.p_first->i_nb_samples
* sizeof(u32)
* p_input->input.i_channels;
int i_available_samples = i_available_bytes
/ p_input->input.i_channels
/ sizeof(u32);
if ( i_available_samples < i_nb_samples )
{
aout_buffer_t * p_old_buffer;
if ( i_available_samples > 0 )
SparseCopy( p_out, p_in, i_available_samples,
p_aout->mixer.output.i_channels,
p_input->input.i_channels );
i_nb_samples -= i_available_samples;
p_out += i_available_samples * p_aout->mixer.output.i_channels;
/* Next buffer */
p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
aout_BufferFree( p_old_buffer );
if ( p_input->fifo.p_first == NULL )
{
msg_Err( p_aout, "internal amix error" );
return;
}
p_in = (u32 *)p_input->fifo.p_first->p_buffer;
}
else
{
SparseCopy( p_out, p_in, i_nb_samples,
p_aout->mixer.output.i_channels,
p_input->input.i_channels );
p_input->p_first_byte_to_mix = (byte_t *)p_in
+ i_nb_samples * p_input->input.i_channels
* sizeof(u32);
break;
}
}
}
}
......@@ -2,7 +2,7 @@
* alsa.c : alsa plugin for vlc
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: alsa.c,v 1.4 2002/08/19 17:07:14 bozo Exp $
* $Id: alsa.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Henri Fallon <henri@videolan.org> - Original Author
* Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API
......@@ -79,8 +79,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *,
aout_buffer_t * );
static void Play ( aout_instance_t * );
static int ALSAThread ( aout_instance_t * );
static void ALSAFill ( aout_instance_t * );
......@@ -343,9 +342,8 @@ static int SetFormat( aout_instance_t * p_aout )
/*****************************************************************************
* Play: queue a buffer for playing by ALSAThread
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t *p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -59,7 +59,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
static int aRtsThread ( aout_instance_t * );
/*****************************************************************************
......@@ -159,9 +159,8 @@ static int SetFormat( aout_instance_t *p_aout )
/*****************************************************************************
* Play: queue a buffer for playing by aRtsThread
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t *p_aout );
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* esd.c : EsounD module
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: esd.c,v 1.6 2002/08/14 13:10:44 sam Exp $
* $Id: esd.c,v 1.7 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -58,7 +58,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
static int ESDThread ( aout_instance_t * );
/*****************************************************************************
......@@ -160,9 +160,8 @@ static int SetFormat( aout_instance_t *p_aout )
/*****************************************************************************
* Play: queue a buffer for playing by ESDThread
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t *p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* file.c : audio output which writes the samples to a file
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: file.c,v 1.5 2002/08/14 00:23:59 massiot Exp $
* $Id: file.c,v 1.6 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -42,7 +42,7 @@
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
/*****************************************************************************
* Module descriptor
......@@ -133,8 +133,8 @@ static int SetFormat( aout_instance_t * p_aout )
if ( p_aout->output.output.i_format == AOUT_FMT_SPDIF )
{
p_aout->output.i_nb_samples = A52_FRAME_NB;
p_aout->output.output.i_bytes_per_sec = p_aout->output.output.i_rate
* AOUT_SPDIF_SIZE / A52_FRAME_NB;
p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->output.output.i_frame_length = A52_FRAME_NB;
}
else
{
......@@ -146,8 +146,9 @@ static int SetFormat( aout_instance_t * p_aout )
/*****************************************************************************
* Play: pretend to play a sound
*****************************************************************************/
static void Play( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t * p_aout )
{
aout_buffer_t * p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
if( fwrite( p_buffer->p_buffer, p_buffer->i_nb_bytes, 1,
(FILE *)p_aout->output.p_sys ) != 1 )
{
......
......@@ -2,7 +2,7 @@
* oss.c : OSS /dev/dsp module for vlc
*****************************************************************************
* Copyright (C) 2000-2002 VideoLAN
* $Id: oss.c,v 1.10 2002/08/14 00:43:52 massiot Exp $
* $Id: oss.c,v 1.11 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -75,7 +75,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
static int OSSThread ( aout_instance_t * );
/*****************************************************************************
......@@ -171,8 +171,8 @@ static int SetFormat( aout_instance_t *p_aout )
if ( p_aout->output.output.i_format == AOUT_FMT_SPDIF )
{
p_aout->output.i_nb_samples = A52_FRAME_NB;
p_aout->output.output.i_bytes_per_sec = p_aout->output.output.i_rate
* AOUT_SPDIF_SIZE / A52_FRAME_NB;
p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->output.output.i_frame_length = A52_FRAME_NB;
}
else
{
......@@ -241,9 +241,8 @@ static int SetFormat( aout_instance_t *p_aout )
/*****************************************************************************
* Play: queue a buffer for playing by OSSThread
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t *p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* sdl.c : SDL audio output plugin for vlc
*****************************************************************************
* Copyright (C) 2000-2002 VideoLAN
* $Id: sdl.c,v 1.2 2002/08/14 00:43:52 massiot Exp $
* $Id: sdl.c,v 1.3 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -47,7 +47,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
static void SDLCallback ( void *, Uint8 *, int );
......@@ -129,13 +129,8 @@ static int SetFormat( aout_instance_t *p_aout )
/*****************************************************************************
* Play: play a sound samples buffer
*****************************************************************************/
static void Play( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t * p_aout )
{
SDL_LockAudio(); /* Stop callbacking */
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
SDL_UnlockAudio(); /* go on callbacking */
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* waveout.c : Windows waveOut plugin for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: waveout.c,v 1.3 2002/08/14 00:43:52 massiot Exp $
* $Id: waveout.c,v 1.4 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -45,7 +45,7 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
/* local functions */
static int OpenWaveOut ( aout_instance_t *p_aout, int i_format,
......@@ -186,9 +186,8 @@ static int SetFormat( aout_instance_t *p_aout )
* This doesn't actually play the buffer. This just stores the buffer so it
* can be played by the callback thread.
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t *p_buffer )
static void Play( aout_instance_t *p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -4,7 +4,7 @@
* (http://liba52.sf.net/).
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: a52.c,v 1.4 2002/08/14 00:23:59 massiot Exp $
* $Id: a52.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -304,7 +304,7 @@ static int DecodeFrame( a52_thread_t * p_dec, byte_t * p_frame_buffer )
A52_FRAME_NB );
if ( p_buffer == NULL ) return -1;
p_buffer->start_date = p_dec->last_date;
p_dec->last_date += (mtime_t)(A52_FRAME_NB * 1000000)
p_dec->last_date += (mtime_t)A52_FRAME_NB * 1000000
/ p_dec->output_format.i_rate;
p_buffer->end_date = p_dec->last_date;
......
......@@ -2,7 +2,7 @@
* spdif.c: A52 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001-2002 VideoLAN
* $Id: spdif.c,v 1.5 2002/08/14 00:23:59 massiot Exp $
* $Id: spdif.c,v 1.6 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
......@@ -170,7 +170,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if( (p_dec->p_aout_input != NULL) &&
( (p_dec->output_format.i_rate != i_rate)
|| (p_dec->output_format.i_bytes_per_sec != i_bit_rate * 1000 / 8) ) )
|| (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 );
......@@ -181,7 +181,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if( p_dec->p_aout_input == NULL )
{
p_dec->output_format.i_rate = i_rate;
p_dec->output_format.i_bytes_per_sec = i_bit_rate * 1000 / 8;
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_channels = i_channels; */
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
......
......@@ -2,7 +2,7 @@
* aout.m: CoreAudio output plugin
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout.m,v 1.4 2002/08/14 00:43:52 massiot Exp $
* $Id: aout.m,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Colin Delacroix <colin@zoy.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
......@@ -58,8 +58,7 @@ struct aout_sys_t
* Local prototypes.
*****************************************************************************/
static int SetFormat ( aout_instance_t *p_aout );
static void Play ( aout_instance_t *p_aout,
aout_buffer_t *p_buffer );
static void Play ( aout_instance_t *p_aout );
static OSStatus IOCallback ( AudioDeviceID inDevice,
const AudioTimeStamp *inNow,
......@@ -139,14 +138,10 @@ static int SetFormat( aout_instance_t * p_aout )
p_aout->output.output.i_format );
return -1;
}
p_sys->stream_format.mFormatFlags |=
kLinearPCMFormatFlagIsFloat;
/* Set sample rate and channels per frame */
p_sys->stream_format.mSampleRate
= p_aout->output.output.i_rate;
p_sys->stream_format.mChannelsPerFrame
= p_aout->output.output.i_channels;
p_aout->output.output.i_rate = p_sys->stream_format.mSampleRate;
p_aout->output.output.i_channels = p_sys->stream_format.mChannelsPerFrame;
/* Get the buffer size that the device uses for IO */
i_param_size = sizeof( p_sys->i_buffer_size );
......@@ -186,8 +181,9 @@ msg_Dbg( p_aout, "toto : %d", p_sys->i_buffer_size );
}
/* Let's pray for the following operation to be atomic... */
p_sys->clock_diff = mdate()
- AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) / 1000;
p_sys->clock_diff = - (mtime_t)AudioConvertHostTimeToNanos(
AudioGetCurrentHostTime()) / 1000;
p_sys->clock_diff += mdate();
return 0;
}
......@@ -214,9 +210,8 @@ void E_(CloseAudio)( aout_instance_t * p_aout )
/*****************************************************************************
* Play: queue a buffer for playing by IOCallback
*****************************************************************************/
static void Play( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t * p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* aout_dummy.c : dummy audio output plugin
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout.c,v 1.4 2002/08/14 00:23:59 massiot Exp $
* $Id: aout.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -39,7 +39,7 @@
* Local prototypes.
*****************************************************************************/
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
/*****************************************************************************
* OpenAudio: open a dummy audio device
......@@ -62,8 +62,8 @@ static int SetFormat( aout_instance_t * p_aout )
if ( p_aout->output.output.i_format == AOUT_FMT_SPDIF )
{
p_aout->output.i_nb_samples = A52_FRAME_NB;
p_aout->output.output.i_bytes_per_sec = p_aout->output.output.i_rate
* AOUT_SPDIF_SIZE / A52_FRAME_NB;
p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->output.output.i_frame_length = A52_FRAME_NB;
}
else
{
......@@ -75,8 +75,9 @@ static int SetFormat( aout_instance_t * p_aout )
/*****************************************************************************
* Play: pretend to play a sound
*****************************************************************************/
static void Play( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
static void Play( aout_instance_t * p_aout )
{
aout_buffer_t * p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
aout_BufferFree( p_buffer );
}
......@@ -2,7 +2,7 @@
* aout.c: Windows DirectX audio output method
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: aout.c,v 1.4 2002/08/14 00:43:52 massiot Exp $
* $Id: aout.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -97,7 +97,7 @@ void E_(CloseAudio) ( vlc_object_t *p_this );
* Local prototypes.
*****************************************************************************/
static int SetFormat ( aout_instance_t * );
static void Play ( aout_instance_t *, aout_buffer_t * );
static void Play ( aout_instance_t * );
/* local functions */
static int DirectxCreateSecondaryBuffer ( aout_instance_t * );
......@@ -248,9 +248,8 @@ static int SetFormat( aout_instance_t *p_aout )
* This doesn't actually play the buffer. This just stores the buffer so it
* can be played by the callback thread.
*****************************************************************************/
static void Play( aout_instance_t *p_aout, aout_buffer_t *p_buffer )
static void Play( aout_instance_t *p_aout )
{
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* audio_output.c : audio output instance
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio_output.c,v 1.96 2002/08/14 13:10:44 sam Exp $
* $Id: audio_output.c,v 1.97 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -57,7 +57,6 @@ aout_instance_t * __aout_NewInstance( vlc_object_t * p_parent )
p_aout->b_change_requested = 0;
p_aout->i_nb_inputs = 0;
vlc_mutex_init( p_parent, &p_aout->mixer_lock );
vlc_cond_init( p_parent, &p_aout->mixer_signal );
p_aout->b_mixer_active = 0;
......@@ -73,7 +72,6 @@ void aout_DeleteInstance( aout_instance_t * p_aout )
{
vlc_mutex_destroy( &p_aout->input_lock );
vlc_cond_destroy( &p_aout->input_signal );
vlc_mutex_destroy( &p_aout->mixer_lock );
vlc_cond_destroy( &p_aout->mixer_signal );
/* Free structure. */
......@@ -94,10 +92,8 @@ aout_buffer_t * aout_BufferNew( aout_instance_t * p_aout,
/* 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 = duration
* aout_FormatToByterate( &p_input->input )
/ 1000000;
p_buffer->i_nb_bytes &= ~0x3;
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 )
{
......@@ -126,8 +122,6 @@ void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input,
void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer )
{
vlc_bool_t b_run_mixer = 0;
if ( p_buffer->start_date == 0 )
{
msg_Warn( p_aout, "non-dated buffer received" );
......@@ -146,28 +140,13 @@ void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_InputPlay( p_aout, p_input, p_buffer );
/* Run the mixer if it is able to run. */
vlc_mutex_lock( &p_aout->mixer_lock );
if ( !p_aout->b_mixer_active )
{
p_aout->b_mixer_active = 1;
b_run_mixer = 1;
}
vlc_mutex_unlock( &p_aout->mixer_lock );
if ( b_run_mixer )
{
aout_MixerRun( p_aout );
vlc_mutex_lock( &p_aout->mixer_lock );
p_aout->b_mixer_active = 0;
vlc_cond_broadcast( &p_aout->mixer_signal );
vlc_mutex_unlock( &p_aout->mixer_lock );
}
}
/*****************************************************************************
* aout_FormatToByterate : compute the number of bytes per second
* aout_FormatPrepare : compute the number of bytes per frame & frame length
*****************************************************************************/
int aout_FormatToByterate( audio_sample_format_t * p_format )
void aout_FormatPrepare( audio_sample_format_t * p_format )
{
int i_result;
......@@ -193,14 +172,15 @@ int aout_FormatToByterate( audio_sample_format_t * p_format )
case AOUT_FMT_SPDIF:
case AOUT_FMT_A52:
case AOUT_FMT_DTS:
/* For these formats the caller has to indicate the number of bytes
* per second it evaluates. */
return p_format->i_bytes_per_sec;
/* For these formats the caller has to indicate the parameters
* by hand. */
return;
default:
return 0; /* will segfault much sooner... */
i_result = 0; /* will segfault much sooner... */
}
return i_result * p_format->i_channels * p_format->i_rate;
p_format->i_bytes_per_frame = i_result * p_format->i_channels;
p_format->i_frame_length = 1;
}
This diff is collapsed.
......@@ -2,7 +2,7 @@
* input.c : internal management of input streams for the audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: input.c,v 1.4 2002/08/14 00:23:59 massiot Exp $
* $Id: input.c,v 1.5 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -42,11 +42,13 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
if ( p_input == NULL ) return NULL;
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_lock( &p_aout->output.fifo.lock );
while ( p_aout->b_mixer_active )
{
vlc_cond_wait( &p_aout->mixer_signal, &p_aout->mixer_lock );
vlc_cond_wait( &p_aout->mixer_signal, &p_aout->output.fifo.lock );
}
p_aout->b_mixer_active = 1;
vlc_mutex_unlock( &p_aout->output.fifo.lock );
if ( p_aout->i_nb_inputs == 0 )
{
......@@ -64,18 +66,16 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
memcpy( &p_input->input, p_format,
sizeof(audio_sample_format_t) );
p_input->input.i_bytes_per_sec =
aout_FormatToByterate( &p_input->input );
aout_FormatPrepare( &p_input->input );
/* Prepare FIFO. */
aout_FifoInit( p_aout, &p_input->fifo );
p_input->p_first_byte_to_mix = NULL;
p_input->next_packet_date = 0;
/* Create filters. */
if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
&p_input->i_nb_filters, &p_input->input,
&p_aout->mixer.input ) < 0 )
&p_aout->mixer.mixer ) < 0 )
{
msg_Err( p_aout, "couldn't set an input pipeline" );
......@@ -106,8 +106,23 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{
aout_OutputDelete( p_aout );
}
else
{
aout_MixerNew( p_aout );
}
vlc_mutex_lock( &p_aout->output.fifo.lock );
p_aout->b_mixer_active = 0;
vlc_cond_signal( &p_aout->mixer_signal );
vlc_mutex_unlock( &p_aout->output.fifo.lock );
return NULL;
}
vlc_mutex_lock( &p_aout->output.fifo.lock );
p_aout->b_mixer_active = 0;
vlc_cond_signal( &p_aout->mixer_signal );
vlc_mutex_unlock( &p_aout->output.fifo.lock );
/* 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;
......@@ -119,12 +134,12 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
/* 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_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;
vlc_mutex_unlock( &p_aout->mixer_lock );
msg_Dbg( p_aout, "input 0x%x created", p_input );
return p_input;
}
......@@ -164,11 +179,13 @@ void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
msg_Dbg( p_aout, "input 0x%x destroyed", p_input );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_lock( &p_aout->output.fifo.lock );
while ( p_aout->b_mixer_active )
{
vlc_cond_wait( &p_aout->mixer_signal, &p_aout->mixer_lock );
vlc_cond_wait( &p_aout->mixer_signal, &p_aout->output.fifo.lock );
}
p_aout->b_mixer_active = 1;
vlc_mutex_unlock( &p_aout->output.fifo.lock );
for ( i_input = 0; i_input < p_aout->i_nb_inputs; i_input++ )
{
......@@ -189,7 +206,10 @@ void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
(AOUT_MAX_INPUTS - i_input - 1) * sizeof(aout_input_t *) );
p_aout->i_nb_inputs--;
vlc_mutex_unlock( &p_aout->mixer_lock );
vlc_mutex_lock( &p_aout->output.fifo.lock );
p_aout->b_mixer_active = 0;
vlc_cond_signal( &p_aout->mixer_signal );
vlc_mutex_unlock( &p_aout->output.fifo.lock );
aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
p_input->i_nb_filters );
......@@ -210,6 +230,8 @@ void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
void 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_aout->input_lock );
while( p_aout->b_change_requested )
{
......@@ -218,9 +240,113 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_aout->i_inputs_active++;
vlc_mutex_unlock( &p_aout->input_lock );
/* We don't care if someone changes the start date behind our back after
* aout_FifoNextStart. aout_FifoPush will deal with that, and we will
* compensate with the next incoming buffer. */
start_date = aout_FifoNextStart( p_aout, &p_input->fifo );
if ( start_date != 0 && start_date < mdate() )
{
/* The decoder is _very_ late. This can only happen if the user
* pauses the stream (or if the decoder is buggy, which cannot
* happen :). */
msg_Warn( p_aout, "Computed PTS is out of range (%lld), clearing out",
start_date );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
start_date = 0;
}
if ( p_buffer->start_date < mdate() )
{
/* The decoder gives us f*cked up PTS. It's its business, but we
* can't present it anyway, so drop the buffer. */
msg_Warn( p_aout, "PTS is out of range (%lld), dropping buffer",
mdate() - p_buffer->start_date );
aout_BufferFree( p_buffer );
vlc_mutex_lock( &p_aout->input_lock );
p_aout->i_inputs_active--;
vlc_cond_broadcast( &p_aout->input_signal );
vlc_mutex_unlock( &p_aout->input_lock );
return;
}
if ( start_date == 0 ) start_date = p_buffer->start_date;
if ( start_date < p_buffer->start_date - AOUT_PTS_TOLERANCE
|| start_date > p_buffer->start_date + AOUT_PTS_TOLERANCE )
{
/* Can happen in several circumstances :
* 1. A problem at the input (clock drift)
* 2. A small pause triggered by the user
* 3. Some delay in the output stage, causing a loss of lip
* synchronization
* Solution : resample the buffer to avoid a scratch.
*/
audio_sample_format_t new_output;
int i_ratio, i_nb_filters;
mtime_t old_duration;
aout_filter_t * pp_filters[AOUT_MAX_FILTERS];
aout_alloc_t dummy_alloc;
mtime_t drift = p_buffer->start_date - start_date;
msg_Warn( p_aout, "buffer is %lld %s, resampling",
drift > 0 ? drift : -drift,
drift > 0 ? "in advance" : "late" );
memcpy( &new_output, &p_aout->mixer.mixer,
sizeof(audio_sample_format_t) );
old_duration = p_buffer->end_date - p_buffer->start_date;
duration = p_buffer->end_date - start_date;
i_ratio = duration * 100 / old_duration;
/* If the ratio is too != 100, the sound quality will be awful. */
if ( i_ratio < 90 /* % */ )
{
duration = old_duration * 90 / 100;
}
if ( i_ratio > 110 /* % */ )
{
duration = old_duration * 110 / 100;
}
new_output.i_rate = new_output.i_rate * old_duration / duration;
if ( aout_FiltersCreatePipeline( p_aout, pp_filters,
&i_nb_filters, &p_input->input,
&new_output ) < 0 )
{
msg_Err( p_aout, "couldn't set an input pipeline for resampling" );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
aout_BufferFree( p_buffer );
vlc_mutex_lock( &p_aout->input_lock );
p_aout->i_inputs_active--;
vlc_cond_broadcast( &p_aout->input_signal );
vlc_mutex_unlock( &p_aout->input_lock );
return;
}
dummy_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
dummy_alloc.i_bytes_per_sec = -1;
aout_FiltersHintBuffers( p_aout, pp_filters, i_nb_filters,
&dummy_alloc );
aout_FiltersPlay( p_aout, pp_filters, i_nb_filters,
&p_buffer );
aout_FiltersDestroyPipeline( p_aout, pp_filters,
i_nb_filters );
}
else
{
/* No resampling needed (except maybe the one imposed by the
* output). */
duration = p_buffer->end_date - p_buffer->start_date;
aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters,
&p_buffer );
}
/* Adding the start date will be managed by aout_FifoPush(). */
p_buffer->start_date = start_date;
p_buffer->end_date = start_date + duration;
aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
vlc_mutex_lock( &p_aout->input_lock );
......
......@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: mixer.c,v 1.5 2002/08/14 13:10:44 sam Exp $
* $Id: mixer.c,v 1.6 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -65,38 +65,141 @@ void aout_MixerRun( aout_instance_t * p_aout )
{
int i;
aout_buffer_t * p_output_buffer;
mtime_t start_date, end_date;
/* Retrieve the date of the next buffer. We don't use aout_FifoNextStart
* because we need to keep the lock on the FIFO, to prevent the aout
* thread from triggering resampling while we are running. */
vlc_mutex_lock( &p_aout->output.fifo.lock );
start_date = p_aout->output.fifo.end_date;
if ( start_date != 0 && start_date < mdate() )
{
/* The output is _very_ late. This can only happen if the user
* pauses the stream (or if the decoder is buggy, which cannot
* happen :). */
msg_Warn( p_aout, "Output PTS is out of range (%lld), clearing out",
start_date );
start_date = p_aout->output.fifo.end_date = 0;
}
end_date = start_date + (mtime_t)p_aout->output.i_nb_samples * 1000000
/ p_aout->output.output.i_rate;
/* See if we have enough data to prepare a new buffer for the audio
* output. */
mtime_t wanted_date = 0, first_date = 0;
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_fifo_t * p_fifo = &p_aout->pp_inputs[i]->fifo;
aout_input_t * p_input = p_aout->pp_inputs[i];
aout_fifo_t * p_fifo = &p_input->fifo;
aout_buffer_t * p_buffer;
mtime_t prev_date;
boolean_t b_drop_buffers;
vlc_mutex_lock( &p_fifo->lock );
for ( p_buffer = p_fifo->p_first; p_buffer != NULL;
p_buffer = p_buffer->p_next )
{
if ( !wanted_date )
p_buffer = p_fifo->p_first;
if ( p_buffer == NULL )
{
if ( !p_aout->output.last_date )
vlc_mutex_unlock( &p_fifo->lock );
break;
}
if ( !start_date )
{
first_date = p_buffer->start_date;
wanted_date = p_buffer->start_date
+ (mtime_t)p_aout->output.i_nb_samples * 1000000
/ p_aout->output.output.i_rate;
start_date = p_buffer->start_date;
end_date += p_buffer->start_date;
p_input->p_first_byte_to_mix = p_buffer->p_buffer;
}
else
{
first_date = p_aout->output.last_date;
wanted_date = p_aout->output.last_date
+ (mtime_t)p_aout->output.i_nb_samples * 1000000
/ p_aout->output.output.i_rate;
/* Check for the continuity of start_date */
while ( p_buffer != NULL && p_buffer->end_date < start_date )
{
aout_buffer_t * p_next = p_buffer->p_next;
msg_Err( p_aout, "the mixer got a packet in the past (%lld)",
start_date - p_buffer->end_date );
aout_BufferFree( p_buffer );
p_fifo->p_first = p_buffer = p_next;
p_input->p_first_byte_to_mix = NULL;
}
if ( p_buffer == NULL )
{
p_fifo->pp_last = &p_fifo->p_first;
vlc_mutex_unlock( &p_fifo->lock );
break;
}
if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer.mixer ) )
{
/* Additionally check that p_first_byte_to_mix is well
* located. */
unsigned long i_nb_bytes = (start_date - p_buffer->start_date)
* p_aout->mixer.mixer.i_bytes_per_frame
* p_aout->mixer.mixer.i_rate
/ p_aout->mixer.mixer.i_frame_length
/ 1000000;
ptrdiff_t mixer_nb_bytes;
if ( p_input->p_first_byte_to_mix == NULL )
{
p_input->p_first_byte_to_mix = p_buffer->p_buffer;
}
mixer_nb_bytes = p_input->p_first_byte_to_mix
- p_buffer->p_buffer;
if ( i_nb_bytes + p_aout->mixer.mixer.i_bytes_per_frame
< mixer_nb_bytes ||
i_nb_bytes - p_aout->mixer.mixer.i_bytes_per_frame
> mixer_nb_bytes )
{
msg_Warn( p_aout,
"mixer start isn't output start (%ld)",
i_nb_bytes - mixer_nb_bytes );
/* Round to the nearest multiple */
i_nb_bytes /= p_aout->mixer.mixer.i_bytes_per_frame;
i_nb_bytes *= p_aout->mixer.mixer.i_bytes_per_frame;
p_input->p_first_byte_to_mix = p_buffer->p_buffer
+ i_nb_bytes;
}
}
}
if ( p_buffer->end_date >= wanted_date ) break;
/* Check that we have enough samples. */
for ( ; ; )
{
p_buffer = p_fifo->p_first;
if ( p_buffer == NULL ) break;
if ( p_buffer->end_date >= end_date ) break;
/* Check that all buffers are contiguous. */
prev_date = p_fifo->p_first->end_date;
p_buffer = p_buffer->p_next;
b_drop_buffers = 0;
for ( ; p_buffer != NULL; p_buffer = p_buffer->p_next )
{
if ( prev_date != p_buffer->start_date )
{
msg_Warn( p_aout,
"buffer discontinuity, dropping packets (%lld)",
p_buffer->start_date - prev_date );
b_drop_buffers = 1;
break;
}
if ( p_buffer->end_date >= end_date ) break;
prev_date = p_buffer->end_date;
}
if ( b_drop_buffers )
{
aout_buffer_t * p_deleted = p_fifo->p_first;
while ( p_deleted != NULL && p_deleted != p_buffer )
{
aout_buffer_t * p_next = p_deleted->p_next;
aout_BufferFree( p_deleted );
p_deleted = p_next;
}
p_fifo->p_first = p_deleted; /* == p_buffer */
}
else break;
}
vlc_mutex_unlock( &p_fifo->lock );
if ( p_buffer == NULL ) break;
......@@ -105,9 +208,13 @@ void aout_MixerRun( aout_instance_t * p_aout )
if ( i < p_aout->i_nb_inputs )
{
/* Interrupted before the end... We can't run. */
vlc_mutex_unlock( &p_aout->output.fifo.lock );
return;
}
p_aout->b_mixer_active = 1;
vlc_mutex_unlock( &p_aout->output.fifo.lock );
/* Run the mixer. */
aout_BufferAlloc( &p_aout->mixer.output_alloc,
((u64)p_aout->output.i_nb_samples * 1000000)
......@@ -122,16 +229,19 @@ void aout_MixerRun( aout_instance_t * p_aout )
return;
}
p_output_buffer->i_nb_samples = p_aout->output.i_nb_samples;
p_output_buffer->i_nb_bytes = (wanted_date - first_date)
* aout_FormatToByterate( &p_aout->mixer.output )
/ 1000000;
p_output_buffer->i_nb_bytes &= ~0x3;
p_output_buffer->start_date = first_date;
p_output_buffer->end_date = wanted_date;
p_aout->output.last_date = wanted_date;
p_output_buffer->i_nb_bytes = p_aout->output.i_nb_samples
* p_aout->output.output.i_bytes_per_frame
/ p_aout->output.output.i_frame_length;
p_output_buffer->start_date = start_date;
p_output_buffer->end_date = end_date;
p_aout->mixer.pf_do_work( p_aout, p_output_buffer );
aout_OutputPlay( p_aout, p_output_buffer );
vlc_mutex_lock( &p_aout->output.fifo.lock );
p_aout->b_mixer_active = 0;
vlc_cond_signal( &p_aout->mixer_signal );
vlc_mutex_unlock( &p_aout->output.fifo.lock );
}
......@@ -2,7 +2,7 @@
* output.c : internal management of output streams for the audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: output.c,v 1.6 2002/08/14 00:43:52 massiot Exp $
* $Id: output.c,v 1.7 2002/08/19 21:31:11 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -46,7 +46,6 @@ int aout_OutputNew( aout_instance_t * p_aout,
vlc_mutex_init( p_aout, &p_aout->output.fifo.lock );
p_aout->output.fifo.p_first = NULL;
p_aout->output.fifo.pp_last = &p_aout->output.fifo.p_first;
p_aout->output.last_date = 0;
p_aout->output.p_module = module_Need( p_aout, "audio output",
psz_name );
......@@ -80,43 +79,36 @@ int aout_OutputNew( aout_instance_t * p_aout,
module_Unneed( p_aout, p_aout->output.p_module );
return -1;
}
aout_FormatPrepare( &p_aout->output.output );
msg_Dbg( p_aout, "output format=%d rate=%d channels=%d",
p_aout->output.output.i_format, p_aout->output.output.i_rate,
p_aout->output.output.i_channels );
/* Calculate the resulting mixer output format. */
p_aout->mixer.output.i_channels = p_aout->output.output.i_channels;
p_aout->mixer.output.i_rate = p_aout->output.output.i_rate;
memcpy( &p_aout->mixer.mixer, &p_aout->output.output,
sizeof(audio_sample_format_t) );
if ( !AOUT_FMT_NON_LINEAR(&p_aout->output.output) )
{
/* Non-S/PDIF mixer only deals with float32 or fixed32. */
p_aout->mixer.output.i_format
p_aout->mixer.mixer.i_format
= (p_aout->p_vlc->i_cpu & CPU_CAPABILITY_FPU) ?
AOUT_FMT_FLOAT32 : AOUT_FMT_FIXED32;
p_aout->mixer.output.i_bytes_per_sec
= aout_FormatToByterate( &p_aout->mixer.output );
aout_FormatPrepare( &p_aout->mixer.mixer );
}
else
{
p_aout->mixer.output.i_format = p_format->i_format;
p_aout->mixer.output.i_bytes_per_sec = p_format->i_bytes_per_sec;
p_aout->mixer.mixer.i_format = p_format->i_format;
}
msg_Dbg( p_aout, "mixer format=%d rate=%d channels=%d",
p_aout->mixer.output.i_format, p_aout->mixer.output.i_rate,
p_aout->mixer.output.i_channels );
/* Calculate the resulting mixer input format. */
p_aout->mixer.input.i_channels = -1; /* unchanged */
p_aout->mixer.input.i_rate = p_aout->mixer.output.i_rate;
p_aout->mixer.input.i_format = p_aout->mixer.output.i_format;
p_aout->mixer.input.i_bytes_per_sec = p_aout->mixer.output.i_bytes_per_sec;
p_aout->mixer.mixer.i_format, p_aout->mixer.mixer.i_rate,
p_aout->mixer.mixer.i_channels );
/* Create filters. */
if ( aout_FiltersCreatePipeline( p_aout, p_aout->output.pp_filters,
&p_aout->output.i_nb_filters,
&p_aout->mixer.output,
&p_aout->mixer.mixer,
&p_aout->output.output ) < 0 )
{
msg_Err( p_aout, "couldn't set an output pipeline" );
......@@ -127,7 +119,9 @@ int aout_OutputNew( aout_instance_t * p_aout,
/* Prepare hints for the buffer allocator. */
p_aout->mixer.output_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
p_aout->mixer.output_alloc.i_bytes_per_sec
= aout_FormatToByterate( &p_aout->output.output );
= p_aout->mixer.mixer.i_bytes_per_frame
* p_aout->mixer.mixer.i_rate
/ p_aout->mixer.mixer.i_frame_length;
aout_FiltersHintBuffers( p_aout, p_aout->output.pp_filters,
p_aout->output.i_nb_filters,
......@@ -157,7 +151,9 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
p_aout->output.i_nb_filters,
&p_buffer );
p_aout->output.pf_play( p_aout, p_buffer );
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
p_aout->output.pf_play( p_aout );
}
/*****************************************************************************
......@@ -211,12 +207,12 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
/* Take the mixer lock because no input can be removed when the
* the mixer lock is taken. */
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_lock( &p_aout->output.fifo.lock );
for ( i = 0; i < p_input->i_nb_inputs; i++ )
{
aout_input_t * p_input = p_aout->pp_inputs[i];
}
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_lock( &p_aout->output.fifo.lock );
}
#endif
......
......@@ -185,7 +185,7 @@ static const char * module_error( char *psz_buffer )
(p_symbols)->aout_BufferNew_inner = aout_BufferNew; \
(p_symbols)->aout_BufferDelete_inner = aout_BufferDelete; \
(p_symbols)->aout_BufferPlay_inner = aout_BufferPlay; \
(p_symbols)->aout_FormatToByterate_inner = aout_FormatToByterate; \
(p_symbols)->aout_FormatPrepare_inner = aout_FormatPrepare; \
(p_symbols)->__aout_InputNew_inner = __aout_InputNew; \
(p_symbols)->aout_InputDelete_inner = aout_InputDelete; \
(p_symbols)->__config_GetInt_inner = __config_GetInt; \
......
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