net: GST_EXPORT -> GST_NET_API
[platform/upstream/gstreamer.git] / libs / gst / net / gstptpclock.c
index 4c48908..e1e0955 100644 (file)
@@ -19,6 +19,7 @@
  */
 /**
  * SECTION:gstptpclock
+ * @title: GstPtpClock
  * @short_description: Special clock that synchronizes to a remote time
  *                     provider via PTP (IEEE1588:2008).
  * @see_also: #GstClock, #GstNetClientClock, #GstPipeline
@@ -40,7 +41,6 @@
  * check this, you can use gst_clock_wait_for_sync(), the GstClock::synced
  * signal and gst_clock_is_synced().
  *
- *
  * To gather statistics about the PTP clock synchronization,
  * gst_ptp_statistics_callback_add() can be used. This gives the application
  * the possibility to collect all kinds of statistics from the clock
 #include <sys/wait.h>
 #endif
 #ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #endif
 #include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#elif defined(G_OS_WIN32)
+#include <io.h>
+#endif
 
 #include <gst/base/base.h>
 
@@ -290,8 +296,10 @@ typedef struct
 static void
 ptp_pending_sync_free (PtpPendingSync * sync)
 {
-  if (sync->timeout_source)
+  if (sync->timeout_source) {
     g_source_destroy (sync->timeout_source);
+    g_source_unref (sync->timeout_source);
+  }
   g_free (sync);
 }
 
@@ -849,6 +857,7 @@ handle_announce_message (PtpMessage * msg, GstClockTime receive_time)
     clock_name = g_strdup_printf ("ptp-clock-%u", domain->domain);
     domain->domain_clock =
         g_object_new (GST_TYPE_SYSTEM_CLOCK, "name", clock_name, NULL);
+    gst_object_ref_sink (domain->domain_clock);
     g_free (clock_name);
     g_queue_init (&domain->pending_syncs);
     domain->last_path_delays_missing = 9;
@@ -961,6 +970,7 @@ send_delay_req_timeout (PtpPendingSync * sync)
       sizeof (header), &written, &err);
   if (status == G_IO_STATUS_ERROR) {
     g_warning ("Failed to write to stdout: %s", err->message);
+    g_clear_error (&err);
     return G_SOURCE_REMOVE;
   } else if (status == G_IO_STATUS_EOF) {
     g_message ("EOF on stdout");
@@ -984,6 +994,7 @@ send_delay_req_timeout (PtpPendingSync * sync)
       (const gchar *) delay_req, 44, &written, &err);
   if (status == G_IO_STATUS_ERROR) {
     g_warning ("Failed to write to stdout: %s", err->message);
+    g_clear_error (&err);
     g_main_loop_quit (main_loop);
     return G_SOURCE_REMOVE;
   } else if (status == G_IO_STATUS_EOF) {
@@ -1392,7 +1403,7 @@ update_mean_path_delay (PtpDomainData * domain, PtpPendingSync * sync)
   GST_DEBUG ("Delay request delay for domain %u: %" GST_TIME_FORMAT,
       domain->domain, GST_TIME_ARGS (delay_req_delay));
 
-#ifdef USE_MEASUREMENT_FILTERING
+#if defined(USE_MEASUREMENT_FILTERING) || defined(USE_MEDIAN_PRE_FILTERING)
 out:
 #endif
   if (g_atomic_int_get (&domain_stats_n_hooks)) {
@@ -1437,6 +1448,7 @@ handle_sync_message (PtpMessage * msg, GstClockTime receive_time)
     clock_name = g_strdup_printf ("ptp-clock-%u", domain->domain);
     domain->domain_clock =
         g_object_new (GST_TYPE_SYSTEM_CLOCK, "name", clock_name, NULL);
+    gst_object_ref_sink (domain->domain_clock);
     g_free (clock_name);
     g_queue_init (&domain->pending_syncs);
     domain->last_path_delays_missing = 9;
@@ -1748,6 +1760,7 @@ have_stdin_data_cb (GIOChannel * channel, GIOCondition condition,
       &read, &err);
   if (status == G_IO_STATUS_ERROR) {
     GST_ERROR ("Failed to read from stdin: %s", err->message);
+    g_clear_error (&err);
     g_main_loop_quit (main_loop);
     return G_SOURCE_REMOVE;
   } else if (status == G_IO_STATUS_EOF) {
@@ -1771,6 +1784,7 @@ have_stdin_data_cb (GIOChannel * channel, GIOCondition condition,
   status = g_io_channel_read_chars (channel, buffer, header.size, &read, &err);
   if (status == G_IO_STATUS_ERROR) {
     GST_ERROR ("Failed to read from stdin: %s", err->message);
+    g_clear_error (&err);
     g_main_loop_quit (main_loop);
     return G_SOURCE_REMOVE;
   } else if (status == G_IO_STATUS_EOF) {
@@ -1981,7 +1995,6 @@ gst_ptp_is_initialized (void)
  * If @clock_id is %GST_PTP_CLOCK_ID_NONE, a clock id is automatically
  * generated from the MAC address of the first network interface.
  *
- *
  * This function is automatically called by gst_ptp_clock_new() with default
  * parameters if it wasn't called before.
  *
@@ -2102,6 +2115,7 @@ gst_ptp_init (guint64 clock_id, gchar ** interfaces)
   observation_system_clock =
       g_object_new (GST_TYPE_SYSTEM_CLOCK, "name", "ptp-observation-clock",
       NULL);
+  gst_object_ref_sink (observation_system_clock);
 
   initted = TRUE;
 
@@ -2264,7 +2278,9 @@ enum
 {
   PROP_0,
   PROP_DOMAIN,
-  PROP_INTERNAL_CLOCK
+  PROP_INTERNAL_CLOCK,
+  PROP_MASTER_CLOCK_ID,
+  PROP_GRANDMASTER_CLOCK_ID
 };
 
 #define GST_PTP_CLOCK_GET_PRIVATE(obj)  \
@@ -2314,6 +2330,16 @@ gst_ptp_clock_class_init (GstPtpClockClass * klass)
           "Internal clock", GST_TYPE_CLOCK,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MASTER_CLOCK_ID,
+      g_param_spec_uint64 ("master-clock-id", "Master Clock ID",
+          "Master Clock ID", 0, G_MAXUINT64, 0,
+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_GRANDMASTER_CLOCK_ID,
+      g_param_spec_uint64 ("grandmaster-clock-id", "Grand Master Clock ID",
+          "Grand Master Clock ID", 0, G_MAXUINT64, 0,
+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
   clock_class->get_internal_time = gst_ptp_clock_get_internal_time;
 }
 
@@ -2417,6 +2443,28 @@ gst_ptp_clock_get_property (GObject * object, guint prop_id,
       gst_ptp_clock_ensure_domain_clock (self);
       g_value_set_object (value, self->priv->domain_clock);
       break;
+    case PROP_MASTER_CLOCK_ID:
+    case PROP_GRANDMASTER_CLOCK_ID:{
+      GList *l;
+
+      g_mutex_lock (&domain_clocks_lock);
+      g_value_set_uint64 (value, 0);
+
+      for (l = domain_clocks; l; l = l->next) {
+        PtpDomainData *clock_data = l->data;
+
+        if (clock_data->domain == self->priv->domain) {
+          if (prop_id == PROP_MASTER_CLOCK_ID)
+            g_value_set_uint64 (value,
+                clock_data->master_clock_identity.clock_identity);
+          else
+            g_value_set_uint64 (value, clock_data->grandmaster_identity);
+          break;
+        }
+      }
+      g_mutex_unlock (&domain_clocks_lock);
+      break;
+    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2461,19 +2509,21 @@ gst_ptp_clock_get_internal_time (GstClock * clock)
  * If gst_ptp_init() was not called before, this will call gst_ptp_init() with
  * default parameters.
  *
- *
  * This clock only returns valid timestamps after it received the first
  * times from the PTP master clock on the network. Once this happens the
  * GstPtpClock::internal-clock property will become non-NULL. You can
  * check this with gst_clock_wait_for_sync(), the GstClock::synced signal and
  * gst_clock_is_synced().
  *
+ * Returns: (transfer full): A new #GstClock
+ *
  * Since: 1.6
  */
 GstClock *
 gst_ptp_clock_new (const gchar * name, guint domain)
 {
-  g_return_val_if_fail (name != NULL, NULL);
+  GstClock *clock;
+
   g_return_val_if_fail (domain <= G_MAXUINT8, NULL);
 
   if (!initted && !gst_ptp_init (GST_PTP_CLOCK_ID_NONE, NULL)) {
@@ -2481,8 +2531,13 @@ gst_ptp_clock_new (const gchar * name, guint domain)
     return NULL;
   }
 
-  return g_object_new (GST_TYPE_PTP_CLOCK, "name", name, "domain", domain,
+  clock = g_object_new (GST_TYPE_PTP_CLOCK, "name", name, "domain", domain,
       NULL);
+
+  /* Clear floating flag */
+  gst_object_ref_sink (clock);
+
+  return clock;
 }
 
 typedef struct