Commit 057ef608 authored by Laurent Aimar's avatar Laurent Aimar

Let decoder handle the audio/spu delay.

It is more reactive and let decoder do proper late/early checks.
parent da93449d
...@@ -111,10 +111,14 @@ struct decoder_owner_sys_t ...@@ -111,10 +111,14 @@ struct decoder_owner_sys_t
/* Pause */ /* Pause */
bool b_paused; bool b_paused;
mtime_t i_pause_date; mtime_t i_pause_date;
/* CC */ /* CC */
bool b_cc_supported; bool b_cc_supported;
bool pb_cc_present[4]; bool pb_cc_present[4];
decoder_t *pp_cc[4]; decoder_t *pp_cc[4];
/* Delay */
mtime_t i_ts_delay;
}; };
/* */ /* */
...@@ -491,6 +495,15 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ) ...@@ -491,6 +495,15 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
DecoderOutputChangePause( p_dec, b_paused, i_date ); DecoderOutputChangePause( p_dec, b_paused, i_date );
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
} }
void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vlc_mutex_lock( &p_owner->lock );
p_owner->i_ts_delay = i_delay;
vlc_mutex_unlock( &p_owner->lock );
}
/** /**
* Create a decoder object * Create a decoder object
* *
...@@ -634,6 +647,7 @@ static decoder_t * CreateDecoder( input_thread_t *p_input, ...@@ -634,6 +647,7 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_owner->pb_cc_present[i] = false; p_owner->pb_cc_present[i] = false;
p_owner->pp_cc[i] = NULL; p_owner->pp_cc[i] = NULL;
} }
p_owner->i_ts_delay = 0;
return p_dec; return p_dec;
} }
...@@ -690,6 +704,19 @@ static void DecoderWaitUnpause( decoder_t *p_dec ) ...@@ -690,6 +704,19 @@ static void DecoderWaitUnpause( decoder_t *p_dec )
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
} }
static mtime_t DecoderGetTotalDelay( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vlc_mutex_lock( &p_owner->lock );
mtime_t i_delay = p_owner->i_ts_delay;
vlc_mutex_unlock( &p_owner->lock );
return p_owner->p_input->i_pts_delay + i_delay;
}
static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ) static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
{ {
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
...@@ -847,7 +874,9 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block ) ...@@ -847,7 +874,9 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
DecoderWaitUnpause( p_dec ); DecoderWaitUnpause( p_dec );
DecoderAoutBufferFixTs( p_aout_buf, p_clock, p_input->i_pts_delay ); const mtime_t i_delay = DecoderGetTotalDelay( p_dec );
DecoderAoutBufferFixTs( p_aout_buf, p_clock, i_delay );
if( p_clock ) if( p_clock )
i_rate = input_clock_GetRate( p_clock ); i_rate = input_clock_GetRate( p_clock );
...@@ -857,7 +886,7 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block ) ...@@ -857,7 +886,7 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
i_rate = INPUT_RATE_DEFAULT; i_rate = INPUT_RATE_DEFAULT;
/* FIXME TODO take care of audio-delay for mdate check */ /* FIXME TODO take care of audio-delay for mdate check */
const mtime_t i_max_date = mdate() + p_input->i_pts_delay + AOUT_MAX_ADVANCE_TIME; const mtime_t i_max_date = mdate() + i_delay + AOUT_MAX_ADVANCE_TIME;
if( p_aout_buf->start_date > 0 && if( p_aout_buf->start_date > 0 &&
p_aout_buf->start_date <= i_max_date && p_aout_buf->start_date <= i_max_date &&
...@@ -1127,10 +1156,12 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) ...@@ -1127,10 +1156,12 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
DecoderWaitUnpause( p_dec ); DecoderWaitUnpause( p_dec );
DecoderVoutBufferFixTs( p_pic, p_owner->p_clock, p_input->i_pts_delay ); const mtime_t i_delay = DecoderGetTotalDelay( p_dec );
DecoderVoutBufferFixTs( p_pic, p_owner->p_clock, i_delay );
/* Video is never delayed so simple */ /* Video is never delayed so simple */
const mtime_t i_max_date = mdate() + p_input->i_pts_delay + VOUT_BOGUS_DELAY; const mtime_t i_max_date = mdate() + i_delay + VOUT_BOGUS_DELAY;
if( p_pic->date > 0 && p_pic->date < i_max_date ) if( p_pic->date > 0 && p_pic->date < i_max_date )
{ {
...@@ -1245,8 +1276,10 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -1245,8 +1276,10 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
DecoderWaitUnpause( p_dec ); DecoderWaitUnpause( p_dec );
const mtime_t i_delay = DecoderGetTotalDelay( p_dec );
DecoderSoutBufferFixTs( p_sout_block, DecoderSoutBufferFixTs( p_sout_block,
p_owner->p_clock, p_owner->p_input->i_pts_delay, b_telx ); p_owner->p_clock, i_delay, b_telx );
sout_InputSendBuffer( p_owner->p_sout_input, sout_InputSendBuffer( p_owner->p_sout_input,
p_sout_block ); p_sout_block );
......
...@@ -386,7 +386,7 @@ static void EsOutDiscontinuity( es_out_t *out, bool b_flush, bool b_audio ) ...@@ -386,7 +386,7 @@ static void EsOutDiscontinuity( es_out_t *out, bool b_flush, bool b_audio )
} }
} }
} }
static void EsOutDecoderChangePause( es_out_t *out, bool b_paused, mtime_t i_date ) static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
...@@ -413,6 +413,25 @@ static void EsOutProgramChangePause( es_out_t *out, bool b_paused, mtime_t i_dat ...@@ -413,6 +413,25 @@ static void EsOutProgramChangePause( es_out_t *out, bool b_paused, mtime_t i_dat
input_clock_ChangePause( p_sys->pgrm[i]->p_clock, b_paused, i_date ); input_clock_ChangePause( p_sys->pgrm[i]->p_clock, b_paused, i_date );
} }
static void EsOutDecoderChangeDelay( es_out_t *out, es_out_id_t *p_es )
{
es_out_sys_t *p_sys = out->p_sys;
mtime_t i_delay = 0;
if( p_es->fmt.i_cat == AUDIO_ES )
i_delay = p_sys->i_audio_delay;
else if( p_es->fmt.i_cat == SPU_ES )
i_delay = p_sys->i_spu_delay;
if( i_delay != 0 )
{
if( p_es->p_dec )
input_DecoderChangeDelay( p_es->p_dec, i_delay );
if( p_es->p_dec_record )
input_DecoderChangeDelay( p_es->p_dec, i_delay );
}
}
void input_EsOutChangeRate( es_out_t *out, int i_rate ) void input_EsOutChangeRate( es_out_t *out, int i_rate )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
...@@ -501,21 +520,24 @@ void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay ) ...@@ -501,21 +520,24 @@ void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay )
if( i_cat == AUDIO_ES ) if( i_cat == AUDIO_ES )
p_sys->i_audio_delay = i_delay; p_sys->i_audio_delay = i_delay;
else if( i_cat == SPU_ES ) else if( i_cat == AUDIO_ES )
p_sys->i_spu_delay = i_delay; p_sys->i_spu_delay = i_delay;
for( int i = 0; i < p_sys->i_es; i++ )
EsOutDecoderChangeDelay( out, p_sys->es[i] );
} }
void input_EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date ) void input_EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
{ {
/* XXX the order is important */ /* XXX the order is important */
if( b_paused ) if( b_paused )
{ {
EsOutDecoderChangePause( out, true, i_date ); EsOutDecodersChangePause( out, true, i_date );
EsOutProgramChangePause( out, true, i_date ); EsOutProgramChangePause( out, true, i_date );
} }
else else
{ {
EsOutProgramChangePause( out, false, i_date ); EsOutProgramChangePause( out, false, i_date );
EsOutDecoderChangePause( out, false, i_date ); EsOutDecodersChangePause( out, false, i_date );
} }
} }
void input_EsOutChangePosition( es_out_t *out ) void input_EsOutChangePosition( es_out_t *out )
...@@ -1187,6 +1209,8 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es ) ...@@ -1187,6 +1209,8 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
p_es->p_dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_input->p->p_sout ); p_es->p_dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_input->p->p_sout );
if( p_es->p_dec && !p_es->p_master && p_sys->p_sout_record ) if( p_es->p_dec && !p_es->p_master && p_sys->p_sout_record )
p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record ); p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record );
EsOutDecoderChangeDelay( out, p_es );
} }
static void EsDestroyDecoder( es_out_t *out, es_out_id_t *p_es ) static void EsDestroyDecoder( es_out_t *out, es_out_id_t *p_es )
{ {
...@@ -1535,16 +1559,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) ...@@ -1535,16 +1559,8 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input; input_thread_t *p_input = p_sys->p_input;
es_out_pgrm_t *p_pgrm = es->p_pgrm; es_out_pgrm_t *p_pgrm = es->p_pgrm;
int64_t i_delay;
int i_total = 0; int i_total = 0;
if( es->fmt.i_cat == AUDIO_ES )
i_delay = p_sys->i_audio_delay;
else if( es->fmt.i_cat == SPU_ES )
i_delay = p_sys->i_spu_delay;
else
i_delay = 0;
if( libvlc_stats( p_input ) ) if( libvlc_stats( p_input ) )
{ {
vlc_mutex_lock( &p_input->p->counters.counters_lock ); vlc_mutex_lock( &p_input->p->counters.counters_lock );
...@@ -1568,12 +1584,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) ...@@ -1568,12 +1584,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
es->i_preroll_end = -1; es->i_preroll_end = -1;
} }
if( p_block->i_dts > 0 )
p_block->i_dts += i_delay;
if( p_block->i_pts > 0 )
p_block->i_pts += i_delay;
p_block->i_rate = 0; p_block->i_rate = 0;
if( !es->p_dec ) if( !es->p_dec )
......
...@@ -41,6 +41,11 @@ ...@@ -41,6 +41,11 @@
*/ */
void input_DecoderChangePause( decoder_t *, bool b_paused, mtime_t i_date ); void input_DecoderChangePause( decoder_t *, bool b_paused, mtime_t i_date );
/**
* This function changes the delay.
*/
void input_DecoderChangeDelay( decoder_t *, mtime_t i_delay );
/** /**
* This function warn the decoder about a discontinuity and allow flushing * This function warn the decoder about a discontinuity and allow flushing
* if requested. * if requested.
......
...@@ -335,14 +335,6 @@ void stream_AccessDelete( stream_t *s ); ...@@ -335,14 +335,6 @@ void stream_AccessDelete( stream_t *s );
void stream_AccessReset( stream_t *s ); void stream_AccessReset( stream_t *s );
void stream_AccessUpdate( stream_t *s ); void stream_AccessUpdate( stream_t *s );
/* decoder.c */
#define BLOCK_FLAG_CORE_FLUSH (1 <<BLOCK_FLAG_CORE_PRIVATE_SHIFT)
void input_DecoderDiscontinuity( decoder_t * p_dec, bool b_flush );
bool input_DecoderEmpty( decoder_t * p_dec );
int input_DecoderSetCcState( decoder_t *, bool b_decode, int i_channel );
int input_DecoderGetCcState( decoder_t *, bool *pb_decode, int i_channel );
void input_DecoderIsCcPresent( decoder_t *, bool pb_present[4] );
/* es_out.c */ /* es_out.c */
es_out_t *input_EsOutNew( input_thread_t *, int i_rate ); es_out_t *input_EsOutNew( input_thread_t *, int i_rate );
void input_EsOutDelete( es_out_t * ); void input_EsOutDelete( es_out_t * );
......
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