0715a51943c8ceb43e013a2c9b1c4d8fe86ad5b0
[platform/upstream/gstreamer.git] / gst-sdk / 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 (!factory->numpadtemplates) {\r
41     g_print ("  none\n");\r
42     return;\r
43   }\r
44   \r
45   pads = factory->staticpadtemplates;\r
46   while (pads) {\r
47     padtemplate = (GstStaticPadTemplate *) (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       g_print ("    Capabilities:\n");\r
68       print_caps (gst_static_caps_get (&padtemplate->static_caps), "      ");\r
69     }\r
70     \r
71     g_print ("\n");\r
72   }\r
73 }\r
74   \r
75 /* Shows the CURRENT capabilities of the requested pad in the given element */\r
76 static void print_pad_capabilities (GstElement *element, gchar *pad_name) {\r
77   GstPad *pad = NULL;\r
78   GstCaps *caps = NULL;\r
79   \r
80   /* Retrieve pad */\r
81   pad = gst_element_get_static_pad (element, pad_name);\r
82   if (!pad) {\r
83     g_printerr ("Could not retrieve pad '%s'\n", pad_name);\r
84     return;\r
85   }\r
86   \r
87   /* Retrieve negotiated caps (or acceptable caps if negotiation is not finished yet) */\r
88   caps = gst_pad_get_negotiated_caps (pad);\r
89   if (!caps)\r
90     caps = gst_pad_get_caps_reffed (pad);\r
91   \r
92   /* Print and free */\r
93   g_print ("Caps for the %s pad:\n", pad_name);\r
94   print_caps (caps, "      ");\r
95   gst_caps_unref (caps);\r
96   gst_object_unref (pad);\r
97 }\r
98   \r
99 int main(int argc, char *argv[]) {\r
100   GstElement *pipeline, *source, *sink;\r
101   GstElementFactory *source_factory, *sink_factory;\r
102   GstBus *bus;\r
103   GstMessage *msg;\r
104   GstStateChangeReturn ret;\r
105   gboolean terminate = FALSE;\r
106   \r
107   /* Initialize GStreamer */\r
108   gst_init (&argc, &argv);\r
109    \r
110   /* Create the element factories */\r
111   source_factory = gst_element_factory_find ("audiotestsrc");\r
112   sink_factory = gst_element_factory_find ("autoaudiosink");\r
113   if (!source_factory || !sink_factory) {\r
114     g_printerr ("Not all element factories could be created.\n");\r
115     return -1;\r
116   }\r
117   \r
118   /* Print information about the pad templates of these factories */\r
119   print_pad_templates_information (source_factory);\r
120   print_pad_templates_information (sink_factory);\r
121   \r
122   /* Ask the factories to instantiate actual elements */\r
123   source = gst_element_factory_create (source_factory, "source");\r
124   sink = gst_element_factory_create (sink_factory, "sink");\r
125   \r
126   /* Create the empty pipeline */\r
127   pipeline = gst_pipeline_new ("test-pipeline");\r
128   \r
129   if (!pipeline || !source || !sink) {\r
130     g_printerr ("Not all elements could be created.\n");\r
131     return -1;\r
132   }\r
133   \r
134   /* Build the pipeline */\r
135   gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);\r
136   if (gst_element_link (source, sink) != TRUE) {\r
137     g_printerr ("Elements could not be linked.\n");\r
138     gst_object_unref (pipeline);\r
139     return -1;\r
140   }\r
141   \r
142   /* Print initial negotiated caps (in NULL state) */\r
143   g_print ("In NULL state:\n");\r
144   print_pad_capabilities (sink, "sink");\r
145   \r
146   /* Start playing */\r
147   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);\r
148   if (ret == GST_STATE_CHANGE_FAILURE) {\r
149     g_printerr ("Unable to set the pipeline to the playing state (check the bus for error messages).\n");\r
150   }\r
151   \r
152   /* Wait until error, EOS or State Change */\r
153   bus = gst_element_get_bus (pipeline);\r
154   do {\r
155     msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS |\r
156         GST_MESSAGE_STATE_CHANGED);\r
157   \r
158     /* Parse message */\r
159     if (msg != NULL) {\r
160       GError *err;\r
161       gchar *debug_info;\r
162     \r
163       switch (GST_MESSAGE_TYPE (msg)) {\r
164         case GST_MESSAGE_ERROR:\r
165           gst_message_parse_error (msg, &err, &debug_info);\r
166           g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);\r
167           g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");\r
168           g_clear_error (&err);\r
169           g_free (debug_info);\r
170           terminate = TRUE;\r
171           break;\r
172         case GST_MESSAGE_EOS:\r
173           g_print ("End-Of-Stream reached.\n");\r
174           terminate = TRUE;\r
175           break;\r
176         case GST_MESSAGE_STATE_CHANGED:\r
177           /* We are only interested in state-changed messages from the pipeline */\r
178           if (GST_MESSAGE_SRC (msg) == GST_OBJECT (pipeline)) {\r
179             GstState old_state, new_state, pending_state;\r
180             gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);\r
181             g_print ("\nPipeline state changed from %s to %s:\n",\r
182                 gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));\r
183             /* Print the current capabilities of the sink element */\r
184             print_pad_capabilities (sink, "sink");\r
185           }\r
186           break;\r
187         default:\r
188           /* We should not reach here because we only asked for ERRORs, EOS and STATE_CHANGED */\r
189           g_printerr ("Unexpected message received.\n");\r
190           break;\r
191       }\r
192       gst_message_unref (msg);\r
193     }\r
194   } while (!terminate);\r
195   \r
196   /* Free resources */\r
197   gst_object_unref (bus);\r
198   gst_element_set_state (pipeline, GST_STATE_NULL);\r
199   gst_object_unref (pipeline);\r
200   gst_object_unref (source_factory);\r
201   gst_object_unref (sink_factory);\r
202   return 0;\r
203 }\r