[vlc-commits] [Git][videolan/vlc][master] 3 commits: clock: add missing locked comment

Steve Lhomme (@robUx4) gitlab at videolan.org
Wed Nov 15 16:52:59 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
e2b85f16 by Thomas Guillem at 2023-11-15T16:24:50+00:00
clock: add missing locked comment

- - - - -
10dc07b8 by Thomas Guillem at 2023-11-15T16:24:50+00:00
clock: add event callbacks

A slave clock can register events that are sent from the master clock.

For now, there is only one event: discontinuity.
For now, the discontinuity event is only sent when updating the first
point.

Refs #27025

- - - - -
62a2fcc8 by Thomas Guillem at 2023-11-15T16:24:50+00:00
video_output: wake up in case of clock discontinuities

This fixes the first 0-3 frames being dropped when starting of after a seek.

Fixes #27025

- - - - -


3 changed files:

- src/clock/clock.c
- src/clock/clock.h
- src/video_output/video_output.c


Changes:

=====================================
src/clock/clock.c
=====================================
@@ -26,11 +26,19 @@
 #include <assert.h>
 #include <limits.h>
 #include <vlc_tracer.h>
+#include <vlc_vector.h>
 #include "clock.h"
 #include "clock_internal.h"
 
 #define COEFF_THRESHOLD 0.2 /* between 0.8 and 1.2 */
 
+struct vlc_clock_event
+{
+    vlc_clock_t *clock;
+    const struct vlc_clock_event_cbs *cbs;
+    void *data;
+};
+
 struct vlc_clock_main_t
 {
     struct vlc_logger *logger;
@@ -61,6 +69,8 @@ struct vlc_clock_main_t
     clock_point_t first_pcr;
     vlc_tick_t output_dejitter; /* Delay used to absorb the output clock jitter */
     vlc_tick_t input_dejitter; /* Delay used to absorb the input jitter */
+
+    struct VLC_VECTOR(struct vlc_clock_event) events;
 };
 
 struct vlc_clock_t
@@ -82,6 +92,55 @@ struct vlc_clock_t
     void *cbs_data;
 };
 
+int vlc_clock_RegisterEvents(vlc_clock_t *clock,
+                             const struct vlc_clock_event_cbs *cbs,
+                             void *data)
+{
+    vlc_clock_main_t *main_clock = clock->owner;
+
+    vlc_mutex_lock(&main_clock->lock);
+    if (clock == main_clock->master || clock == main_clock->input_master)
+    {
+        /* Events are only from master to slaves */
+        vlc_mutex_unlock(&main_clock->lock);
+        return -EINVAL;
+    }
+
+    int ret;
+    if (cbs != NULL)
+    {
+        const struct vlc_clock_event event = {
+            .clock = clock,
+            .cbs = cbs,
+            .data = data,
+        };
+        ret = vlc_vector_push(&main_clock->events, event) ? 0 : -ENOMEM;
+    }
+    else
+    {
+        ret = -EINVAL;
+        const struct vlc_clock_event *event;
+        vlc_vector_foreach_ref(event, &main_clock->events)
+            if (event->clock == clock)
+            {
+                vlc_vector_remove(&main_clock->events, vlc_vector_idx_event);
+                ret = 0;
+                break;
+            }
+        assert(ret == 0);
+    }
+
+    vlc_mutex_unlock(&main_clock->lock);
+    return ret;
+}
+
+#define vlc_clock_SendEvent(main_clock, event) { \
+    const struct vlc_clock_event *event; \
+    vlc_vector_foreach_ref(event, &main_clock->events) \
+        if (event->cbs->on_##event != NULL) \
+            event->cbs->on_##event(event->data); \
+}
+
 static vlc_tick_t main_stream_to_system(vlc_clock_main_t *main_clock,
                                         vlc_tick_t ts)
 {
@@ -172,6 +231,8 @@ static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
                                               clock->track_str_id,
                                               "reset_bad_source");
 
+                    vlc_clock_SendEvent(main_clock, discontinuity);
+
                     /* Reset and continue (calculate the offset from the
                      * current point) */
                     vlc_clock_main_reset(main_clock);
@@ -188,6 +249,8 @@ static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
             main_clock->wait_sync_ref_priority = UINT_MAX;
             main_clock->wait_sync_ref =
                 clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
+
+            vlc_clock_SendEvent(main_clock, discontinuity);
         }
 
         main_clock->offset =
