summaryrefslogtreecommitdiffstats
path: root/src/gst/gstpipewireclock.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gst/gstpipewireclock.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/gst/gstpipewireclock.c b/src/gst/gstpipewireclock.c
new file mode 100644
index 0000000..44b1158
--- /dev/null
+++ b/src/gst/gstpipewireclock.c
@@ -0,0 +1,127 @@
+/* GStreamer
+ *
+ * Copyright © 2018 Wim Taymans
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <gst/gst.h>
+
+#include "gstpipewireclock.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_pipewire_clock_debug_category);
+#define GST_CAT_DEFAULT gst_pipewire_clock_debug_category
+
+G_DEFINE_TYPE (GstPipeWireClock, gst_pipewire_clock, GST_TYPE_SYSTEM_CLOCK);
+
+GstClock *
+gst_pipewire_clock_new (struct pw_stream *stream, GstClockTime last_time)
+{
+ GstPipeWireClock *clock;
+
+ clock = g_object_new (GST_TYPE_PIPEWIRE_CLOCK, NULL);
+ clock->stream = stream;
+ clock->last_time = last_time;
+ clock->time_offset = last_time;
+
+ return GST_CLOCK_CAST (clock);
+}
+
+static GstClockTime
+gst_pipewire_clock_get_internal_time (GstClock * clock)
+{
+ GstPipeWireClock *pclock = (GstPipeWireClock *) clock;
+ GstClockTime result;
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+#if 0
+ struct pw_time t;
+ if (pclock->stream == NULL ||
+ pw_stream_get_time (pclock->stream, &t) < 0 ||
+ t.rate.denom == 0)
+ return pclock->last_time;
+
+ result = gst_util_uint64_scale_int (t.ticks, GST_SECOND * t.rate.num, t.rate.denom);
+ result += SPA_TIMESPEC_TO_NSEC(&ts) - t.now;
+
+ result += pclock->time_offset;
+ pclock->last_time = result;
+
+ GST_DEBUG ("%"PRId64", %d/%d %"PRId64" %"PRId64,
+ t.ticks, t.rate.num, t.rate.denom, t.now, result);
+#else
+ result = SPA_TIMESPEC_TO_NSEC(&ts);
+ result += pclock->time_offset;
+ pclock->last_time = result;
+#endif
+
+ return result;
+}
+
+static void
+gst_pipewire_clock_finalize (GObject * object)
+{
+ GstPipeWireClock *clock = GST_PIPEWIRE_CLOCK (object);
+
+ GST_DEBUG_OBJECT (clock, "finalize");
+
+ G_OBJECT_CLASS (gst_pipewire_clock_parent_class)->finalize (object);
+}
+
+static void
+gst_pipewire_clock_class_init (GstPipeWireClockClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstClockClass *gstclock_class = GST_CLOCK_CLASS (klass);
+
+ gobject_class->finalize = gst_pipewire_clock_finalize;
+
+ gstclock_class->get_internal_time = gst_pipewire_clock_get_internal_time;
+
+ GST_DEBUG_CATEGORY_INIT (gst_pipewire_clock_debug_category, "pipewireclock", 0,
+ "debug category for pipewireclock object");
+}
+
+static void
+gst_pipewire_clock_init (GstPipeWireClock * clock)
+{
+ GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER);
+}
+
+void
+gst_pipewire_clock_reset (GstPipeWireClock * clock, GstClockTime time)
+{
+ GstClockTimeDiff time_offset;
+
+ if (clock->last_time >= time)
+ time_offset = clock->last_time - time;
+ else
+ time_offset = -(time - clock->last_time);
+
+ clock->time_offset = time_offset;
+
+ GST_DEBUG_OBJECT (clock,
+ "reset clock to %" GST_TIME_FORMAT ", last %" GST_TIME_FORMAT
+ ", offset %" GST_STIME_FORMAT, GST_TIME_ARGS (time),
+ GST_TIME_ARGS (clock->last_time), GST_STIME_ARGS (time_offset));
+}