From 5fd5aaf262c319d3324e326405ee04cd72a59c74 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Thu, 4 Mar 2010 23:03:40 +0100 Subject: [PATCH] Added an option (clock-jitter) to control the maximum compensated jitter. Only input jitters lower than clock-jitter will be compensated. You may set it to 0 to avoid having the latency increased automatically by VLC. --- src/input/es_out.c | 37 +++++++++++++++++++++++++------------ src/input/input.c | 3 --- src/input/input_internal.h | 3 +++ src/libvlc-module.c | 8 ++++++++ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/input/es_out.c b/src/input/es_out.c index f717338736..67324f1864 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -148,6 +148,7 @@ struct es_out_sys_t /* Clock configuration */ mtime_t i_pts_delay; + mtime_t i_pts_jitter; int i_cr_average; int i_rate; @@ -310,6 +311,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ) p_sys->i_rate = i_rate; p_sys->i_pts_delay = 0; + p_sys->i_pts_jitter = 0; p_sys->i_cr_average = 0; p_sys->b_buffering = true; @@ -2307,23 +2309,32 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) else if( b_late && ( !p_sys->p_input->p->p_sout || !p_sys->p_input->p->b_out_pace_control ) ) { + const mtime_t i_pts_delay_base = p_sys->i_pts_delay - p_sys->i_pts_jitter; mtime_t i_pts_delay = input_clock_GetJitter( p_pgrm->p_clock ); /* Avoid dangerously high value */ - const mtime_t i_pts_delay_max = 30000000; - if( i_pts_delay > i_pts_delay_max ) - i_pts_delay = __MAX( i_pts_delay_max, p_sys->i_pts_delay ); + const mtime_t i_jitter_max = INT64_C(1000) * var_InheritInteger( p_sys->p_input, "clock-jitter" ); + if( i_pts_delay > __MIN( i_pts_delay_base + i_jitter_max, INPUT_PTS_DELAY_MAX ) ) + { + msg_Err( p_sys->p_input, + "ES_OUT_SET_(GROUP_)PCR is called too late (jitter of %d ms ingnored)", + (int)(i_pts_delay - i_pts_delay_base) / 1000 ); + i_pts_delay = p_sys->i_pts_delay; + } + else + { + msg_Err( p_sys->p_input, + "ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to %d ms)", + (int)(i_pts_delay/1000) ); + } /* Force a rebufferization when we are too late */ - msg_Err( p_sys->p_input, - "ES_OUT_SET_(GROUP_)PCR is called too late, increasing pts_delay to %d ms", - (int)(i_pts_delay/1000) ); /* It is not really good, as we throw away already buffered data * TODO have a mean to correctly reenter bufferization */ es_out_Control( out, ES_OUT_RESET_PCR ); - es_out_SetJitter( out, i_pts_delay, 0, p_sys->i_cr_average ); + es_out_SetJitter( out, i_pts_delay_base, i_pts_delay - i_pts_delay_base, p_sys->i_cr_average ); } } return VLC_SUCCESS; @@ -2602,14 +2613,16 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) mtime_t i_pts_jitter = (mtime_t)va_arg( args, mtime_t ); int i_cr_average = (int)va_arg( args, int ); - if( i_pts_delay + i_pts_jitter == p_sys->i_pts_delay && - i_cr_average == p_sys->i_cr_average ) - return VLC_SUCCESS; + bool b_change_clock = + i_pts_delay + i_pts_jitter != p_sys->i_pts_delay || + i_cr_average != p_sys->i_cr_average; - p_sys->i_pts_delay = i_pts_delay + i_pts_jitter; + assert( i_pts_jitter >= 0 ); + p_sys->i_pts_delay = i_pts_delay + i_pts_jitter; + p_sys->i_pts_jitter = i_pts_jitter; p_sys->i_cr_average = i_cr_average; - for( int i = 0; i < p_sys->i_pgrm; i++ ) + for( int i = 0; i < p_sys->i_pgrm && b_change_clock; i++ ) input_clock_SetJitter( p_sys->pgrm[i]->p_clock, i_pts_delay + i_pts_jitter, i_cr_average ); return VLC_SUCCESS; diff --git a/src/input/input.c b/src/input/input.c index 892e54d64d..f4081ccbce 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -110,9 +110,6 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */ -/* Do not let a pts_delay from access/demux go beyong 60s */ -#define INPUT_PTS_DELAY_MAX INT64_C(60000000) - #undef input_Create /** * Create a new input_thread_t. diff --git a/src/input/input_internal.h b/src/input/input_internal.h index 2dc33b7fea..2bb59a20f1 100644 --- a/src/input/input_internal.h +++ b/src/input/input_internal.h @@ -220,6 +220,9 @@ enum input_control_e */ void input_ControlPush( input_thread_t *, int i_type, vlc_value_t * ); +/* Bound pts_delay */ +#define INPUT_PTS_DELAY_MAX INT64_C(60000000) + /********************************************************************** * Item metadata **********************************************************************/ diff --git a/src/libvlc-module.c b/src/libvlc-module.c index e4594411d4..9398a0439e 100644 --- a/src/libvlc-module.c +++ b/src/libvlc-module.c @@ -634,6 +634,11 @@ static const char *const ppsz_pos_descriptions[] = "real-time sources. Use this if you experience jerky playback of " \ "network streams.") +#define CLOCK_JITTER_TEXT N_("Clock jitter") +#define CLOCK_JITTER_LONGTEXT N_( \ + "It tells the clock algorithms what is the maximal input jitter that " \ + "is considered valid and can be compensated (in milliseconds)" ) + #define NETSYNC_TEXT N_("Network synchronisation" ) #define NETSYNC_LONGTEXT N_( "This allows you to remotely " \ "synchronise clocks for server and client. The detailed settings " \ @@ -1900,6 +1905,9 @@ vlc_module_begin () add_integer( "clock-synchro", -1, NULL, CLOCK_SYNCHRO_TEXT, CLOCK_SYNCHRO_LONGTEXT, true ) change_integer_list( pi_clock_values, ppsz_clock_descriptions, NULL ) + add_integer( "clock-jitter", 5 * CLOCK_FREQ/1000, NULL, CLOCK_JITTER_TEXT, + CLOCK_JITTER_LONGTEXT, true ) + change_safe() add_bool( "network-synchronisation", false, NULL, NETSYNC_TEXT, NETSYNC_LONGTEXT, true ) -- 2.39.2