1 /* GStreamer
2 * Copyright (C) 2015 Sebastian Dröge <sebastian@centricular.com>
3 *
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 /* Create a PTP client clock and print times and statistics.
22 *
23 * When running this from a GStreamer build tree, you will have to set
24 * GST_PTP_HELPER to libs/gst/helpers/.libs/gst-ptp-helper and also
25 * make sure that it has the right permissions (setuid root or appropriate
26 * capabilities
27 *
28 * You can test this with any PTP compatible clock, e.g. ptpd from here: http://ptpd.sourceforge.net/
29 *
30 * For testing the accuracy, you can use the PTP reflector available from
31 * http://code.centricular.com/ptp-clock-reflector/ or here
32 * https://github.com/sdroege/ptp-clock-reflector
33 */
34
35 #include <gst/gst.h>
36 #include <gst/net/net.h>
37
38 static gint domain = 0;
39 static gboolean stats = FALSE;
40
41 static GOptionEntry opt_entries[] = {
42 {"domain", 'd', 0, G_OPTION_ARG_INT, &domain,
43 "PTP domain", NULL},
44 {"stats", 's', 0, G_OPTION_ARG_NONE, &stats,
45 "Print PTP statistics", NULL},
46 {NULL}
47 };
48
49 static gboolean
stats_cb(guint8 d,const GstStructure * stats,gpointer user_data)50 stats_cb (guint8 d, const GstStructure * stats, gpointer user_data)
51 {
52 if (d == domain) {
53 gchar *stats_str = gst_structure_to_string (stats);
54 g_print ("Got stats: %s\n", stats_str);
55 g_free (stats_str);
56 }
57
58 return TRUE;
59 }
60
61 gint
main(gint argc,gchar ** argv)62 main (gint argc, gchar ** argv)
63 {
64 GOptionContext *opt_ctx;
65 GstClock *clock;
66 GError *err = NULL;
67
68 opt_ctx = g_option_context_new ("- GStreamer PTP clock test app");
69 g_option_context_add_main_entries (opt_ctx, opt_entries, NULL);
70 g_option_context_add_group (opt_ctx, gst_init_get_option_group ());
71 if (!g_option_context_parse (opt_ctx, &argc, &argv, &err))
72 g_error ("Error parsing options: %s", err->message);
73 g_clear_error (&err);
74 g_option_context_free (opt_ctx);
75
76 if (!gst_ptp_init (GST_PTP_CLOCK_ID_NONE, NULL))
77 g_error ("failed to init ptp");
78
79 if (stats)
80 gst_ptp_statistics_callback_add (stats_cb, NULL, NULL);
81
82 clock = gst_ptp_clock_new ("test-clock", domain);
83
84 gst_clock_wait_for_sync (GST_CLOCK (clock), GST_CLOCK_TIME_NONE);
85
86 while (TRUE) {
87 GstClockTime local, remote;
88 GstClockTimeDiff diff;
89
90 local = g_get_real_time () * 1000;
91 remote = gst_clock_get_time (clock);
92 diff = GST_CLOCK_DIFF (local, remote);
93
94 g_print ("local: %" GST_TIME_FORMAT " ptp: %" GST_TIME_FORMAT " diff: %s%"
95 GST_TIME_FORMAT "\n", GST_TIME_ARGS (local), GST_TIME_ARGS (remote),
96 (diff < 0 ? "-" : " "), GST_TIME_ARGS (ABS (diff)));
97 g_usleep (100000);
98 }
99
100 return 0;
101 }
102