]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gst-plugin-vpe.git/commitdiff
Adding test application and perf plugin
authorHarinarayan Bhatta <harinarayan@ti.com>
Fri, 2 May 2014 05:57:50 +0000 (11:27 +0530)
committerHarinarayan Bhatta <harinarayan@ti.com>
Fri, 2 May 2014 05:57:50 +0000 (11:27 +0530)
The "gstvpetest" application is useful to test pause/seek and
multiple pipelines from a single process. It also prints out
memory leaks and dmabuf leaks.

The "perf" plugin a simple plugin that displays the framerate
of data passing through it, useful for debugging and used in the
gstvpetest application.

Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
Makefile.am
configure.ac
tests/perf/Makefile.am [new file with mode: 0644]
tests/perf/gstperf.c [new file with mode: 0644]
tests/perf/gstperf.h [new file with mode: 0644]
tests/vpetest/Makefile.am [new file with mode: 0644]
tests/vpetest/gstvpetest.c [new file with mode: 0755]

index 1ea48a2c462df16fd59c97373a8913bb95ec2503..d7de68a35435bc83fa2fe5b08e1782995710355c 100644 (file)
@@ -1,3 +1,3 @@
-SUBDIRS = src
+SUBDIRS = src tests/vpetest tests/perf
 
 EXTRA_DIST = autogen.sh m4 po
index 48e5a11854fff25f6d9272ef2639b92776457bb0..d2480213ba2ead3e9c0b8b9964b4c430c51a8048 100644 (file)
@@ -138,6 +138,6 @@ dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
 GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS"
 AC_SUBST(GST_PLUGIN_LDFLAGS)
 
-AC_CONFIG_FILES([Makefile src/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile tests/vpetest/Makefile tests/perf/Makefile])
 AC_OUTPUT
 
