2 * Copyright (C) 2016 Centricular Ltd.
3 * Author: Arun Raghavan <arun@centricular.com>
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.
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.
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.
27 /* We need the internal netclock estimation function to (re)run the code on
28 * captured samples, plus its dependencies for the build to succeed. */
29 #include "../../libs/gst/net/gstntppacket.c"
30 #include "../../libs/gst/net/gstnetclientclock.c"
31 #include "../../libs/gst/net/gstnetutils.c"
33 static gchar *input = NULL;
34 static gboolean debug = FALSE;
35 static gint rtt_limit = 0;
37 static GOptionEntry entries[] = {
38 {"input", 'i', 0, G_OPTION_ARG_FILENAME, &input,
39 "Clock reading file containing one local and remote time readings, one "
42 {"rtt-limit", 'r', 0, G_OPTION_ARG_INT64, &rtt_limit,
43 "Round trip time limit on packets (in ms)", "MSEC"},
44 {"debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Verbose debug output", NULL},
49 main (int argc, char *argv[])
51 GstNetClientInternalClock *clock;
56 GOptionContext *context;
60 context = g_option_context_new (NULL);
61 g_option_context_add_main_entries (context, entries, NULL);
62 g_option_context_add_group (context, gst_init_get_option_group ());
64 if (!g_option_context_parse (context, &argc, &argv, &error)) {
65 g_print ("Failed to parse options: %s\n\n", error->message);
71 if (!(channel = g_io_channel_new_file (input, "r", NULL))) {
72 g_print ("Could not read input file: %s\n", input);
76 if (!(channel = g_io_channel_unix_new (0))) {
77 g_print ("Could not read stdin");
82 clock = g_object_new (GST_TYPE_NET_CLIENT_INTERNAL_CLOCK, NULL);
85 /* FIXME: Find a way to do this without touching the structure internals */
87 clock->roundtrip_limit = rtt_limit * GST_MSECOND;
88 clock->busses = g_list_prepend (clock->busses, bus);
90 while ((status = g_io_channel_read_line (channel, &line, NULL, NULL,
91 &error)) == G_IO_STATUS_NORMAL) {
92 GstClockTime local_1, local_2, remote_1, remote_2;
95 if (sscanf (line, "%" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT " %"
96 G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, &local_1, &remote_1,
97 &remote_2, &local_2) != 4) {
98 g_print ("Failed to get local/remote time values from: %s\n", line);
103 g_print ("%s", line);
105 gst_net_client_internal_clock_observe_times (clock, local_1, remote_1,
110 if ((message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT))) {
111 const GstStructure *st;
114 st = gst_message_get_structure (message);
115 str = gst_structure_to_string (st);
117 g_print ("%s\n", str);
120 gst_message_unref (message);
124 if (status == G_IO_CHANNEL_ERROR) {
125 g_print ("Error reading file: %s\n", error->message);
126 g_error_free (error);
130 g_io_channel_unref (channel);
132 gst_object_unref (bus);