--- /dev/null
+From d1d935579a6248dd10a6681f130404519f815276 Mon Sep 17 00:00:00 2001
+From: Maemo Multimedia <multimedia@maemo.org>
+Date: Thu, 22 Jan 2009 09:57:49 +0200
+Subject: [PATCH] Startup benchmarking test
+
+---
+ configure.ac | 1 +
+ tests/benchmarks/Makefile.am | 4 +
+ tests/benchmarks/startup.c | 255 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 260 insertions(+), 0 deletions(-)
+ create mode 100644 tests/benchmarks/Makefile.am
+ create mode 100644 tests/benchmarks/startup.c
+
+diff --git a/configure.ac b/configure.ac
+index 4de8751..a7e72c6 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1003,6 +1003,7 @@ pkgconfig/gstreamer-video-uninstalled.pc
+ pkgconfig/gstreamer-plugins-base.pc
+ pkgconfig/gstreamer-plugins-base-uninstalled.pc
+ tests/Makefile
++tests/benchmarks/Makefile
+ tests/check/Makefile
+ tests/examples/Makefile
+ tests/examples/app/Makefile
+diff --git a/tests/benchmarks/Makefile.am b/tests/benchmarks/Makefile.am
+new file mode 100644
+index 0000000..93a2440
+--- /dev/null
++++ b/tests/benchmarks/Makefile.am
+@@ -0,0 +1,4 @@
++noinst_PROGRAMS = startup
++
++AM_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
++LDADD = $(GST_LIBS)
+diff --git a/tests/benchmarks/startup.c b/tests/benchmarks/startup.c
+new file mode 100644
+index 0000000..4d39f9d
+--- /dev/null
++++ b/tests/benchmarks/startup.c
+@@ -0,0 +1,255 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <gst/gst.h>
++
++GList *sink_list = NULL;
++GMainLoop *loop = NULL;
++GstClockTime generic_start;
++GstClockTime generic_end;
++GstClockTime null_start;
++GstClockTime paused_start;
++GstClockTime playing_end;
++guint profile = 0;
++guint id = 0;
++
++static GstClockTime
++gst_get_current_time (void)
++{
++ GTimeVal tv;
++
++ g_get_current_time (&tv);
++ return GST_TIMEVAL_TO_TIME (tv);
++}
++
++void dbin_dpad_cb (GstElement* e,
++ GstPad* pad,
++ gboolean cont,
++ gpointer user_data)
++{
++ GstElement *pipeline;
++ GstCaps *padcaps;
++ gboolean audio = FALSE;
++
++ pipeline = (GstElement *) user_data;
++
++ padcaps = gst_pad_get_caps (pad);
++
++ if (padcaps) {
++ GstStructure *stru;
++ const gchar *name;
++
++ stru = gst_caps_get_structure ((const GstCaps *) padcaps, 0);
++ name = gst_structure_get_name (stru);
++ if (g_strrstr (name, "audio/x-raw")) {
++ audio = TRUE;
++ }
++ gst_caps_unref (padcaps);
++ }
++
++ if (audio) {
++#if 0
++ GstElement *conv, *resamp, *sink;
++ GstBin *bin;
++ GstPad *spad, *gpad;
++
++ printf ("creating audio bin\n");
++
++ bin = (GstBin *) gst_bin_new ("abin");
++ gst_object_ref (bin);
++ gst_object_sink (bin);
++
++ conv = gst_element_factory_make ("audioconvert", "aconv");
++ resamp = gst_element_factory_make ("audioresample", "aresample");
++ sink = gst_element_factory_make ("autoaudiosink", "audiosink");
++
++ gst_bin_add_many (bin, conv, resamp, sink, NULL);
++ gst_element_link_pads (conv, "src", resamp, "sink");
++ gst_element_link_pads (resamp, "src", sink, "sink");
++
++ gst_bin_add (GST_BIN_CAST (pipeline), GST_ELEMENT_CAST (bin));
++
++ spad = gst_element_get_static_pad (conv, "sink");
++ gpad = gst_ghost_pad_new ("sink", spad);
++ gst_element_add_pad (GST_ELEMENT_CAST (bin), gpad);
++ gst_object_unref (spad);
++
++ gst_pad_link (pad, gpad);
++ sink_list = g_list_append (sink_list, bin);
++#else
++ GstElement *sink;
++ GstPad *spad;
++
++ sink = gst_element_factory_make ("alsasink", "audiosink");
++ gst_bin_add (GST_BIN_CAST (pipeline), sink);
++ gst_element_set_state (sink, GST_STATE_PAUSED);
++ spad = gst_element_get_static_pad (sink, "sink");
++ gst_pad_link (pad, spad);
++ gst_object_unref (spad);
++ sink_list = g_list_append (sink_list, sink);
++#endif
++
++ }
++ else {
++ GstElement *fsink;
++ GstPad *fsinkpad;
++
++ printf ("creating fakesink for non-audio pad\n");
++
++ fsink = gst_element_factory_make ("fakesink", NULL);
++ sink_list = g_list_append (sink_list, fsink);
++ gst_element_set_state (fsink, GST_STATE_PAUSED);
++ gst_bin_add (GST_BIN_CAST (pipeline), fsink);
++ fsinkpad = gst_element_get_static_pad (fsink, "sink");
++ gst_pad_link (pad, fsinkpad);
++ gst_object_unref (fsinkpad);
++ }
++}
++
++
++static gboolean
++metadata_bus_async_cb (GstBus *bus, GstMessage *msg, gpointer data)
++{
++ GError *error = NULL;
++ GstElement *pipeline = (GstElement *) data;
++ gboolean stop = FALSE;
++
++ switch (GST_MESSAGE_TYPE (msg)) {
++ case GST_MESSAGE_ERROR:
++ gst_message_parse_error (msg, &error, NULL);
++ printf ("ERROR: %s\n", error->message);
++ g_error_free (error);
++ stop = TRUE;
++ break;
++ case GST_MESSAGE_EOS:
++ printf (" EOS\n");
++ stop = TRUE;
++ break;
++ case GST_MESSAGE_STATE_CHANGED:
++ {
++ GstElement *sender = (GstElement *) GST_MESSAGE_SRC (msg);
++ if (sender == pipeline) {
++ GstState newstate;
++ gst_message_parse_state_changed (msg, NULL, &newstate, NULL);
++ if (newstate == GST_STATE_PLAYING) {
++ if (profile) {
++ system ("opcontrol --stop");
++ printf ("=== PROFILER STOPPED ===\n");
++ }
++ playing_end = gst_get_current_time ();
++ printf ("Startup time from NULL: %" GST_TIME_FORMAT "\n",
++ GST_TIME_ARGS (playing_end - null_start));
++ printf ("Startup time from PAUSED: %" GST_TIME_FORMAT "\n",
++ GST_TIME_ARGS (playing_end - paused_start));
++ stop = TRUE;
++ }
++ else if (newstate == GST_STATE_PAUSED) {
++ paused_start = gst_get_current_time ();
++ }
++ }
++ }
++ default:
++ break;
++ }
++
++ if (stop) {
++ gst_element_set_state (pipeline, GST_STATE_READY);
++ g_main_loop_quit (loop);
++ }
++
++ return TRUE;
++}
++
++int main(int argc, char **argv)
++{
++ GstElement *pipeline;
++ GstBus *bus;
++ int pipe_type = 0;
++
++ if(argc < 4) {
++ printf ("\nUSAGE: %s <pipeline_type> <profile (0/1)> <URI> [<typefind caps for decodebin2>]\n\n", argv[0]);
++ printf (" Pipeline type: 0: Hardcoded MP3 pipeline\n");
++ printf (" 1: Playbin2\n");
++ printf (" 2: Decodebin2\n\n");
++ exit (1);
++ }
++
++ pipe_type = atoi (argv[1]);
++ profile = atoi (argv[2]);
++
++ printf ("============================================================\n");
++
++ generic_start = gst_get_current_time ();
++ gst_init (&argc, &argv);
++ generic_end = gst_get_current_time ();
++
++ printf ("gst_init() time: %" GST_TIME_FORMAT "\n",
++ GST_TIME_ARGS (generic_end - generic_start));
++
++ if (pipe_type == 0) {
++ GstElement *src, *dec, *sink;
++ pipeline = gst_element_factory_make ("pipeline", NULL);
++ src = gst_element_factory_make ("filesrc", NULL);
++ dec = gst_element_factory_make ("omx_mp3dec", NULL);
++ sink = gst_element_factory_make ("alsasink", NULL);
++ gst_bin_add_many (GST_BIN_CAST (pipeline), src, dec, sink, NULL);
++ gst_element_link_many (src, dec, sink, NULL);
++
++ g_object_set (G_OBJECT (src), "location", argv[3], NULL);
++ g_object_set (G_OBJECT (dec), "use-timestamps", FALSE, NULL);
++ }
++ else if (pipe_type == 1) {
++ pipeline = gst_element_factory_make ("playbin2", NULL);
++ g_object_set (G_OBJECT (pipeline), "uri", argv[3], NULL);
++ g_object_set (G_OBJECT (pipeline), "skip-metadata", TRUE, NULL);
++ }
++ else if (pipe_type == 2) {
++ GstElement *src, *dec;
++ GstCaps *filecaps;
++
++ pipeline = gst_element_factory_make ("pipeline", NULL);
++ src = gst_element_factory_make ("filesrc", NULL);
++ dec = gst_element_factory_make ("decodebin2", NULL);
++ gst_bin_add_many (GST_BIN_CAST (pipeline), src, dec, NULL);
++ gst_element_link_many (src, dec, NULL);
++
++ g_object_set (G_OBJECT (src), "location", argv[3], NULL);
++ g_object_set (G_OBJECT (dec), "skip-metadata", TRUE, NULL);
++
++ if (argc >= 5) {
++ printf ("Setting caps '%s' to skip typefinding!\n", argv[4]);
++ filecaps = gst_caps_from_string (argv[4]);
++ g_object_set (G_OBJECT (dec), "sink-caps", filecaps, NULL);
++ gst_caps_unref (filecaps);
++ }
++
++ id = g_signal_connect (G_OBJECT (dec), "new-decoded-pad",
++ G_CALLBACK (dbin_dpad_cb), pipeline);
++
++ }
++ else {
++ printf ("Unknown pipeline type\n");
++ goto leave;
++ }
++
++ loop = g_main_loop_new (NULL, FALSE);
++ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
++ gst_bus_add_watch (bus, metadata_bus_async_cb, pipeline);
++
++ if (profile) {
++ system ("opcontrol --start");
++ printf ("=== PROFILER RUNNING ===\n");
++ }
++
++ null_start = gst_get_current_time ();
++ gst_element_set_state (pipeline, GST_STATE_PLAYING);
++ g_main_loop_run (loop);
++
++ gst_element_set_state (pipeline, GST_STATE_NULL);
++ gst_object_unref (bus);
++ gst_object_unref (GST_OBJECT (pipeline));
++
++leave:
++ printf ("============================================================\n");
++
++ return 0;
++}