1 /* Copyright (C) <2018, 2019> Philippe Normand <philn@igalia.com>
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18
19 #include <gst/gst.h>
20
21 static GMainLoop *loop;
22 static GstElement *pipe1;
23 static GstBus *bus1;
24
25 static gboolean
_bus_watch(GstBus * bus,GstMessage * msg,GstElement * pipe)26 _bus_watch (GstBus * bus, GstMessage * msg, GstElement * pipe)
27 {
28 switch (GST_MESSAGE_TYPE (msg)) {
29 case GST_MESSAGE_STATE_CHANGED:
30 if (GST_ELEMENT (msg->src) == pipe) {
31 GstState old, new, pending;
32
33 gst_message_parse_state_changed (msg, &old, &new, &pending);
34
35 {
36 gchar *dump_name = g_strconcat ("state_changed-",
37 gst_element_state_get_name (old), "_",
38 gst_element_state_get_name (new), NULL);
39 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (msg->src),
40 GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
41 g_free (dump_name);
42 }
43 }
44 break;
45 case GST_MESSAGE_ERROR:{
46 GError *err = NULL;
47 gchar *dbg_info = NULL;
48
49 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipe),
50 GST_DEBUG_GRAPH_SHOW_ALL, "error");
51
52 gst_message_parse_error (msg, &err, &dbg_info);
53 g_printerr ("ERROR from element %s: %s\n",
54 GST_OBJECT_NAME (msg->src), err->message);
55 g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
56 g_error_free (err);
57 g_free (dbg_info);
58 g_main_loop_quit (loop);
59 break;
60 }
61 case GST_MESSAGE_EOS:{
62 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipe),
63 GST_DEBUG_GRAPH_SHOW_ALL, "eos");
64 g_print ("EOS received\n");
65 g_main_loop_quit (loop);
66 break;
67 }
68 default:
69 break;
70 }
71
72 return TRUE;
73 }
74
75 static void
_wpe_pad_added(GstElement * src,GstPad * new_pad,GstElement * pipe)76 _wpe_pad_added (GstElement * src, GstPad * new_pad, GstElement * pipe)
77 {
78 GstElement *out;
79 GstPad *sink;
80 gchar *name = gst_pad_get_name (new_pad);
81 gchar *bin_name;
82
83 out = gst_parse_bin_from_description
84 ("audioresample ! audioconvert ! autoaudiosink", TRUE, NULL);
85 bin_name = g_strdup_printf ("%s-bin", name);
86 g_free (name);
87
88 gst_object_set_name (GST_OBJECT_CAST (out), bin_name);
89 g_free (bin_name);
90
91 gst_bin_add (GST_BIN (pipe), out);
92 sink = out->sinkpads->data;
93 gst_pad_link (new_pad, sink);
94 gst_element_sync_state_with_parent (out);
95 }
96
97 static void
_wpe_pad_removed(GstElement * src,GstPad * pad,GstElement * pipe)98 _wpe_pad_removed (GstElement * src, GstPad * pad, GstElement * pipe)
99 {
100 gchar *name = gst_pad_get_name (pad);
101 gchar *bin_name = g_strdup_printf ("%s-bin", name);
102 GstElement *bin = gst_bin_get_by_name (GST_BIN_CAST (pipe), bin_name);
103
104 if (GST_IS_ELEMENT (bin)) {
105 gst_bin_remove (GST_BIN_CAST (pipe), bin);
106 gst_element_set_state (bin, GST_STATE_NULL);
107 }
108 g_free (name);
109 g_free (bin_name);
110 }
111
112 int
main(int argc,char * argv[])113 main (int argc, char *argv[])
114 {
115 GstElement *src;
116
117 if (argc < 2) {
118 g_printerr ("Usage: %s <website url>\n", argv[0]);
119 return 1;
120 }
121
122 gst_init (&argc, &argv);
123
124 loop = g_main_loop_new (NULL, FALSE);
125 pipe1 =
126 gst_parse_launch
127 ("wpesrc name=wpesrc ! queue ! glcolorconvert ! gtkglsink enable-last-sample=0",
128 NULL);
129 bus1 = gst_pipeline_get_bus (GST_PIPELINE (pipe1));
130 gst_bus_add_watch (bus1, (GstBusFunc) _bus_watch, pipe1);
131
132 src = gst_bin_get_by_name (GST_BIN (pipe1), "wpesrc");
133
134 gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_READY);
135
136 g_signal_connect (src, "pad-added", G_CALLBACK (_wpe_pad_added), pipe1);
137 g_signal_connect (src, "pad-removed", G_CALLBACK (_wpe_pad_removed), pipe1);
138
139 g_object_set (src, "location", argv[1], NULL);
140 gst_clear_object (&src);
141
142 g_print ("Starting pipeline\n");
143 gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_PLAYING);
144
145 g_main_loop_run (loop);
146
147 gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_NULL);
148 g_print ("Pipeline stopped\n");
149
150 gst_bus_remove_watch (bus1);
151 gst_object_unref (bus1);
152 gst_object_unref (pipe1);
153
154 gst_deinit ();
155
156 return 0;
157 }
158