Commit ef4280c5 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Change audio output tolerance times

Maximum buffering time (AOUT_MAX_PREPARE_TIME) is increased to 2
seconds, consistent with increases in audio hardware buffer sizes.
In practice however, this is bound to the input PTS delay.

Maximum advance time is updated accordingly (+ 1 second).

Lip desynchronization tolerance is segregated, following EBU R37:
 - 40 ms (as before) maximum audio advance
 - 60 ms maximum audio delay.
parent 25f179e1
......@@ -33,19 +33,24 @@
/* Buffers which arrive in advance of more than AOUT_MAX_ADVANCE_TIME
* will be considered as bogus and be trashed */
#define AOUT_MAX_ADVANCE_TIME (DEFAULT_PTS_DELAY * 5)
#define AOUT_MAX_ADVANCE_TIME (AOUT_MAX_PREPARE_TIME + CLOCK_FREQ)
/* Buffers which arrive in advance of more than AOUT_MAX_PREPARE_TIME
* will cause the calling thread to sleep */
#define AOUT_MAX_PREPARE_TIME (CLOCK_FREQ/2)
#define AOUT_MAX_PREPARE_TIME (2 * CLOCK_FREQ)
/* Buffers which arrive after pts - AOUT_MIN_PREPARE_TIME will be trashed
* to avoid too heavy resampling */
#define AOUT_MIN_PREPARE_TIME (CLOCK_FREQ/25)
#define AOUT_MIN_PREPARE_TIME AOUT_MAX_PTS_ADVANCE
/* Max acceptable delay between the coded PTS and the actual presentation
* time, without resampling */
#define AOUT_PTS_TOLERANCE (CLOCK_FREQ/25)
/* Tolerance values from EBU Recommendation 37 */
/** Maximum advance of actual audio playback time to coded PTS,
* above which downsampling will be performed */
#define AOUT_MAX_PTS_ADVANCE (CLOCK_FREQ / 25)
/** Maximum delay of actual audio playback time from coded PTS,
* above which upsampling will be performed */
#define AOUT_MAX_PTS_DELAY (3 * CLOCK_FREQ / 50)
/* Max acceptable resampling (in %) */
#define AOUT_MAX_RESAMPLING 10
......
......@@ -569,7 +569,8 @@ static void* ALSAThread( void *data )
/* Wait for the exact time to start playing (avoids resampling) */
vlc_sem_wait( &p_sys->wait );
mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );
mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE / 4 );
#warning Should wait for buffer availability instead!
for(;;)
ALSAFill( p_aout );
......
......@@ -1028,7 +1028,7 @@ static void* DirectSoundThread( void *data )
if( !vlc_atomic_get( &p_notif->abort) )
{
HRESULT dsresult;
mwait( p_notif->start_date - AOUT_PTS_TOLERANCE / 2 );
mwait( p_notif->start_date - AOUT_MAX_PTS_ADVANCE / 2 );
/* start playing the buffer */
dsresult = IDirectSoundBuffer_Play( p_aout->output.p_sys->p_dsbuffer,
......
......@@ -633,7 +633,7 @@ static void* OSSThread( void *obj )
else
{
mtime_t delay = next_date - mdate();
if( delay > AOUT_PTS_TOLERANCE )
if( delay > AOUT_MAX_PTS_ADVANCE )
{
msleep( delay / 2 );
}
......
......@@ -887,10 +887,10 @@ static void* WaveOutThread( void *data )
return NULL;
msg_Dbg( p_aout, "will start to play in %"PRId64" us",
(p_sys->start_date - AOUT_PTS_TOLERANCE/4)-mdate());
(p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4)-mdate());
// than wait a short time... before grabbing first frames
mwait( p_sys->start_date - AOUT_PTS_TOLERANCE/4 );
mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4 );
#define waveout_warn(msg) msg_Warn( p_aout, "aout_OutputNextBuffer no buffer "\
"got next_date=%d ms, "\
......@@ -937,7 +937,7 @@ static void* WaveOutThread( void *data )
// means we are too early to request a new buffer?
waveout_warn("waiting...")
next_date = aout_FifoFirstDate( &p_aout->output.fifo );
mwait( next_date - AOUT_PTS_TOLERANCE/4 );
mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 );
next_date = mdate();
p_buffer = aout_OutputNextBuffer( p_aout, next_date,
b_sleek );
......
......@@ -573,11 +573,9 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
if( !start_date )
start_date = p_buffer->i_pts;
mtime_t tolerance = 3 * AOUT_PTS_TOLERANCE
* i_input_rate / INPUT_RATE_DEFAULT;
mtime_t drift = start_date - p_buffer->i_pts;
if( drift < -tolerance )
if( drift < -i_input_rate * 3 * AOUT_MAX_PTS_ADVANCE / INPUT_RATE_DEFAULT )
{
msg_Warn( p_aout, "buffer way too early (%"PRId64"), clearing queue",
drift );
......@@ -589,7 +587,8 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
start_date = p_buffer->i_pts;
drift = 0;
}
else if( drift > +tolerance )
else
if( drift > +i_input_rate * 3 * AOUT_MAX_PTS_DELAY / INPUT_RATE_DEFAULT )
{
msg_Warn( p_aout, "buffer way too late (%"PRId64"), dropping buffer",
drift );
......@@ -607,7 +606,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
/* Run the resampler if needed.
* We first need to calculate the output rate of this resampler. */
if ( ( p_input->i_resampling_type == AOUT_RESAMPLING_NONE ) &&
( drift < -AOUT_PTS_TOLERANCE || drift > +AOUT_PTS_TOLERANCE ) &&
( drift < -AOUT_MAX_PTS_ADVANCE || drift > +AOUT_MAX_PTS_DELAY ) &&
p_input->i_nb_resamplers > 0 )
{
/* Can happen in several circumstances :
......
......@@ -275,7 +275,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
* In the case of b_can_sleek, we don't use a resampler so we need to be
* a lot more severe. */
while( ((p_buffer = p_fifo->p_first) != NULL)
&& p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_PTS_TOLERANCE )
&& p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_MAX_PTS_DELAY )
{
msg_Dbg( p_aout, "audio output is too slow (%"PRId64"), "
"trashing %"PRId64"us", now - p_buffer->i_pts,
......@@ -304,12 +304,6 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
* generally true, and anyway if it's wrong it won't be a disaster.
*/
if ( 0 > delta + p_buffer->i_length )
/*
* + AOUT_PTS_TOLERANCE )
* There is no reason to want that, it just worsen the scheduling of
* an audio sample after an output starvation (ie. on start or on resume)
* --Gibalou
*/
{
if ( !p_aout->output.b_starving )
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
......@@ -322,17 +316,15 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
p_aout->output.b_starving = false;
p_buffer = aout_FifoPop( p_fifo );
if( !b_can_sleek )
if( !b_can_sleek
&& ( delta > AOUT_MAX_PTS_DELAY || delta < -AOUT_MAX_PTS_ADVANCE ) )
{
if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE )
{
/* Try to compensate the drift by doing some resampling. */
msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", delta );
/* Try to compensate the drift by doing some resampling. */
msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", delta );
aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
aout_FifoMoveDates( p_fifo, delta );
}
aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
aout_FifoMoveDates( p_fifo, delta );
}
out:
aout_unlock( p_aout );
......
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