24ad2835dcf139d9d9dfdcf0e0409491bf54ff61
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / tests / icles / output-selector-test.c
1 #include <gst/gst.h>
2
3 #define SWITCH_TIMEOUT 1000
4 #define NUM_VIDEO_BUFFERS 500
5
6 static GMainLoop *loop;
7
8 /* Output selector src pads */
9 static GstPad *osel_src1 = NULL;
10 static GstPad *osel_src2 = NULL;
11
12 static gboolean
13 my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
14 {
15   g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
16
17   switch (GST_MESSAGE_TYPE (message)) {
18     case GST_MESSAGE_ERROR:{
19       GError *err;
20       gchar *debug;
21
22       gst_message_parse_error (message, &err, &debug);
23       g_print ("Error: %s\n", err->message);
24       g_error_free (err);
25       g_free (debug);
26
27       g_main_loop_quit (loop);
28       break;
29     }
30     case GST_MESSAGE_EOS:
31       /* end-of-stream */
32       g_main_loop_quit (loop);
33       break;
34     default:
35       /* unhandled message */
36       break;
37   }
38   /* we want to be notified again the next time there is a message
39    * on the bus, so returning TRUE (FALSE means we want to stop watching
40    * for messages on the bus and our callback should not be called again)
41    */
42   return TRUE;
43 }
44
45 static gboolean
46 switch_cb (gpointer user_data)
47 {
48   GstElement *sel = GST_ELEMENT (user_data);
49   GstPad *old_pad, *new_pad = NULL;
50
51   g_object_get (G_OBJECT (sel), "active-pad", &old_pad, NULL);
52
53   if (old_pad == osel_src1)
54     new_pad = osel_src2;
55   else
56     new_pad = osel_src1;
57
58   g_object_set (G_OBJECT (sel), "active-pad", new_pad, NULL);
59
60   g_print ("switched from %s:%s to %s:%s\n", GST_DEBUG_PAD_NAME (old_pad),
61       GST_DEBUG_PAD_NAME (new_pad));
62
63   gst_object_unref (old_pad);
64
65   return TRUE;
66
67 }
68
69 static void
70 on_bin_element_added (GstBin * bin, GstElement * element, gpointer user_data)
71 {
72   g_object_set (G_OBJECT (element), "sync", FALSE, "async", FALSE, NULL);
73 }
74
75 gint
76 main (gint argc, gchar * argv[])
77 {
78   GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *c1, *c2, *c0;
79   GstPad *sinkpad;
80   GstBus *bus;
81
82   /* init GStreamer */
83   gst_init (&argc, &argv);
84   loop = g_main_loop_new (NULL, FALSE);
85
86   /* create elements */
87   pipeline = gst_element_factory_make ("pipeline", "pipeline");
88   src = gst_element_factory_make ("videotestsrc", "src");
89   c0 = gst_element_factory_make ("ffmpegcolorspace", NULL);
90   toverlay = gst_element_factory_make ("timeoverlay", "timeoverlay");
91   osel = gst_element_factory_make ("output-selector", "osel");
92   c1 = gst_element_factory_make ("ffmpegcolorspace", NULL);
93   c2 = gst_element_factory_make ("ffmpegcolorspace", NULL);
94   sink1 = gst_element_factory_make ("autovideosink", "sink1");
95   sink2 = gst_element_factory_make ("autovideosink", "sink2");
96
97   if (!pipeline || !src || !c0 || !toverlay || !osel || !c1 || !c2 || !sink1 ||
98       !sink2) {
99     g_print ("missing element\n");
100     return -1;
101   }
102
103   /* add them to bin */
104   gst_bin_add_many (GST_BIN (pipeline), src, c0, toverlay, osel, c1, sink1, c2,
105       sink2, NULL);
106
107   /* set properties */
108   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
109   g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL);
110   g_object_set (G_OBJECT (src), "num-buffers", NUM_VIDEO_BUFFERS, NULL);
111   g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL);
112
113   /* handle deferred properties */
114   g_signal_connect (G_OBJECT (sink1), "element-added",
115       G_CALLBACK (on_bin_element_added), NULL);
116   g_signal_connect (G_OBJECT (sink2), "element-added",
117       G_CALLBACK (on_bin_element_added), NULL);
118
119   /* link src ! timeoverlay ! osel */
120   if (!gst_element_link_many (src, c0, toverlay, osel, NULL)) {
121     g_print ("linking failed\n");
122     return -1;
123   }
124
125   /* link output 1 */
126   sinkpad = gst_element_get_static_pad (c1, "sink");
127   osel_src1 = gst_element_get_request_pad (osel, "src%d");
128   if (gst_pad_link (osel_src1, sinkpad) != GST_PAD_LINK_OK) {
129     g_print ("linking output 1 converter failed\n");
130     return -1;
131   }
132   gst_object_unref (sinkpad);
133
134   if (!gst_element_link (c1, sink1)) {
135     g_print ("linking output 1 failed\n");
136     return -1;
137   }
138
139   /* link output 2 */
140   sinkpad = gst_element_get_static_pad (c2, "sink");
141   osel_src2 = gst_element_get_request_pad (osel, "src%d");
142   if (gst_pad_link (osel_src2, sinkpad) != GST_PAD_LINK_OK) {
143     g_print ("linking output 2 converter failed\n");
144     return -1;
145   }
146   gst_object_unref (sinkpad);
147
148   if (!gst_element_link (c2, sink2)) {
149     g_print ("linking output 2 failed\n");
150     return -1;
151   }
152
153   /* add switch callback */
154   g_timeout_add (SWITCH_TIMEOUT, switch_cb, osel);
155
156   /* change to playing */
157   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
158   gst_bus_add_watch (bus, my_bus_callback, loop);
159   gst_object_unref (bus);
160
161   gst_element_set_state (pipeline, GST_STATE_PLAYING);
162
163   /* now run */
164   g_main_loop_run (loop);
165
166   /* also clean up */
167   gst_element_set_state (pipeline, GST_STATE_NULL);
168   gst_element_release_request_pad (osel, osel_src1);
169   gst_element_release_request_pad (osel, osel_src2);
170   gst_object_unref (GST_OBJECT (pipeline));
171
172   return 0;
173 }