[vlc-devel] [PATCH 16/17] input: pass times measurement date to the player

Thomas Guillem thomas at gllm.fr
Tue Mar 9 15:15:45 UTC 2021


Passing the input times to the player is generally synchronous so the
system_date difference should be minimal (except if various lock are
blocking).

However, it will fixes input times delay when using timeshift.

Reminder: this input time is (unlikely) used by the player timer when
the demux doesn't send any PCR or ES.
---
 src/input/es_out.c           |  5 +++--
 src/input/es_out.h           | 11 ++++++-----
 src/input/es_out_timeshift.c |  4 ++++
 src/input/event.h            |  3 ++-
 src/input/input.c            |  6 ++++--
 src/input/input_internal.h   |  1 +
 src/player/input.c           |  4 +---
 7 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/input/es_out.c b/src/input/es_out.c
index 8618e725c06..723cd2186ec 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -3696,6 +3696,7 @@ static int EsOutVaPrivControlLocked( es_out_t *out, int query, va_list args )
         return VLC_SUCCESS;
     case ES_OUT_PRIV_SET_TIMES:
     {
+        vlc_tick_t i_system_date = va_arg( args, vlc_tick_t );
         double f_position = va_arg( args, double );
         vlc_tick_t i_time = va_arg( args, vlc_tick_t );
         vlc_tick_t i_length = va_arg( args, vlc_tick_t );
@@ -3723,10 +3724,10 @@ static int EsOutVaPrivControlLocked( es_out_t *out, int query, va_list args )
             if( f_position < 0 )
                 f_position = 0;
 
-            input_SendEventTimes( p_sys->p_input, f_position, i_time, i_length );
+            input_SendEventTimes( p_sys->p_input, i_system_date, f_position, i_time, i_length );
         }
         else
-            input_SendEventTimes( p_sys->p_input, 0.0, VLC_TICK_INVALID, i_length );
+            input_SendEventTimes( p_sys->p_input, VLC_TICK_INVALID, 0.0, VLC_TICK_INVALID, i_length );
         return VLC_SUCCESS;
     }
     case ES_OUT_PRIV_SET_JITTER:
diff --git a/src/input/es_out.h b/src/input/es_out.h
index 9c592a9d208..d5b2f7816a6 100644
--- a/src/input/es_out.h
+++ b/src/input/es_out.h
@@ -81,7 +81,7 @@ enum es_out_query_private_e
     ES_OUT_PRIV_SET_FRAME_NEXT,                     /*                          res=can fail */
 
     /* Set position/time/length */
-    ES_OUT_PRIV_SET_TIMES,                          /* arg1=double f_position arg2=vlc_tick_t i_time arg3=vlc_tick_t i_length res=cannot fail */
+    ES_OUT_PRIV_SET_TIMES,                          /* arg1=vlc_tick_t i_system_date arg2=double f_position arg3=vlc_tick_t i_time arg4=vlc_tick_t i_length res=cannot fail */
 
     /* Set jitter */
     ES_OUT_PRIV_SET_JITTER,                         /* arg1=vlc_tick_t i_pts_delay arg2= vlc_tick_t i_pts_jitter, arg2=int i_cr_average res=cannot fail */
@@ -203,11 +203,12 @@ static inline int es_out_SetFrameNext( es_out_t *p_out )
 {
     return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_FRAME_NEXT );
 }
