[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