[vlc-devel] [PATCH V3 05/19] clock: forward clock update points

Thomas Guillem thomas at gllm.fr
Fri Sep 6 17:20:35 CEST 2019


---
 src/clock/clock.c  | 66 +++++++++++++++++++++++++++++++++++++---------
 src/clock/clock.h  | 29 ++++++++++++++++++--
 src/input/es_out.c |  5 ++--
 3 files changed, 83 insertions(+), 17 deletions(-)

diff --git a/src/clock/clock.c b/src/clock/clock.c
index c20f241a1d..9d408ee3b5 100644
--- a/src/clock/clock.c
+++ b/src/clock/clock.c
@@ -72,6 +72,9 @@ struct vlc_clock_t
     vlc_clock_main_t *owner;
     vlc_tick_t delay;
     vlc_tick_t dejitter;
+
+    const struct vlc_clock_cbs *cbs;
+    void *cbs_data;
 };
 
 static vlc_tick_t main_stream_to_system(vlc_clock_main_t *main_clock,
@@ -139,15 +142,25 @@ static void vlc_clock_main_reset(vlc_clock_main_t *main_clock)
     vlc_cond_broadcast(&main_clock->cond);
 }
 
+static inline void vlc_clock_on_update(vlc_clock_t *clock,
+                                       vlc_tick_t system_now,
+                                       vlc_tick_t ts, double rate)
+{
+    if (clock->cbs)
+        clock->cbs->on_update(system_now, ts, rate, clock->cbs_data);
+}
+
 static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
                                           vlc_tick_t system_now,
-                                          vlc_tick_t ts, double rate)
+                                          vlc_tick_t original_ts, double rate)
 {
     vlc_clock_main_t *main_clock = clock->owner;
 
-    if (unlikely(ts == VLC_TICK_INVALID || system_now == VLC_TICK_INVALID))
+    if (unlikely(original_ts == VLC_TICK_INVALID
+     || system_now == VLC_TICK_INVALID))
         return VLC_TICK_INVALID;
-    ts += clock->delay;
+
+    const vlc_tick_t ts = original_ts + clock->delay;
 
     vlc_mutex_lock(&main_clock->lock);
 
@@ -173,7 +186,11 @@ static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
 
     main_clock->rate = rate;
     vlc_cond_broadcast(&main_clock->cond);
+
+    original_ts = vlc_clock_main_update_origin(main_clock, original_ts);
     vlc_mutex_unlock(&main_clock->lock);
+
+    vlc_clock_on_update(clock, system_now, original_ts, rate);
     return VLC_TICK_INVALID;
 }
 
@@ -203,6 +220,8 @@ static void vlc_clock_master_reset(vlc_clock_t *clock)
     }
 
     vlc_mutex_unlock(&main_clock->lock);
+
+    vlc_clock_on_update(clock, VLC_TICK_INVALID, VLC_TICK_INVALID, 1.f);
 }
 
 static vlc_tick_t vlc_clock_master_set_delay(vlc_clock_t *clock, vlc_tick_t delay)
@@ -312,7 +331,11 @@ static vlc_tick_t vlc_clock_slave_update(vlc_clock_t *clock,
     vlc_mutex_lock(&main_clock->lock);
 
     vlc_tick_t computed = clock->to_system_locked(clock, system_now, ts, rate);
+
+    ts = vlc_clock_main_update_origin(main_clock, ts);
     vlc_mutex_unlock(&main_clock->lock);
+
+    vlc_clock_on_update(clock, computed, ts, rate);
     return computed != INT64_MAX ? computed - system_now : INT64_MAX;
 }
 
@@ -322,7 +345,10 @@ static void vlc_clock_slave_reset(vlc_clock_t *clock)
     vlc_mutex_lock(&main_clock->lock);
     main_clock->wait_sync_ref =
         clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
+
     vlc_mutex_unlock(&main_clock->lock);
+
+    vlc_clock_on_update(clock, VLC_TICK_INVALID, VLC_TICK_INVALID, 1.0f);
 }
 
 static vlc_tick_t vlc_clock_slave_set_delay(vlc_clock_t *clock, vlc_tick_t delay)
@@ -369,7 +395,6 @@ static void vlc_clock_slave_set_dejitter(vlc_clock_t *clock, vlc_tick_t delay)
     VLC_UNUSED(delay);
 }
 
-
 vlc_clock_main_t *vlc_clock_main_New(void)
 {
     vlc_clock_main_t *main_clock = malloc(sizeof(vlc_clock_main_t));
@@ -400,7 +425,7 @@ vlc_clock_main_t *vlc_clock_main_New(void)
     main_clock->wait_sync_ref = main_clock->last =
         clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
 
-    clock_point_t first_pcr_point = clock_point_Create(VLC_TICK_0, VLC_TICK_0);
+    clock_point_t first_pcr_point = clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
     bool success = vlc_vector_push(&main_clock->origin_map, first_pcr_point);
     assert(success);
 
@@ -554,7 +579,9 @@ static void vlc_clock_set_slave_callbacks(vlc_clock_t *clock)
     clock->to_system_locked = vlc_clock_slave_to_system_locked;
 }
 
-vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock)
+static vlc_clock_t *vlc_clock_main_Create(vlc_clock_main_t *main_clock,
+                                          const struct vlc_clock_cbs *cbs,
+                                          void *cbs_data)
 {
     vlc_clock_t *clock = malloc(sizeof(vlc_clock_t));
     if (clock == NULL)
@@ -562,6 +589,20 @@ vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock)
 
     clock->owner = main_clock;
     clock->delay = 0;
+    clock->cbs = cbs;
+    clock->cbs_data = cbs_data;
+    assert(!cbs || cbs->on_update);
+
+    return clock;
+}
+
+vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
+                                         const struct vlc_clock_cbs *cbs,
+                                         void *cbs_data)
+{
+    vlc_clock_t *clock = vlc_clock_main_Create(main_clock, cbs, cbs_data);
+    if (!clock)
+        return NULL;
 
     vlc_mutex_lock(&main_clock->lock);
     if (main_clock->master != NULL)
@@ -577,15 +618,14 @@ vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock)
     return clock;
 }
 
-vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock)
+vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
+                                        const struct vlc_clock_cbs *cbs,
+                                        void *cbs_data)
 {
-    vlc_clock_t *clock = malloc(sizeof(vlc_clock_t));
-    if (clock == NULL)
+    vlc_clock_t *clock = vlc_clock_main_Create(main_clock, cbs, cbs_data);
+    if (!clock)
         return NULL;
 
-    clock->owner = main_clock;
-    clock->delay = 0;
-
     vlc_mutex_lock(&main_clock->lock);
     vlc_clock_set_slave_callbacks(clock);
     main_clock->rc++;
@@ -596,7 +636,7 @@ vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock)
 
 vlc_clock_t *vlc_clock_CreateSlave(const vlc_clock_t *clock)
 {
-    return vlc_clock_main_CreateSlave(clock->owner);
+    return vlc_clock_main_CreateSlave(clock->owner, NULL, NULL);
 }
 
 void vlc_clock_main_SetMaster(vlc_clock_main_t *main_clock, vlc_clock_t *clock)
diff --git a/src/clock/clock.h b/src/clock/clock.h
index 4adce5789d..4af235cce4 100644
--- a/src/clock/clock.h
+++ b/src/clock/clock.h
@@ -30,6 +30,27 @@ enum vlc_clock_master_source
 typedef struct vlc_clock_main_t vlc_clock_main_t;
 typedef struct vlc_clock_t vlc_clock_t;
 
+/**
+ * Callbacks for the owner of the main clock
+ */
+struct vlc_clock_cbs
+{
+    /**
+     * Called when a clock is updated
+     *
+     * @param system_ts system date when the ts will be rendered,
+     * VLC_TICK_INVALID when the clock is reset or INT64_MAX when the update is
+     * forced (an output was still rendered while paused for example). Note:
+     * when valid, this date can be in the future, it is not necessarily now.
+     * @param ts stream timestamp or VLC_TICK_INVALID when the clock is reset,
+     * should be subtracted with VLC_TICK_0 to get the original value
+     * @param rate rate used when updated
+     * @param data opaque pointer set from vlc_clock_main_New()
+     */
+    void (*on_update)(vlc_tick_t system_ts, vlc_tick_t ts, double rate,
+                      void *data);
+};
+
 /**
  * This function creates the vlc_clock_main_t of the program
  */
@@ -90,14 +111,18 @@ void vlc_clock_main_SetMaster(vlc_clock_main_t *main_clock, vlc_clock_t *clock);
  *
  * You must use vlc_clock_Delete to free it.
  */
-vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock);
+vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
+                                         const struct vlc_clock_cbs *cbs,
+                                         void *cbs_data);
 
 /**
  * This function creates a new slave vlc_clock_t interface
  *
  * You must use vlc_clock_Delete to free it.
  */
-vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock);
+vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
+                                         const struct vlc_clock_cbs *cbs,
+                                         void *cbs_data);
 
 /**
  * This function creates a new slave vlc_clock_t interface
diff --git a/src/input/es_out.c b/src/input/es_out.c
index c401e7251d..366beefefe 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -2007,9 +2007,10 @@ static void EsOutCreateDecoder( es_out_t *out, es_out_id_t *p_es )
      && p_es->fmt.i_cat == p_sys->i_master_source_cat
      && p_es->p_pgrm->p_master_clock == NULL )
         p_es->p_pgrm->p_master_clock = p_es->p_clock =
-            vlc_clock_main_CreateMaster( p_es->p_pgrm->p_main_clock );
+            vlc_clock_main_CreateMaster( p_es->p_pgrm->p_main_clock, NULL, NULL );
     else
-        p_es->p_clock = vlc_clock_main_CreateSlave( p_es->p_pgrm->p_main_clock );
+        p_es->p_clock = vlc_clock_main_CreateSlave( p_es->p_pgrm->p_main_clock,
+                                                    NULL, NULL );
     if( !p_es->p_clock )
         return;
 
-- 
2.20.1



More information about the vlc-devel mailing list