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