wpe: Implement audio support
[platform/upstream/gstreamer.git] / tests / examples / wpe / wpe.c
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
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
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   if (g_str_has_prefix (name, "audio")) {
84     out =
85         gst_parse_bin_from_description
86         ("audioresample ! audioconvert ! autoaudiosink", TRUE, NULL);
87   } else {
88     out =
89         gst_parse_bin_from_description
90         ("queue ! glcolorconvert ! gtkglsink enable-last-sample=0", TRUE, NULL);
91   }
92
93   bin_name = g_strdup_printf ("%s-bin", name);
94   g_free (name);
95
96   gst_object_set_name (GST_OBJECT_CAST (out), bin_name);
97   g_free (bin_name);
98
99   gst_bin_add (GST_BIN (pipe), out);
100   sink = out->sinkpads->data;
101   gst_pad_link (new_pad, sink);
102   gst_element_sync_state_with_parent (out);
103 }
104
105 static void
106 _wpe_pad_removed (GstElement * src, GstPad * pad, GstElement * pipe)
107 {
108   gchar *name = gst_pad_get_name (pad);
109   gchar *bin_name = g_strdup_printf ("%s-bin", name);
110   GstElement *bin = gst_bin_get_by_name (GST_BIN_CAST (pipe), bin_name);
111
112   if (GST_IS_ELEMENT (bin)) {
113     gst_bin_remove (GST_BIN_CAST (pipe), bin);
114     gst_element_set_state (bin, GST_STATE_NULL);
115   }
116   g_free (name);
117   g_free (bin_name);
118 }
119
120 int
121 main (int argc, char *argv[])
122 {
123   GstElement *src;
124
125   if (argc < 2) {
126     g_printerr ("Usage: %s <website url>\n", argv[0]);
127     return 1;
128   }
129
130   gst_init (&argc, &argv);
131
132   loop = g_main_loop_new (NULL, FALSE);
133   pipe1 = gst_pipeline_new (NULL);
134   bus1 = gst_pipeline_get_bus (GST_PIPELINE (pipe1));
135   gst_bus_add_watch (bus1, (GstBusFunc) _bus_watch, pipe1);
136
137   src = gst_element_factory_make ("wpesrc", NULL);
138
139   gst_bin_add (GST_BIN_CAST (pipe1), src);
140   gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_READY);
141
142   g_signal_connect (src, "pad-added", G_CALLBACK (_wpe_pad_added), pipe1);
143   g_signal_connect (src, "pad-removed", G_CALLBACK (_wpe_pad_removed), pipe1);
144
145   g_object_set (src, "location", argv[1], NULL);
146
147   g_print ("Starting pipeline\n");
148   gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_PLAYING);
149
150   g_main_loop_run (loop);
151
152   gst_element_set_state (GST_ELEMENT (pipe1), GST_STATE_NULL);
153   g_print ("Pipeline stopped\n");
154
155   gst_bus_remove_watch (bus1);
156   gst_object_unref (bus1);
157   gst_object_unref (pipe1);
158
159   gst_deinit ();
160
161   return 0;
162 }