mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
netclientclock: Handle time server reset correctly
If the time server is restarted with a time in the past the net client clock will not report the new time anymore as this would mean that the clock moves back in time which it does not do. Now the clock will be kept alive but marked as corrupted and will not be re-used from the cache. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4802>
This commit is contained in:
parent
ebf7966a26
commit
df41d11a7d
1 changed files with 26 additions and 1 deletions
|
@ -137,12 +137,14 @@ struct _GstNetClientInternalClock
|
|||
GSocketAddress *servaddr;
|
||||
GCancellable *cancel;
|
||||
gboolean made_cancel_fd;
|
||||
gboolean marked_corrupted;
|
||||
|
||||
GstClockTime timeout_expiration;
|
||||
GstClockTime roundtrip_limit;
|
||||
GstClockTime rtt_avg;
|
||||
GstClockTime minimum_update_interval;
|
||||
GstClockTime last_remote_poll_interval;
|
||||
GstClockTime last_remote_time;
|
||||
GstClockTime remote_avg_old;
|
||||
guint skipped_updates;
|
||||
GstClockTime last_rtts[MEDIAN_PRE_FILTERING_WINDOW];
|
||||
|
@ -230,6 +232,7 @@ gst_net_client_internal_clock_init (GstNetClientInternalClock * self)
|
|||
self->last_remote_poll_interval = GST_CLOCK_TIME_NONE;
|
||||
self->skipped_updates = 0;
|
||||
self->last_rtts_missing = MEDIAN_PRE_FILTERING_WINDOW;
|
||||
self->marked_corrupted = FALSE;
|
||||
self->remote_avg_old = 0;
|
||||
}
|
||||
|
||||
|
@ -374,6 +377,11 @@ gst_net_client_internal_clock_observe_times (GstNetClientInternalClock * self,
|
|||
G_GUINT64_FORMAT " local2 %" G_GUINT64_FORMAT, local_1, remote_1,
|
||||
remote_2, local_2);
|
||||
|
||||
/* if we are ahead of time the time server may have been reset */
|
||||
if (self->last_remote_time > remote_1 || self->marked_corrupted)
|
||||
goto corrupted;
|
||||
self->last_remote_time = remote_1;
|
||||
|
||||
/* If the server told us a poll interval and it's bigger than the
|
||||
* one configured via the property, use the server's */
|
||||
if (self->last_remote_poll_interval != GST_CLOCK_TIME_NONE &&
|
||||
|
@ -649,6 +657,14 @@ bogus_observation:
|
|||
/* Schedule a new packet again soon */
|
||||
self->timeout_expiration = gst_util_get_timestamp () + (GST_SECOND / 4);
|
||||
return;
|
||||
|
||||
corrupted:
|
||||
if (!self->marked_corrupted) {
|
||||
GST_ERROR_OBJECT (self, "Remote clock time reverted, mark clock invalid");
|
||||
self->marked_corrupted = TRUE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
return;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
|
@ -1196,7 +1212,13 @@ gst_net_client_clock_finalize (GObject * object)
|
|||
update_clock_cache (cache);
|
||||
} else {
|
||||
GstClock *sysclock = gst_system_clock_obtain ();
|
||||
GstClockTime time = gst_clock_get_time (sysclock) + 60 * GST_SECOND;
|
||||
GstClockTime time = gst_clock_get_time (sysclock);
|
||||
GstNetClientInternalClock *internal_clock =
|
||||
GST_NET_CLIENT_INTERNAL_CLOCK (cache->clock);
|
||||
|
||||
/* only defer deletion if the clock is not marked corrupted */
|
||||
if (!internal_clock->marked_corrupted)
|
||||
time += 60 * GST_SECOND;
|
||||
|
||||
cache->remove_id = gst_clock_new_single_shot_id (sysclock, time);
|
||||
gst_clock_id_wait_async (cache->remove_id, remove_clock_cache, cache,
|
||||
|
@ -1365,6 +1387,9 @@ gst_net_client_clock_constructed (GObject * object)
|
|||
GstNetClientInternalClock *internal_clock =
|
||||
GST_NET_CLIENT_INTERNAL_CLOCK (tmp->clock);
|
||||
|
||||
if (internal_clock->marked_corrupted)
|
||||
break;
|
||||
|
||||
if (strcmp (internal_clock->address, self->priv->address) == 0 &&
|
||||
internal_clock->port == self->priv->port) {
|
||||
cache = tmp;
|
||||
|
|
Loading…
Reference in a new issue