benchmark: add commandline parameters for capsnego
[platform/upstream/gstreamer.git] / tests / benchmarks / capsnego.c
1 /* GStreamer
2  * Copyright (C) 2010 Stefan Kost <ensonic@users.sf.net>
3  *
4  * capsnego.c: benchmark for caps negotiation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /* this benchmark recursively builds a pipeline and meassures the time to go
23  * from ready to paused.
24  * The graph size and type can be controlled with a few commandline args:
25  *  -d depth: is the depth of the tree
26  *  -c children: is the number of branches on each level
27  *  -f <flavour>: can be a=udio/v=ideo and is conttrolling the kind of elements
28  *                that are used.
29  */
30
31 #include <gst/gst.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 enum
36 {
37   FLAVOUR_AUDIO = 0,
38   FLAVOUR_VIDEO,
39   NUM_FLAVOURS
40 };
41
42 enum
43 {
44   ELEM_SRC = 0,
45   ELEM_MIX,
46   ELEM_PROC,
47   ELEM_CONV,
48   NUM_ELEM
49 };
50
51 static const gchar *factories[NUM_FLAVOURS][NUM_ELEM] = {
52   {"audiotestsrc", "adder", "volume", "audioconvert"},
53   {"videotestsrc", "videomixer", "videoscale", "ffmpegcolorspace"}
54 };
55
56
57 static gboolean
58 create_node (GstBin * bin, GstElement * sink, GstElement ** new_sink,
59     gint children, gint flavour)
60 {
61   GstElement *mix, *proc, *conv;
62
63   if (children >= 1) {
64     mix = gst_element_factory_make (factories[flavour][ELEM_MIX], NULL);
65     if (!mix) {
66       GST_WARNING ("need element '%s'", factories[flavour][ELEM_MIX]);
67       return FALSE;
68     }
69   } else {
70     mix = gst_element_factory_make ("identity", NULL);
71   }
72   proc = gst_element_factory_make (factories[flavour][ELEM_PROC], NULL);
73   if (!proc) {
74     GST_WARNING ("need element '%s'", factories[flavour][ELEM_PROC]);
75     return FALSE;
76   }
77   conv = gst_element_factory_make (factories[flavour][ELEM_CONV], NULL);
78   if (!conv) {
79     GST_WARNING ("need element '%s'", factories[flavour][ELEM_CONV]);
80     return FALSE;
81   }
82   gst_bin_add_many (bin, mix, proc, conv, NULL);
83   if (!gst_element_link_many (mix, proc, conv, sink, NULL)) {
84     GST_WARNING ("can't link elements");
85     return FALSE;
86   }
87   *new_sink = mix;
88   return TRUE;
89 }
90
91 static gboolean
92 create_nodes (GstBin * bin, GstElement * sink, gint depth, gint children,
93     gint flavour)
94 {
95   GstElement *new_sink, *src;
96   gint i;
97
98   for (i = 0; i < children; i++) {
99     if (depth > 0) {
100       if (!create_node (bin, sink, &new_sink, children, flavour)) {
101         return FALSE;
102       }
103       if (!create_nodes (bin, new_sink, depth - 1, children, flavour)) {
104         return FALSE;
105       }
106     } else {
107       src = gst_element_factory_make (factories[flavour][ELEM_SRC], NULL);
108       if (!src) {
109         GST_WARNING ("need element '%s'", factories[flavour][ELEM_SRC]);
110         return FALSE;
111       }
112       gst_bin_add (bin, src);
113       if (!gst_element_link (src, sink)) {
114         GST_WARNING ("can't link elements");
115         return FALSE;
116       }
117     }
118   }
119   return TRUE;
120 }
121
122 static void
123 event_loop (GstElement * bin)
124 {
125   GstBus *bus;
126   GstMessage *msg = NULL;
127   gboolean running = TRUE;
128
129   bus = gst_element_get_bus (bin);
130
131   while (running) {
132     msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
133
134     if (GST_MESSAGE_SRC (msg) == (GstObject *) bin) {
135       GstState old_state, new_state;
136
137       gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
138       if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) {
139         running = FALSE;
140       }
141     }
142     gst_message_unref (msg);
143   }
144 }
145
146
147 gint
148 main (gint argc, gchar * argv[])
149 {
150   GstBin *bin;
151   GstClockTime start, end;
152   GstElement *sink, *new_sink;
153
154   /* default parameters */
155   gint depth = 4;
156   gint children = 3;
157   gint flavour = FLAVOUR_AUDIO;
158   const gchar *flavour_str = "audio";
159
160   gst_init (&argc, &argv);
161
162   /* check command line options */
163   if (argc) {
164     gint arg;
165     for (arg = 0; arg < argc; arg++) {
166       if (!strcmp (argv[arg], "-d")) {
167         arg++;
168         if (arg < argc)
169           depth = atoi (argv[arg]);
170       } else if (!strcmp (argv[arg], "-c")) {
171         arg++;
172         if (arg < argc)
173           children = atoi (argv[arg]);
174       } else if (!strcmp (argv[arg], "-f")) {
175         arg++;
176         if (arg < argc) {
177           flavour_str = argv[arg];
178           switch (*flavour_str) {
179             case 'a':
180               flavour = FLAVOUR_AUDIO;
181               break;
182             case 'v':
183               flavour = FLAVOUR_VIDEO;
184               break;
185             default:
186               break;
187           }
188         }
189       }
190     }
191   }
192
193   /* build pipeline */
194   bin = GST_BIN (gst_pipeline_new ("pipeline"));
195
196   g_print ("building %s pipeline with depth = %d and children = %d\n",
197       flavour_str, depth, children);
198   sink = gst_element_factory_make ("fakesink", NULL);
199   gst_bin_add (bin, sink);
200   if (!create_node (bin, sink, &new_sink, children, flavour)) {
201     goto Error;
202   }
203   if (!create_nodes (bin, new_sink, depth, children, flavour)) {
204     goto Error;
205   }
206   g_print ("built pipeline with %d elements\n", GST_BIN_NUMCHILDREN (bin));
207
208   /* meassure */
209   g_print ("starting pipeline\n");
210   gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
211   GST_DEBUG_BIN_TO_DOT_FILE (bin, GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE, "capsnego");
212   start = gst_util_get_timestamp ();
213   gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
214   event_loop (GST_ELEMENT (bin));
215   end = gst_util_get_timestamp ();
216   g_print ("%" GST_TIME_FORMAT " reached paused\n",
217       GST_TIME_ARGS (end - start));
218
219   /* clean up */
220 Error:
221   gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
222   gst_object_unref (bin);
223   return 0;
224 }