Update theme submodule
[platform/upstream/gstreamer.git] / tutorials / basic-tutorial-6.c
1 #include <gst/gst.h>\r
2   \r
3 /* Functions below print the Capabilities in a human-friendly format */\r
4 static gboolean print_field (GQuark field, const GValue * value, gpointer pfx) {\r
5   gchar *str = gst_value_serialize (value);\r
6   \r
7   g_print ("%s  %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);\r
8   g_free (str);\r
9   return TRUE;\r
10 }\r
11   \r
12 static void print_caps (const GstCaps * caps, const gchar * pfx) {\r
13   guint i;\r
14   \r
15   g_return_if_fail (caps != NULL);\r
16   \r
17   if (gst_caps_is_any (caps)) {\r
18     g_print ("%sANY\n", pfx);\r
19     return;\r
20   }\r
21   if (gst_caps_is_empty (caps)) {\r
22     g_print ("%sEMPTY\n", pfx);\r
23     return;\r
24   }\r
25   \r
26   for (i = 0; i < gst_caps_get_size (caps); i++) {\r
27     GstStructure *structure = gst_caps_get_structure (caps, i);\r
28     \r
29     g_print ("%s%s\n", pfx, gst_structure_get_name (structure));\r
30     gst_structure_foreach (structure, print_field, (gpointer) pfx);\r
31   }\r
32 }\r
33   \r
34 /* Prints information about a Pad Template, including its Capabilities */\r
35 static void print_pad_templates_information (GstElementFactory * factory) {\r
36   const GList *pads;\r
37   GstStaticPadTemplate *padtemplate;\r
38   \r
39   g_print ("Pad Templates for %s:\n", gst_element_factory_get_longname (factory));\r
40   if (!gst_element_factory_get_num_pad_templates (factory)) {\r
41     g_print ("  none\n");\r
42     return;\r
43   }\r
44   \r
45   pads = gst_element_factory_get_static_pad_templates (factory);\r
46   while (pads) {\r
47     padtemplate = pads->data;\r
48     pads = g_list_next (pads);\r
49     \r
50     if (padtemplate->direction == GST_PAD_SRC)\r
51       g_print ("  SRC template: '%s'\n", padtemplate->name_template);\r
52     else if (padtemplate->direction == GST_PAD_SINK)\r
53       g_print ("  SINK template: '%s'\n", padtemplate->name_template);\r
54     else\r
55       g_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);\r
56     \r
57     if (padtemplate->presence == GST_PAD_ALWAYS)\r
58       g_print ("    Availability: Always\n");\r
59     else if (padtemplate->presence == GST_PAD_SOMETIMES)\r
60       g_print ("    Availability: Sometimes\n");\r
61     else if (padtemplate->presence == GST_PAD_REQUEST) {\r
62       g_print ("    Availability: On request\n");\r
63     } else\r
64       g_print ("    Availability: UNKNOWN!!!\n");\r
65     \r
66     if (padtemplate->static_caps.string) {\r
67       GstCaps *caps;\r
68 \r
69       g_print ("    Capabilities:\n");\r
70       caps = gst_static_caps_get (&padtemplate->static_caps);\r
71       print_caps (caps, "      ");\r
72       gst_caps_unref (caps);\r
73     }\r
74     \r
75     g_print ("\n");\r
76   }\r
77 }\r
78   \r
79 /* Shows the CURRENT capabilities of the requested pad in the given element */\r
80 static void print_pad_capabilities (GstElement *element, gchar *pad_name) {\r
81   GstPad *pad = NULL;\r
82   GstCaps *caps = NULL;\r
83   \r
84   /* Retrieve pad */\r
85   pad = gst_element_get_static_pad (element, pad_name);\r
86   if (!pad) {\r
87     g_printerr ("Could not retrieve pad '%s'\n", pad_name);\r
88     return;\r
89   }\r
90   \r
91   /* Retrieve negotiated caps (or acceptable caps if negotiation is not finished yet) */\r
92   caps = gst_pad_get_current_caps (pad);\r
93   if (!caps)\r
94     caps = gst_pad_query_caps (pad, NULL);\r
95   \r
96   /* Print and free */\r
97   g_print ("Caps for the %s pad:\n", pad_name);\r
98   print_caps (caps, "      ");\r
99   gst_caps_unref (caps);\r
100   gst_object_unref (pad);\r
101 }\r
102   \r
103 int main(int argc, char *argv[]) {\r
104   GstElement *pipeline, *source, *sink;\r
105   GstElementFactory *source_factory, *sink_factory;\r
106   GstBus *bus;\r
107   GstMessage *msg;\r
108   GstStateChangeReturn ret;\r
109   gboolean terminate = FALSE;\r
110   \r
111   /* Initialize GStreamer */\r
112   gst_init (&argc, &argv);\r
113    \r
114   /* Create the element factories */\r
115   source_factory = gst_element_factory_find ("audiotestsrc");\r
116   sink_factory = gst_element_factory_find ("autoaudiosink");\r
117   if (!source_factory || !sink_factory) {\r
118     g_printerr ("Not all element factories could be created.\n");\r
119     return -1;\r
120   }\r
121   \r
122   /* Print information about the pad templates of these factories */\r
123   print_pad_templates_information (source_factory);\r
124   print_pad_templates_information (sink_factory);\r
125   \r
126   /* Ask the factories to instantiate actual elements */\r
127   source = gst_element_factory_create (source_factory, "source");\r
128   sink = gst_element_factory_create (sink_factory, "sink");\r
129   \r
130   /* Create the empty pipeline */\r
131   pipeline = gst_pipeline_new ("test-pipeline");\r
132   \r
133   if (!pipeline || !source || !sink) {\r
134     g_printerr ("Not all elements could be created.\n");\r
135     return -1;\r
136   }\r
137   \r
138   /* Build the pipeline */\r
139   gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);\r
140   if (gst_element_link (source, sink) != TRUE) {\r
141     g_printerr ("Elements could not be linked.\n");\r
142     gst_object_unref (pipeline);\r
143     return -1;\r
144   }\r
145   \r
146   /* Print initial negotiated caps (in NULL state) */\r
147   g_print ("In NULL state:\n");\r
148   print_pad_capabilities (sink, "sink");\r
149   \r
150   /* Start playing */\r
151   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);\r
152   if (ret == GST_STATE_CHANGE_FAILURE) {\r
153     g_printerr ("Unable to set the pipeline to the playing state (check the bus for error messages).\n");\r
154   }\r
155   \r
156   /* Wait until error, EOS or State Change */\r
157   bus = gst_element_get_bus (pipeline);\r
158   do {\r
159     msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS |\r
160         GST_MESSAGE_STATE_CHANGED);\r
161   \r
162     /* Parse message */\r
163     if (msg != NULL) {\r
164       GError *err;\r
165       gchar *debug_info;\r
166     \r
167       switch (GST_MESSAGE_TYPE (msg)) {\r
168         case GST_MESSAGE_ERROR:\r
169           gst_message_parse_error (msg, &err, &debug_info);\r
170           g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);\r
171           g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");\r
172           g_clear_error (&err);\r
173           g_free (debug_info);\r
174           terminate = TRUE;\r
175           break;\r
176         case GST_MESSAGE_EOS:\r
177           g_print ("End-Of-Stream reached.\n");\r
178           terminate = TRUE;\r
179           break;\r
180         case GST_MESSAGE_STATE_CHANGED:\r
181           /* We are only interested in state-changed messages from the pipeline */\r
182           if (GST_MESSAGE_SRC (msg) == GST_OBJECT (pipeline)) {\r
183             GstState old_state, new_state, pending_state;\r
184             gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);\r
185             g_print ("\nPipeline state changed from %s to %s:\n",\r
186                 gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));\r
187             /* Print the current capabilities of the sink element */\r
188             print_pad_capabilities (sink, "sink");\r
189           }\r
190           break;\r
191         default:\r
192           /* We should not reach here because we only asked for ERRORs, EOS and STATE_CHANGED */\r
193           g_printerr ("Unexpected message received.\n");\r
194           break;\r
195       }\r
196       gst_message_unref (msg);\r
197     }\r
198   } while (!terminate);\r
199   \r
200   /* Free resources */\r
201   gst_object_unref (bus);\r
202   gst_element_set_state (pipeline, GST_STATE_NULL);\r
203   gst_object_unref (pipeline);\r
204   gst_object_unref (source_factory);\r
205   gst_object_unref (sink_factory);\r
206   return 0;\r
207 }\r