@@ -475,6 +538,8 @@ vlc_clock_main_t *vlc_clock_main_New(struct vlc_logger *parent_logger, struct vl
     AvgInit(&main_clock->coeff_avg, 10);
     AvgResetAndFill(&main_clock->coeff_avg, main_clock->coeff);
 
+    vlc_vector_init(&main_clock->events);
+
     return main_clock;
 }
 
@@ -552,6 +617,10 @@ void vlc_clock_main_Delete(vlc_clock_main_t *main_clock)
     assert(main_clock->rc == 1);
     if (main_clock->logger != NULL)
         vlc_LogDestroy(main_clock->logger);
+
+    assert(main_clock->events.size == 0);
+    vlc_vector_destroy(&main_clock->events);
+
     free(main_clock);
 }
 


=====================================
src/clock/clock.h
=====================================
@@ -54,6 +54,22 @@ struct vlc_clock_cbs
                       void *data);
 };
 
+/**
+ * Event callbacks for the user of a vlc_clock_t
+ */
+struct vlc_clock_event_cbs
+{
+    /**
+     * Called when the master source triggered a discontinuity.
+     *
+     * A discontinuity happens when:
+     *  - The first point is updated from the master source
+     *
+     * @param data opaque pointer set from vlc_clock_main_New()
+     */
+    void (*on_discontinuity)(void *data);
+};
+
 /**
  * This function creates the vlc_clock_main_t of the program
  */
@@ -209,9 +225,23 @@ int vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_deadline);
 
 /**
  * Wake up any vlc_clock_Wait()
+ *
+ * The clock mutex must be locked.
  */
 void vlc_clock_Wake(vlc_clock_t *clock);
 
+/**
+ * Register for events
+ *
+ * @param clock the clock used by the source
+ * @param cbs valid pointer to register events or NULL to unregister
+ * @param data opaque data used by cbs
+ * @return 0 in case of success
+ */
+int vlc_clock_RegisterEvents(vlc_clock_t *clock,
+                             const struct vlc_clock_event_cbs *cbs,
+                             void *data);
+
 /**
  * This function converts a timestamp from stream to system
  *


=====================================
src/video_output/video_output.c
=====================================
@@ -1913,6 +1913,8 @@ static void vout_ReleaseDisplay(vout_thread_sys_t *vout)
     if (sys->spu)
         spu_Detach(sys->spu);
 
+    vlc_clock_RegisterEvents(sys->clock, NULL, NULL);
+
     vlc_mutex_lock(&sys->clock_lock);
     sys->clock = NULL;
     vlc_mutex_unlock(&sys->clock_lock);
@@ -2191,6 +2193,20 @@ static void vout_InitSource(vout_thread_sys_t *vout)
     }
 }
 
+static void clock_event_OnDiscontinuity(void *data)
+{
+    vout_thread_sys_t *vout = data;
+    vout_thread_sys_t *sys = vout;
+
+    /* The Render thread wait for a deadline that is either:
+     *  - VOUT_REDISPLAY_DELAY
+     *  - calculated from the clock
+     * In case of a clock discontinuity, we need to wake up the Render thread,
+     * in order to trigger the rendering of the next picture, if new timings
+     * require it. */
+    vout_control_Wake(&sys->control);
+}
+
 int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input_thread_t *input)
 {
     vout_thread_sys_t *vout = VOUT_THREAD_TO_SYS(cfg->vout);
@@ -2242,6 +2258,11 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
     sys->clock = cfg->clock;
     vlc_mutex_unlock(&sys->clock_lock);
 
+    static const struct vlc_clock_event_cbs clock_event_cbs = {
+        .on_discontinuity = clock_event_OnDiscontinuity,
+    };
+    vlc_clock_RegisterEvents(sys->clock, &clock_event_cbs, vout);
+
     sys->delay = 0;
 
     if (vout_Start(vout, vctx, cfg))
@@ -2262,6 +2283,7 @@ error_thread:
     vout_ReleaseDisplay(vout);
 error_display:
     vout_DisableWindow(vout);
+    vlc_clock_RegisterEvents(sys->clock, NULL, NULL);
     vlc_mutex_lock(&sys->clock_lock);
     sys->clock = NULL;
     vlc_mutex_unlock(&sys->clock_lock);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/790d36399e495b27c8ca256c3750453209773226...62a2fcc8d6d07d371f8611c480b5ea5330fd7729

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/790d36399e495b27c8ca256c3750453209773226...62a2fcc8d6d07d371f8611c480b5ea5330fd7729
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list