-static inline void es_out_SetTimes( es_out_t *p_out, double f_position,
-                                    vlc_tick_t i_time, vlc_tick_t i_length )
+static inline void es_out_SetTimes( es_out_t *p_out, vlc_tick_t system_date,
+                                    double f_position, vlc_tick_t i_time,
+                                    vlc_tick_t i_length )
 {
-    int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_TIMES, f_position, i_time,
-                                    i_length );
+    int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_TIMES, system_date,
+                                    f_position, i_time, i_length );
     assert( !i_ret );
 }
 static inline void es_out_SetJitter( es_out_t *p_out,
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index d696bd28c12..32440484675 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -165,6 +165,7 @@ typedef struct attribute_packed
         } jitter;
         struct
         {
+            vlc_tick_t i_system_date;
             double  f_position;
             vlc_tick_t i_time;
             vlc_tick_t i_length;
@@ -1784,10 +1785,12 @@ static int CmdInitPrivControl( ts_cmd_privcontrol_t *p_cmd, int i_query, va_list
     }
     case ES_OUT_PRIV_SET_TIMES:
     {
+        vlc_tick_t i_system_date = va_arg( args, vlc_tick_t );
         double f_position = va_arg( args, double );
         vlc_tick_t i_time = va_arg( args, vlc_tick_t );
         vlc_tick_t i_length = va_arg( args, vlc_tick_t );
 
+        p_cmd->u.times.i_system_date = i_system_date;
         p_cmd->u.times.f_position = f_position;
         p_cmd->u.times.i_time = i_time;
         p_cmd->u.times.i_length = i_length;
@@ -1817,6 +1820,7 @@ static int CmdExecutePrivControl( es_out_t *p_tsout, ts_cmd_privcontrol_t *p_cmd
                                    p_cmd->u.jitter.i_cr_average );
     case ES_OUT_PRIV_SET_TIMES:
         return es_out_PrivControl( p_sys->p_out, i_query,
+                                   p_cmd->u.times.i_system_date,
                                    p_cmd->u.times.f_position,
                                    p_cmd->u.times.i_time,
                                    p_cmd->u.times.i_length );
diff --git a/src/input/event.h b/src/input/event.h
index 3899563889d..0fb7ef367a8 100644
--- a/src/input/event.h
+++ b/src/input/event.h
@@ -55,12 +55,13 @@ static inline void input_SendEventCapabilities(input_thread_t *p_input,
 }
 
 static inline void input_SendEventTimes(input_thread_t *p_input,
+                                        vlc_tick_t i_system_date,
                                         double f_position, vlc_tick_t i_time,
                                         vlc_tick_t i_length)
 {
     input_SendEvent(p_input, &(struct vlc_input_event) {
         .type = INPUT_EVENT_TIMES,
-        .times = { f_position, i_time, i_length }
+        .times = { i_system_date, f_position, i_time, i_length }
     });
 }
 
diff --git a/src/input/input.c b/src/input/input.c
index 940f311c358..9d66d838675 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -620,6 +620,8 @@ static void MainLoopStatistics( input_thread_t *p_input )
     vlc_tick_t i_time;
     vlc_tick_t i_length;
 
+    const vlc_tick_t system_now = vlc_tick_now();
+
     /* update input status variables */
     if( demux_Control( priv->master->p_demux,
                        DEMUX_GET_POSITION, &f_position ) )
@@ -631,7 +633,7 @@ static void MainLoopStatistics( input_thread_t *p_input )
     if( demux_Control( priv->master->p_demux, DEMUX_GET_LENGTH, &i_length ) )
         i_length = 0;
 
-    es_out_SetTimes( priv->p_es_out, f_position, i_time, i_length );
+    es_out_SetTimes( priv->p_es_out, system_now, f_position, i_time, i_length );
 
     struct input_stats_t new_stats;
     if( priv->stats != NULL )
@@ -1286,7 +1288,7 @@ static int Init( input_thread_t * p_input )
     if( i_length == 0 )
         i_length = input_item_GetDuration( priv->p_item );
 
-    input_SendEventTimes( p_input, 0.0, VLC_TICK_INVALID, i_length );
+    input_SendEventTimes( p_input, VLC_TICK_INVALID, 0.0, VLC_TICK_INVALID, i_length );
 
     if( !priv->b_preparsing )
     {
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index 1196c027310..4a9ccbe5fb8 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -160,6 +160,7 @@ struct vlc_input_event_state
 
 struct vlc_input_event_times
 {
+    vlc_tick_t system_date;
     float position;
     vlc_tick_t time;
     vlc_tick_t length;
diff --git a/src/player/input.c b/src/player/input.c
index 4f9b235e285..400be052077 100644
--- a/src/player/input.c
+++ b/src/player/input.c
@@ -752,7 +752,6 @@ input_thread_Events(input_thread_t *input_thread,
         case INPUT_EVENT_TIMES:
         {
             bool changed = false;
-            vlc_tick_t system_date = VLC_TICK_INVALID;
 
             if (event->times.time != VLC_TICK_INVALID
              && (input->time != event->times.time
@@ -760,7 +759,6 @@ input_thread_Events(input_thread_t *input_thread,
             {
                 input->time = event->times.time;
                 input->position = event->times.position;
-                system_date = vlc_tick_now();
                 changed = true;
                 vlc_player_SendEvent(player, on_position_changed,
                                      input->time, input->position);
@@ -782,7 +780,7 @@ input_thread_Events(input_thread_t *input_thread,
                     .rate = input->rate,
                     .ts = input->time,
                     .length = input->length,
-                    .system_date = system_date,
+                    .system_date = event->times.system_date,
                 };
                 vlc_player_UpdateTimer(player, NULL, false, &point, 0, 0);
             }
-- 
2.30.0



More information about the vlc-devel mailing list