* output.c : internal management of output streams for the audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: output.c,v 1.3 2002/08/11 22:36:35 massiot Exp $
+ * $Id: output.c,v 1.6 2002/08/14 00:43:52 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
memcpy( &p_aout->output.output, p_format, sizeof(audio_sample_format_t) );
if ( i_rate != -1 ) p_aout->output.output.i_rate = i_rate;
if ( i_channels != -1 ) p_aout->output.output.i_channels = i_channels;
- if ( AOUT_FMT_IS_SPDIF(&p_aout->output.output) )
+ if ( AOUT_FMT_NON_LINEAR(&p_aout->output.output) )
{
p_aout->output.output.i_format = AOUT_FMT_SPDIF;
}
/* 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;
- if ( AOUT_FMT_IS_SPDIF(&p_aout->output.output) )
- {
- p_aout->mixer.output.i_format = AOUT_FMT_SPDIF;
- }
- else
+ 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->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 );
+ }
+ 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;
}
+ 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;
/* Create filters. */
if ( aout_FiltersCreatePipeline( p_aout, p_aout->output.pp_filters,
/* 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->output.output.i_rate );
+ = aout_FormatToByterate( &p_aout->output.output );
aout_FiltersHintBuffers( p_aout, p_aout->output.pp_filters,
p_aout->output.i_nb_filters,
/*****************************************************************************
* aout_OutputNextBuffer : give the audio output plug-in the right 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
+ * do it by itself. S/PDIF outputs should always set b_can_sleek = 1.
*****************************************************************************/
aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
- mtime_t start_date )
+ mtime_t start_date ,
+ vlc_bool_t b_can_sleek )
{
aout_buffer_t * p_buffer;
return NULL;
}
+ /* Here we suppose that all buffers have the same duration - this is
+ * generally true, and anyway if it's wrong it won't be a disaster. */
if ( p_buffer->start_date > start_date
- + (mtime_t)p_aout->output.i_nb_samples
- * 1000000 / p_aout->output.output.i_rate )
+ + (p_buffer->end_date - p_buffer->start_date) )
{
vlc_mutex_unlock( &p_aout->output.fifo.lock );
msg_Dbg( p_aout, "audio output is starving (%lld)",
return NULL;
}
- /* FIXME : there we should handle the case where start_date is not
- * completely equal to p_buffer->start_date. */
+#if 0
+ if ( !b_can_sleek )
+ {
+ /* Try to compensate the drift by doing some resampling. */
+ int i;
+
+ /* Take the mixer lock because no input can be removed when the
+ * the mixer lock is taken. */
+ vlc_mutex_lock( &p_aout->mixer_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 );
+ }
+#endif
p_aout->output.fifo.p_first = p_buffer->p_next;
if ( p_buffer->p_next == NULL )