diff --git a/tests/perf/Makefile.am b/tests/perf/Makefile.am
new file mode 100644 (file)
index 0000000..ddfc2a2
--- /dev/null
@@ -0,0 +1,25 @@
+plugin_LTLIBRARIES = libgstperf.la
+
+# headers we need but don't want installed
+noinst_HEADERS = \
+       gstperf.h
+
+# sources used to compile this plug-in
+libgstperf_la_SOURCES = \
+       gstperf.c
+       $(noinst_HEADERS)
+
+# compiler and linker flags used to compile this plugin, set in configure.ac
+libgstperf_la_CFLAGS = \
+       $(GST_CFLAGS)
+
+libgstperf_la_LIBADD = \
+       $(GST_LIBS)
+
+libgstperf_la_LDFLAGS = \
+       $(GST_PLUGIN_LDFLAGS) \
+       $(GST_ALL_LDFLAGS) \
+       --no-undefined
+
+libgstperf_la_LIBTOOLFLAGS = --tag=disable-static
+
diff --git a/tests/perf/gstperf.c b/tests/perf/gstperf.c
new file mode 100644 (file)
index 0000000..fb55373
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2012 Harinarayan Bhatta <<user@hostname.org>>
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-perf
+ *
+ * FIXME:Describe perf here.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch -v -m fakesrc ! perf ! fakesink silent=TRUE
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#include "gstperf.h"
+
+/* the capabilities of the inputs and outputs.
+ *
+ * describe the real formats here.
+ */
+static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+
+static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("ANY")
+    );
+
+GST_BOILERPLATE (GstPerf, gst_perf, GstElement, GST_TYPE_ELEMENT);
+
+static gboolean gst_perf_set_caps (GstPad * pad, GstCaps * caps);
+static GstFlowReturn gst_perf_chain (GstPad * pad, GstBuffer * buf);
+
+#define DEFAULT_INTERVAL  1
+#define PRINT_ARM_LOAD    TRUE
+#define PRINT_FPS         TRUE
+
+
+/* GObject vmethod implementations */
+
+static void
+gst_perf_base_init (gpointer gclass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
+
+  gst_element_class_set_details_simple (element_class,
+      "perf",
+      "Miscellaneous",
+      "Print framerate", "Harinarayan Bhatta <harinarayan@ti.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sink_factory));
+}
+
+
+
+/* initialize the perf's class */
+static void
+gst_perf_class_init (GstPerfClass * klass)
+{
+}
+
+/* initialize the new element
+ * instantiate pads and add them to element
+ * set pad calback functions
+ * initialize instance structure
+ */
+static void
+gst_perf_init (GstPerf * self, GstPerfClass * gclass)
+{
+  self->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
+  gst_pad_set_setcaps_function (self->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_perf_set_caps));
+  gst_pad_set_chain_function (self->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_perf_chain));
+
+  self->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
+
+  gst_pad_set_getcaps_function (self->srcpad,
+      GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
+  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
+  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
+
+  self->fps_update_interval = GST_SECOND * DEFAULT_INTERVAL;
+  self->print_arm_load = PRINT_ARM_LOAD;
+  self->print_fps = PRINT_FPS;
+  self->lastbuf_ts = GST_CLOCK_TIME_NONE;
+
+  /* Init counters */
+  self->frames_count = G_GUINT64_CONSTANT (0);
+  self->total_size = G_GUINT64_CONSTANT (0);
+  self->last_frames_count = G_GUINT64_CONSTANT (0);
+
+  /* init time stamps */
+  self->last_ts = self->start_ts = self->interval_ts = GST_CLOCK_TIME_NONE;
+
+}
+
+/* GstElement vmethod implementations */
+
+/* this function handles the link with other elements */
+static gboolean
+gst_perf_set_caps (GstPad * pad, GstCaps * caps)
+{
+  GstPerf *self;
+  GstPad *otherpad;
+
+  self = GST_PERF (gst_pad_get_parent (pad));
+  otherpad = (pad == self->srcpad) ? self->sinkpad : self->srcpad;
+  gst_object_unref (self);
+
+  return gst_pad_set_caps (otherpad, caps);
+}
+
+static gboolean
+display_current_fps (gpointer data)
+{
+  GstPerf *self = GST_PERF (data);
+  guint64 frames_count;
+  gdouble rr, average_fps, average_bitrate;
+  gchar fps_message[256];
+  gdouble time_diff, time_elapsed;
+  GstClockTime current_ts = gst_util_get_timestamp ();
+  char *name = GST_OBJECT_NAME (self);
+
+  frames_count = self->frames_count;
+
+  time_diff = (gdouble) (current_ts - self->last_ts) / GST_SECOND;
+  time_elapsed = (gdouble) (current_ts - self->start_ts) / GST_SECOND;
+
+  rr = (gdouble) (frames_count - self->last_frames_count) / time_diff;
+
+  average_fps = (gdouble) frames_count / time_elapsed;
+  average_bitrate = ((gdouble) self->total_size * 8.0) / (time_diff * 1000);
+
+  g_snprintf (fps_message, 255,
+      "%" GST_TIME_FORMAT " %s: frames: %" G_GUINT64_FORMAT
+      " \tcurrent: %.2f \t average: %.2f \tbitrate: %.2f \tts: %"
+      GST_TIME_FORMAT, GST_TIME_ARGS (current_ts), name, frames_count, rr,
+      average_fps, average_bitrate, GST_TIME_ARGS (self->lastbuf_ts));
+  g_print ("%s", fps_message);
+
+  self->total_size = G_GUINT64_CONSTANT (0);
+  self->last_frames_count = frames_count;
+  self->last_ts = current_ts;
+  self->lastbuf_ts = GST_CLOCK_TIME_NONE;
+
+  return TRUE;
+}
+
+
+static int
+print_cpu_load (GstPerf * perf)
+{
+  int cpuLoadFound = FALSE;
+  unsigned long nice, sys, idle, iowait, irq, softirq, steal;
+  unsigned long deltaTotal;
+  char textBuf[4];
+  FILE *fptr;
+  int load;
+
+  /* Read the overall system information */
+  fptr = fopen ("/proc/stat", "r");
+
+  if (fptr == NULL) {
+    return -1;
+  }
+
+  perf->prevTotal = perf->total;
+  perf->prevuserTime = perf->userTime;
+
+  /* Scan the file line by line */
+  while (fscanf (fptr, "%4s %lu %lu %lu %lu %lu %lu %lu %lu", textBuf,
+          &perf->userTime, &nice, &sys, &idle, &iowait, &irq, &softirq,
+          &steal) != EOF) {
+    if (strcmp (textBuf, "cpu") == 0) {
+      cpuLoadFound = TRUE;
+      break;
+    }
+  }
+
+  if (fclose (fptr) != 0) {
+    return -1;
+  }
+
+  if (!cpuLoadFound) {
+    return -1;
+  }
+
+  perf->total = perf->userTime + nice + sys + idle + iowait + irq + softirq +
+      steal;
+  perf->userTime += nice + sys + iowait + irq + softirq + steal;
+  deltaTotal = perf->total - perf->prevTotal;
+
+  if (deltaTotal) {
+    load = 100 * (perf->userTime - perf->prevuserTime) / deltaTotal;
+  } else {
+    load = 0;
+  }
+
+  g_print ("\tarm-load: %d", load);
+  return 0;
+}
+
+/* chain function
+ * this function does the actual processing
+ */
+static GstFlowReturn
+gst_perf_chain (GstPad * pad, GstBuffer * buf)
+{
+  GstClockTime ts;
+  GstPerf *self = GST_PERF (GST_PAD_PARENT (pad));
+
+  self->frames_count++;
+  self->total_size += GST_BUFFER_SIZE (buf);
+
+  if (self->lastbuf_ts == GST_CLOCK_TIME_NONE)
+    self->lastbuf_ts = GST_BUFFER_TIMESTAMP (buf);
+
+  ts = gst_util_get_timestamp ();
+  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (self->start_ts))) {
+    self->interval_ts = self->last_ts = self->start_ts = ts;
+  }
+
+  if (GST_CLOCK_DIFF (self->interval_ts, ts) > self->fps_update_interval) {
+
+    if (self->print_fps)
+      display_current_fps (self);
+
+    if (self->print_arm_load)
+      print_cpu_load (self);
+
+    g_print ("\n");
+    self->interval_ts = ts;
+  }
+  return gst_pad_push (self->srcpad, buf);
+}
+
+
+/* entry point to initialize the plug-in
+ * initialize the plug-in itself
+ * register the element factories and other features
+ */
+static gboolean
+rate_init (GstPlugin * perf)
+{
+  /* debug category for fltering log messages
+   *
+   * exchange the string 'Template perf' with your description
+   */
+  return gst_element_register (perf, "perf", GST_RANK_PRIMARY, GST_TYPE_PERF);
+}
+
+/* PACKAGE: this is usually set by autotools depending on some _INIT macro
+ * in configure.ac and then written into and defined in config.h, but we can
+ * just set it ourselves here in case someone doesn't use autotools to
+ * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
+ */
+#ifndef PACKAGE
+#define PACKAGE "perf"
+#endif
+
+/* gstreamer looks for this structure to register rates
+ *
+ * exchange the string 'Template perf' with your perf description
+ */
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "perf",
+    "Performance display",
+    rate_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
diff --git a/tests/perf/gstperf.h b/tests/perf/gstperf.h
new file mode 100644 (file)
index 0000000..23d6fc1
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2012 Harinarayan Bhatta <<user@hostname.org>>
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_PERF_H__
+#define __GST_PERF_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_PERF \
+  (gst_perf_get_type())
+#define GST_PERF(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PERF,GstPerf))
+#define GST_PERF_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PERF,GstPerfClass))
+#define GST_IS_RATE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PERF))
+#define GST_IS_RATE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PERF))
+typedef struct _GstPerf GstPerf;
+typedef struct _GstPerfClass GstPerfClass;
+
+struct _GstPerf
+{
+  GstElement element;
+
+  GstPad *sinkpad, *srcpad;
+  GstClockTime last_time;
+
+  /* statistics */
+  guint64 frames_count, last_frames_count, total_size;
+
+  GstClockTime start_ts;
+  GstClockTime last_ts;
+  GstClockTime interval_ts;
+  GstClockTime lastbuf_ts;
+
+  gboolean print_fps, print_arm_load, fps_update_interval;
+  unsigned long int total;
+  unsigned long int prevTotal;
+  unsigned long int userTime;
+  unsigned long int prevuserTime;
+
+};
+
+struct _GstPerfClass
+{
+  GstElementClass parent_class;
+};
+
+GType gst_perf_get_type (void);
+
+G_END_DECLS
+#endif /* __GST_PERF_H__ */
diff --git a/tests/vpetest/Makefile.am b/tests/vpetest/Makefile.am
new file mode 100644 (file)
index 0000000..225cfce
--- /dev/null
@@ -0,0 +1,8 @@
+
+noinst_PROGRAMS = gstvpetest 
+
+gstvpetest_SOURCES = gstvpetest.c
+gstvpetest_CFLAGS = $(GST_CFLAGS)
+gstvpetest_LDADD = $(GST_LIBS)
+
+
diff --git a/tests/vpetest/gstvpetest.c b/tests/vpetest/gstvpetest.c
new file mode 100755 (executable)
index 0000000..c633a41
--- /dev/null
@@ -0,0 +1,361 @@
+/*\r
+ * GStreamer\r
+ * Copyright (c) 2014, Texas Instruments Incorporated\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation\r
+ * version 2.1 of the License.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
+ */  \r
+    \r
+#ifdef HAVE_CONFIG_H\r
+#include <config.h>\r
+#endif /* \r */
+    \r
+#define _GNU_SOURCE\r
+#include <features.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <errno.h>\r
+#include <sys/types.h>\r
+#include <sys/time.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+    \r
+#include <gst/gst.h>\r
+\rstatic int sigtermed = 0;
+\r \r
+#define MAX_PIPELINES 16\r
+\rstatic GstElement *p[MAX_PIPELINES];
+\r \rstatic void
+my_signal_handler (int signum) \r
+{
+  \rif (signum == SIGINT) {
+    \rsigtermed = 1;
+  \r}
+\r}
+
+\r \rstatic void
+pad_added_cb (GstElement * element, GstPad * pad, void *data) \r
+{
+  \rGstElement * parse = GST_ELEMENT (data);
+  \rGstPad * sinkpad;
+  \rgchar * theName = GST_PAD_NAME (pad);
+  \rprintf ("pad added:%s\n", theName);
+  \rif (strstr (theName, "video") != NULL) {
+    \rsinkpad = gst_element_get_static_pad (parse, "sink");
+    \rgst_pad_link (pad, sinkpad);
+    \rgst_object_unref (sinkpad);
+  \r} else
+    \rprintf ("not linking audio pad\n");
+\r}
+
+\r \rstatic const char *sinkname = "kmssink";
+\rstatic gboolean use_vpe = TRUE;
+\rstatic gboolean use_scaling = TRUE;
+\rstatic gint scale_w = 800, scale_h = 480;
+\rstatic gboolean use_avsync = TRUE;
+\r \rstatic GstElement *
+create_pipeline (char *arg) \r
+{
+  \rGstElement * src1;
+  \rGstElement * demux;
+  \rGstElement * vdecode, *h264parse, *pipeline, *gstperf, *filter;
+  \rGstElement * vqueue;
+  \rGstElement * queue, *vsink;
+  \rGstCaps * filtercaps;
+  \rconst char *decoder_name, *parser_name, *demux_name;
+  \r \rif (NULL != strcasestr (arg, ".mkv"))
+    demux_name = "matroskademux";
+  \r
+  else if (NULL != strcasestr (arg, ".mp4"))
+    demux_name = "qtdemux";
+  \r
+  else if (NULL != strcasestr (arg, ".asf"))
+    demux_name = "asfdemux";
+  \r
+  else if (NULL != strcasestr (arg, ".wmv"))
+    demux_name = "asfdemux";
+  \r
+  else if (NULL != strcasestr (arg, ".ts"))
+    demux_name = "mpegtsdemux";
+  \r
+  else
+    demux_name = "identity";
+  \r \rif (NULL != strcasestr (arg, "264")) {
+    \rdecoder_name = use_vpe ? "ducatih264decvpe" : "ducatih264dec";
+    \rparser_name = "h264parse";
+  \r}
+  \r
+  else if (NULL != strcasestr (arg, "mpeg2")) {
+    \rdecoder_name = use_vpe ? "ducatimpeg2decvpe" : "ducatimpeg2dec";
+    \rparser_name = "mpegvideoparse";
+  \r}
+  \r
+  else if (NULL != strcasestr (arg, "mpeg4")) {
+    \rdecoder_name = use_vpe ? "ducatimpeg4decvpe" : "ducatimpeg4dec";
+    \rparser_name = "mpeg4videoparse";
+  \r}
+  \r
+  else {
+    \rdecoder_name = use_vpe ? "ducativc1decvpe" : "ducativc1dec";
+    \rparser_name = "identity";
+  \r}
+  \r \rprintf ("Creating pipeline with %s->%s->%s\n", \rdemux_name, parser_name,
+      decoder_name);
+  \r \rpipeline = gst_pipeline_new ("my-pipeline");
+  \r \rsrc1 = gst_element_factory_make ("filesrc", "src1");
+  \r \rif (src1 == NULL)
+    printf ("Could not create 'src1' element\r\n");
+  \r \rdemux = gst_element_factory_make (demux_name, "demux");
+  \rif (demux == NULL)
+    printf ("Could not create 'demux' element\r\n");
+  \r \rvdecode = gst_element_factory_make (decoder_name, "vdecode");
+  \rif (vdecode == NULL)
+    printf ("Could not create 'omx_h264dec1' element\r\n");
+  \r \rh264parse = gst_element_factory_make (parser_name, "h264parse");
+  \rif (h264parse == NULL)
+    printf ("Could not create 'h264parse' element\r\n");
+  \r \rvsink = gst_element_factory_make (sinkname, "kmssink");
+  \rif (vsink == NULL)
+    \rprintf ("Could not create neither 'omx_videosink' element\r\n");
+  \r \rgstperf = gst_element_factory_make ("perf", "perf");
+  \rif (gstperf == NULL)
+    \rprintf ("Could not create neither 'perf' element\r\n");
+  \r \rqueue = gst_element_factory_make ("queue", "queue");
+  \rif (queue == NULL)
+    \rprintf ("Could not create neither 'queue' element\r\n");
+  \r \rvqueue = gst_element_factory_make ("queue", "vqueue");
+  \rif (vqueue == NULL)
+    \rprintf ("Could not create neither 'queue' element\r\n");
+  \r \rfilter =
+      gst_element_factory_make (use_scaling ? "capsfilter" : "identity",
+      "filter");
+  \rif (filter == NULL)
+    \rprintf ("Could not create 'capsfilter' element\r\n");
+  \r \rfiltercaps =
+      gst_caps_new_simple ("video/x-raw-yuv", \r"format", GST_TYPE_FOURCC,
+      GST_MAKE_FOURCC ('N', 'V', '1', '2'), \r"width", G_TYPE_INT, scale_w,
+      \r"height", G_TYPE_INT, scale_h, \rNULL);
+  \rg_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
+  \rgst_caps_unref (filtercaps);
+  \r \rprintf ("set locaticn to : %s\n", arg);
+  \r
+      // ================= Add capabilities and properties\r
+      // g_object_set(G_OBJECT (scaler), "num-input-buffers", 24, NULL);\r
+      // g_object_set(G_OBJECT (scaler), "num-output-buffers", 12, NULL);\r
+      // g_object_set(G_OBJECT (vdecode), "max-reorder-frames", 4, NULL);\r
+      g_object_set (G_OBJECT (src1), "location", arg, NULL);
+  \rg_object_set (G_OBJECT (vsink), "sync", use_avsync, NULL);
+  \r \r
+      // ================= Put pipeline together\r
+      gst_bin_add_many (\rGST_BIN (pipeline), \rsrc1, demux, h264parse, vdecode,
+      vsink, \rgstperf, filter, vqueue, queue, \rNULL \r);
+  \r \rgst_element_link_many (src1, demux, NULL);
+  \rgst_element_link_many (h264parse, queue, vdecode, vqueue, filter, gstperf,
+      vsink, NULL);
+  \r \rif (!g_signal_connect (demux, "pad-added", G_CALLBACK (pad_added_cb),
+          (void *) h264parse))
+    printf ("Cannot connect pad-added cb\r\n");
+  \r \r
+      // ================= Run\r
+      printf ("Set Play Mode ...\r\n");
+  \rgst_element_set_state (pipeline, GST_STATE_PLAYING);
+  \r
+#if 0\r
+  {
+    \rGstClock * clk = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
+    \rif (clk) {
+      \rprintf ("Pipeline clock is %s\n", GST_OBJECT_NAME (clk));
+      \rgst_object_unref (clk);
+    \r}
+  \r}
+  \r
+#endif /* \r */
+      return pipeline;
+\r}
+
+\r \rgint \r main (gint argc, gchar * argv[]) \r
+{
+  \rFILE * in = stdin;
+  \rfd_set f;
+  \rchar *line = NULL;
+  \rchar linebuf[1024];
+  \rchar *args[10];
+  \rint n, i, time, j;
+  \r \rif (SIG_ERR == signal (SIGINT, my_signal_handler))
+    \rexit (1);
+  \r \r
+      /* Init GStreamer */ \r
+      gst_init (&argc, &argv);
+  \r \rif (argc > 1 && (0 == strcmp ("-h", argv[1])
+          || 0 == strcmp ("--help", argv[1]))) {
+    \rprintf ("Usage: %s <options>\n", argv[0]);
+    \rprintf
+        ("       -s <sinkname>    Specify the video sink name to be used, default: kmssink\n");
+    \rprintf ("       -n               Do not use VPE, implies - no scaling\n");
+    \rprintf
+        ("       -r <width>x<height> Resize the output to widthxheight, no scaling if left blank\n");
+    \rprintf ("       -a               Play with no A/V Sync\n");
+    \rprintf
+        ("       -c <cmds file>   Non-interactive mode, reading commands from <cmds file>\n");
+  \r}
+  \r \rfor (i = 1; i < argc; i++) {
+    \rif (0 == strcmp ("-s", argv[i])) {
+      \rsinkname = argv[i + 1];
+      \ri++;
+    \r}
+    \rif (0 == strcmp ("-n", argv[i])) {
+      \ruse_vpe = FALSE;
+      \ruse_scaling = FALSE;
+      \rprintf ("Not using VPE...\n");
+    \r}
+    \rif (0 == strcmp ("-r", argv[i])) {
+      \rif ((i + 1) < argc
+          && \r2 == sscanf (argv[i + 1], "%dx%d", &scale_w, &scale_h)) {
+        \rprintf ("Scaling output to %dx%d\n", scale_w, scale_h);
+      \r} else {
+        \ruse_scaling = FALSE;
+        \rprintf ("Not using Scaling...\n");
+      \r}
+    \r}
+    \rif (0 == strcmp ("-a", argv[i])) {
+      \ruse_avsync = FALSE;
+      \rprintf ("No A/V Sync, playing as fast as possible...\n");
+    \r}
+    \rif (0 == strcmp ("-c", argv[i]) && (i + 1) < argc) {
+      \rin = fopen (argv[i + 1], "r");
+      \rif (!in) {
+        \rprintf
+            ("cannot open %s to read in commands, reverting to interactive mode\n",
+            argv[i + 1]);
+        \rin = stdin;
+      \r}
+      \ri++;
+    \r}
+  \r}
+  \rprintf ("Using videosink=%s\n", sinkname);
+  \r \r
+// To detect memory leaks\r
+      if (!gst_alloc_trace_available ()) {
+    \rprintf ("Trace not available (recompile with trace enabled).\n");
+  \r}
+  \rgst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE |
+      GST_ALLOC_TRACE_MEM_LIVE);
+  \rgst_alloc_trace_print_live ();
+  \r \rwhile (!sigtermed) {
+    \rif (in == stdin) {
+      \rfflush (stdout);
+      \rFD_ZERO (&f);
+      \rFD_SET (0, &f);
+    \r}
+    \rprintf ("<Enter ip> ");
+    \rline = fgets (linebuf, 1023, in);
+    \rif (!line)
+      continue;
+    \rline[1023] = '\0';
+    \rn = 0;
+    \rwhile (*line) {
+      \rargs[n++] = line;
+      \rwhile (!isspace (*line))
+        line++;
+      \rif (!(*line))
+        break;
+      \r*line = '\0';
+      line++;
+      \rwhile (isspace (*line))
+        line++;
+    \r}
+    \rif (3 == n && 0 == strcmp ("start", args[0])) {
+      \ri = atoi (args[1]);
+      \rprintf ("Starting pipeline %d\n", i);
+      \rp[i] = create_pipeline (args[2]);
+    \r}
+    \r
+    else if (2 == n && 0 == strcmp ("stop", args[0])) {
+      \ri = atoi (args[1]);
+      \rif (p[i]) {
+        \rgst_element_set_state (p[i], GST_STATE_NULL);
+        \rgst_object_unref (p[i]);
+        \rp[i] = NULL;
+      \r}
+    \r}
+    \r
+    else if (2 == n && 0 == strcmp ("pause", args[0])) {
+      \ri = atoi (args[1]);
+      \rif (p[i])
+        \rgst_element_set_state (p[i], GST_STATE_PAUSED);
+    \r}
+    \r
+    else if (2 == n && 0 == strcmp ("resume", args[0])) {
+      \ri = atoi (args[1]);
+      \rif (p[i])
+        \rgst_element_set_state (p[i], GST_STATE_PLAYING);
+    \r}
+    \r
+    else if (3 == n && 0 == strcmp ("seek", args[0])) {
+      \ri = atoi (args[1]);
+      \rtime = atoi (args[2]);
+      \rif (p[i])
+        \rgst_element_seek_simple (p[i], GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+            time * GST_SECOND);
+    \r}
+    \r
+    else if (2 == n && 0 == strcmp ("sleep", args[0])) {
+      \rsleep (atoi (args[1]));
+    \r}
+    \r
+    else if (2 == n && 0 == strcmp ("rewind", args[0])) {
+      \rif (in != stdin) {
+        \rrewind (in);
+        \rj = atoi (args[1]);
+        \rwhile (--j)
+          fgets (linebuf, 1023, in);
+      \r}
+    \r}
+    \r
+    else if (1 == n && 0 == strcmp ("exit", args[0])) {
+      \rbreak;
+    \r}
+    \r
+    else if (1 == n && 0 == strcmp ("help", args[0])) {
+      \rprintf ("Commands available:\n");
+      \rprintf (" start  <instance num> <filename>\n");
+      \rprintf (" stop   <instance num>\n");
+      \rprintf (" pause  <instance num>\n");
+      \rprintf (" resume <instance num>\n");
+      \rprintf (" seek   <instance num> <seek to time in seconds>\n");
+      \rprintf (" seek   <instance num> <seek to time in seconds>\n");
+      \rprintf (" sleep   <sleep time in seconds>\n");
+      \rprintf
+          (" rewind <line number> <rewind command file go to line number>\n");
+      \rprintf (" exit\n");
+    \r}
+  \r}
+  \rfor (i = 0; i < MAX_PIPELINES; i++) {
+    \rif (p[i]) {
+      \rgst_element_set_state (p[i], GST_STATE_NULL);
+      \rgst_object_unref (p[i]);
+      \rp[i] = NULL;
+    \r}
+  \r}
+  \rsleep (1);
+  \rgst_alloc_trace_print_live ();
+  \r {
+    \rchar command[256];
+    \rsprintf (command, "ls -l //proc//%d//fd//", getpid ());
+    \rsystem (command);
+  \r\rreturn 0;
+\r}
+
+\r