/* PCR system clock manipulation for external clock synchronization */
ES_OUT_GET_PCR_SYSTEM, /* arg1=mtime_t * res=can fail */
+ ES_OUT_MODIFY_PCR_SYSTEM, /* arg1=int is_absolute, arg2=mtime_t, res=can fail */
/* First value usable for private control */
ES_OUT_PRIVATE_START = 0x10000,
{
return es_out_Control( out, ES_OUT_GET_PCR_SYSTEM, pi_system );
}
+static inline int es_out_ControlModifyPcrSystem( es_out_t *out, bool b_absolute, mtime_t i_system )
+{
+ return es_out_Control( out, ES_OUT_MODIFY_PCR_SYSTEM, b_absolute, i_system );
+}
/**
* @}
clock_point_t ref;
bool b_has_reference;
+ /* External clock drift */
+ mtime_t i_external_clock;
+ bool b_has_external_clock;
+
/* Current modifiers */
bool b_paused;
int i_rate;
vlc_mutex_init( &cl->lock );
cl->b_has_reference = false;
cl->ref = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
+ cl->b_has_external_clock = false;
cl->last = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
cl->b_has_reference = true;
cl->ref = clock_point_Create( i_ck_stream,
__MAX( cl->i_ts_max + CR_MEAN_PTS_GAP, i_ck_system ) );
+ cl->b_has_external_clock = false;
}
/* Compute the drift between the stream clock and the system clock
cl->b_has_reference = false;
cl->ref = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
+ cl->b_has_external_clock = false;
cl->i_ts_max = VLC_TS_INVALID;
vlc_mutex_unlock( &cl->lock );
return VLC_SUCCESS;
}
-void input_clock_ChangeSystemOrigin( input_clock_t *cl, mtime_t i_system )
+void input_clock_ChangeSystemOrigin( input_clock_t *cl, bool b_absolute, mtime_t i_system )
{
vlc_mutex_lock( &cl->lock );
assert( cl->b_has_reference );
- const mtime_t i_offset = i_system - cl->ref.i_system - ClockGetTsOffset( cl );
+ mtime_t i_offset;
+ if( b_absolute )
+ {
+ i_offset = i_system - cl->ref.i_system - ClockGetTsOffset( cl );
+ }
+ else
+ {
+ if( !cl->b_has_external_clock )
+ {
+ cl->b_has_external_clock = true;
+ cl->i_external_clock = i_system;
+ }
+ i_offset = i_system - cl->i_external_clock;
+ }
cl->ref.i_system += i_offset;
cl->last.i_system += i_offset;
mtime_t input_clock_GetSystemOrigin( input_clock_t * );
/**
- * This function allows to rebase the original system value date.
- * It can be called only imediatly after a input_clock_Update call.
- * FIXME ugly
+ * This function allows to rebase the original system value date (a valid
+ * reference point must have been set).
+ * When using the absolute mode, it will create a discontinuity unless
+ * called imediatly after a input_clock_Update.
*/
-void input_clock_ChangeSystemOrigin( input_clock_t *, mtime_t i_system );
+void input_clock_ChangeSystemOrigin( input_clock_t *, bool b_absolute, mtime_t i_system );
/**
* This function converts a pair of timestamp from stream clock to system clock.
const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/
const mtime_t i_current_date = p_sys->b_paused ? p_sys->i_pause_date : mdate();
- input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, i_current_date + i_wakeup_delay - i_buffering_duration );
+ input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, true,
+ i_current_date + i_wakeup_delay - i_buffering_duration );
for( int i = 0; i < p_sys->i_es; i++ )
{
return VLC_SUCCESS;
}
+ case ES_OUT_MODIFY_PCR_SYSTEM:
+ {
+ if( p_sys->b_buffering )
+ return VLC_EGENERIC;
+
+ es_out_pgrm_t *p_pgrm = p_sys->p_pgrm;
+ if( !p_pgrm )
+ return VLC_EGENERIC;
+
+ const bool b_absolute = va_arg( args, int );
+ const mtime_t i_system = va_arg( args, mtime_t );
+ input_clock_ChangeSystemOrigin( p_pgrm->p_clock, b_absolute, i_system );
+ return VLC_SUCCESS;
+ }
+
default:
msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
return VLC_EGENERIC;
mtime_t *pi_system = (mtime_t*)va_arg( args, mtime_t * );
return es_out_ControlGetPcrSystem( p_sys->p_out, pi_system );
}
+ case ES_OUT_MODIFY_PCR_SYSTEM:
+ {
+ const bool b_absolute = va_arg( args, int );
+ const mtime_t i_system = va_arg( args, mtime_t );
+
+ if( b_absolute && p_sys->b_delayed )
+ return VLC_EGENERIC;
+
+ return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system );
+ }
default:
msg_Err( p_sys->p_input, "Unknown es_out_Control query !" );
assert(0);