ensonic gst-plugins-base: gst-plugins-base/ gst-plugins-base/gst/adder/

[email protected] Wed, 17 Dec 2008 00:51:49 -0800 (PST)
Newsgroups gmane.comp.video.gstreamer.cvs
Message-ID <[email protected]>
CVS Root:       /cvs/gstreamer
Module:         gst-plugins-base
Changes by:     ensonic
Date:           Wed Dec 17 2008  08:51:49 UTC

Log message:
	* gst/adder/Makefile.am:
	* gst/adder/gstadder.c:
	  Cleanup variable names to make the adder-loop easier to understand.
	  Also try to use liboil to spee it up, but ifdef it out as it does not
	  make any change for me (Intel pentim M (sse,sse2) please try on other
	  systems).

Modified files:
    .               : ChangeLog
    gst/adder       : Makefile.am gstadder.c

Links:
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.4256&r2=1.4257
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/adder/Makefile.am.diff?r1=1.11&r2=1.12
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/adder/gstadder.c.diff?r1=1.103&r2=1.104

====Begin Diffs====
Index: ChangeLog
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v
retrieving revision 1.4256
retrieving revision 1.4257
diff -u -d -r1.4256 -r1.4257
--- ChangeLog	16 Dec 2008 20:16:15 -0000	1.4256
+++ ChangeLog	17 Dec 2008 08:51:33 -0000	1.4257
@@ -1,3 +1,12 @@
+2008-12-17  Stefan Kost  <[email protected]>
+
+	* gst/adder/Makefile.am:
+	* gst/adder/gstadder.c:
+	  Cleanup variable names to make the adder-loop easier to understand.
+	  Also try to use liboil to spee it up, but ifdef it out as it does not
+	  make any change for me (Intel pentim M (sse,sse2) please try on other
+	  systems).
 2008-12-16  Wim Taymans  <[email protected]>
 
 	* docs/plugins/Makefile.am:
Index: Makefile.am
RCS file: /cvs/gstreamer/gst-plugins-base/gst/adder/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- Makefile.am	16 Oct 2008 15:06:54 -0000	1.11
+++ Makefile.am	17 Dec 2008 08:51:34 -0000	1.12
@@ -2,8 +2,10 @@
 libgstadder_la_SOURCES = gstadder.c
 libgstadder_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+#$(LIBOIL_CFLAGS)
 libgstadder_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstadder_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
+#$(LIBOIL_LIBS)
 libgstadder_la_LIBTOOLFLAGS = --tag=disable-static
 noinst_HEADERS = gstadder.h
Index: gstadder.c
RCS file: /cvs/gstreamer/gst-plugins-base/gst/adder/gstadder.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -d -r1.103 -r1.104
--- gstadder.c	10 Nov 2008 13:55:08 -0000	1.103
+++ gstadder.c	17 Dec 2008 08:51:34 -0000	1.104
@@ -46,6 +46,7 @@
 #include "gstadder.h"
 #include <gst/audio/audio.h>
 #include <string.h>             /* strcmp */
+/*#include <liboil/liboil.h>*/
 /* highest positive/lowest negative x-bit value we can use for clamping */
 #define MAX_INT_32  ((gint32) (0x7fffffff))
@@ -151,7 +152,9 @@
   return adder_type;
 }
-/* clipping versions */
+/* clipping versions
+ * FIXME: what about: oil_add_s16 (out, out, in, bytes / sizeof (type))
+ */
 #define MAKE_FUNC(name,type,ttype,min,max)                      \
 static void name (type *out, type *in, gint bytes) {            \
   gint i;                                                       \
@@ -160,13 +163,31 @@
 /* non-clipping versions (for float) */
-#define MAKE_FUNC_NC(name,type,ttype)                           \
+#define MAKE_FUNC_NC(name,type)                                 \
   for (i = 0; i < bytes / sizeof (type); i++)                   \
-    out[i] = (ttype)out[i] + (ttype)in[i];                      \
+    out[i] += in[i];                                            \
+#if 0
+/* right now, the liboil function don't seems to be faster
+ * time gst-launch audiotestsrc num-buffers=50000 ! audio/x-raw-float ! adder name=m ! fakesink audiotestsrc num-buffers=50000 ! audio/x-raw-float ! m.
+ * time gst-launch audiotestsrc num-buffers=50000 ! audio/x-raw-float,width=32 ! adder name=m ! fakesink audiotestsrc num-buffers=50000 ! audio/x-raw-float,width=32 ! m.
+static void
+add_float32 (gfloat * out, gfloat * in, gint bytes)
+{
+  oil_add_f32 (out, out, in, bytes / sizeof (gfloat));
+}
+add_float64 (gdouble * out, gdouble * in, gint bytes)
+  oil_add_f64 (out, out, in, bytes / sizeof (gdouble));
+#endif
 /* *INDENT-OFF* */
 MAKE_FUNC (add_int32, gint32, gint64, MIN_INT_32, MAX_INT_32)
 MAKE_FUNC (add_int16, gint16, gint32, MIN_INT_16, MAX_INT_16)
@@ -174,8 +195,8 @@
 MAKE_FUNC (add_uint32, guint32, guint64, MIN_UINT_32, MAX_UINT_32)
 MAKE_FUNC (add_uint16, guint16, guint32, MIN_UINT_16, MAX_UINT_16)
 MAKE_FUNC (add_uint8, guint8, guint16, MIN_UINT_8, MAX_UINT_8)
-MAKE_FUNC_NC (add_float64, gdouble, gdouble)
-MAKE_FUNC_NC (add_float32, gfloat, gfloat)
+MAKE_FUNC_NC (add_float64, gdouble)
+MAKE_FUNC_NC (add_float32, gfloat)
 /* *INDENT-ON* */
 /* we can only accept caps that we and downstream can handle. */
@@ -244,13 +265,15 @@
   structure = gst_caps_get_structure (caps, 0);
   media_type = gst_structure_get_name (structure);
   if (strcmp (media_type, "audio/x-raw-int") == 0) {
-    GST_DEBUG_OBJECT (adder, "parse_caps sets adder to format int");
     adder->format = GST_ADDER_FORMAT_INT;
     gst_structure_get_int (structure, "width", &adder->width);
     gst_structure_get_int (structure, "depth", &adder->depth);
     gst_structure_get_int (structure, "endianness", &adder->endianness);
     gst_structure_get_boolean (structure, "signed", &adder->is_signed);
+    GST_INFO_OBJECT (adder, "parse_caps sets adder to format int, %d bit",
+        adder->width);
     if (adder->endianness != G_BYTE_ORDER)
       goto not_supported;
@@ -271,11 +294,13 @@
         goto not_supported;
     }
   } else if (strcmp (media_type, "audio/x-raw-float") == 0) {
-    GST_DEBUG_OBJECT (adder, "parse_caps sets adder to format float");
     adder->format = GST_ADDER_FORMAT_FLOAT;
+    GST_INFO_OBJECT (adder, "parse_caps sets adder to format float, %d bit",
@@ -801,7 +826,7 @@
 gst_adder_collected (GstCollectPads * pads, gpointer user_data)
 {
   /*
-   * combine channels by adding sample values
+   * combine streams by adding data values
    * basic algorithm :
    * - this function is called when all pads have a buffer
    * - get available bytes on all pads.
@@ -809,13 +834,19 @@
    *   - read available bytes, copy or add to target buffer
    *   - if there's an EOS event, remove the input channel
    * - push out the output buffer
+   *
+   * todo:
+   * - would be nice to have a mixing mode, where instead of adding we mix
+   *   - for float we could downscale after collect loop
+   *   - for int we need to downscale each input to avoid clipping or
+   *     mix into a temp (float) buffer and scale afterwards as well
    */
   GstAdder *adder;
-  guint size;
   GSList *collected;
-  GstBuffer *outbuf;
   GstFlowReturn ret;
-  gpointer outbytes;
+  GstBuffer *outbuf = NULL;
+  gpointer outdata = NULL;
+  guint outsize;
   gboolean empty = TRUE;
   adder = GST_ADDER (user_data);
@@ -824,79 +855,75 @@
   if (G_UNLIKELY (adder->func == NULL))
     goto not_negotiated;
-  /* get available bytes for reading, this can be 0 which could mean
-   * empty buffers or EOS, which we will catch when we loop over the
-   * pads. */
-  size = gst_collect_pads_available (pads);
+  /* get available bytes for reading, this can be 0 which could mean empty
+   * buffers or EOS, which we will catch when we loop over the pads. */
+  outsize = gst_collect_pads_available (pads);
   GST_LOG_OBJECT (adder,
-      "starting to cycle through channels, %d bytes available (bps = %d)", size,
-      adder->bps);
-
-  outbuf = NULL;
-  outbytes = NULL;
+      "starting to cycle through channels, %d bytes available (bps = %d)",
+      outsize, adder->bps);
   for (collected = pads->data; collected; collected = g_slist_next (collected)) {
-    GstCollectData *data;
-    guint8 *bytes;
-    guint len;
+    GstCollectData *collect_data;
     GstBuffer *inbuf;
+    guint8 *indata;
+    guint insize;
-    data = (GstCollectData *) collected->data;
+    collect_data = (GstCollectData *) collected->data;
     /* get a subbuffer of size bytes */
-    inbuf = gst_collect_pads_take_buffer (pads, data, size);
+    inbuf = gst_collect_pads_take_buffer (pads, collect_data, outsize);
     /* NULL means EOS or an empty buffer so we still need to flush in
      * case of an empty buffer. */
     if (inbuf == NULL) {
-      GST_LOG_OBJECT (adder, "channel %p: no bytes available", data);
-      goto next;
+      GST_LOG_OBJECT (adder, "channel %p: no bytes available", collect_data);
+      continue;
-    bytes = GST_BUFFER_DATA (inbuf);
-    len = GST_BUFFER_SIZE (inbuf);
+    indata = GST_BUFFER_DATA (inbuf);
+    insize = GST_BUFFER_SIZE (inbuf);
     if (outbuf == NULL) {
       GST_LOG_OBJECT (adder, "channel %p: making output buffer of %d bytes",
-          data, size);
+          collect_data, outsize);
-      /* first buffer, alloc size bytes. FIXME, we can easily subbuffer
-       * and _make_writable. */
-      outbuf = gst_buffer_new_and_alloc (size);
-      outbytes = GST_BUFFER_DATA (outbuf);
+      /* first buffer, alloc outsize.
+       * FIXME: we can easily subbuffer and _make_writable.
+       * FIXME: only create empty buffer for first non-gap buffer, so that we
+       * only use adder function when really adding
+       */
+      outbuf = gst_buffer_new_and_alloc (outsize);
+      outdata = GST_BUFFER_DATA (outbuf);
       gst_buffer_set_caps (outbuf, GST_PAD_CAPS (adder->srcpad));
       if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
-        /* clear if we are only going to fill a partial buffer */
-        if (G_UNLIKELY (size > len))
-          memset (outbytes, 0, size);
         GST_LOG_OBJECT (adder, "channel %p: copying %d bytes from data %p",
-            data, len, bytes);
+            collect_data, insize, indata);
+        /* clear if we are only going to fill a partial buffer */
+        if (G_UNLIKELY (outsize > insize))
+          memset (outdata + insize, 0, outsize - insize);
         /* and copy the data into it */
-        memcpy (outbytes, bytes, len);
+        memcpy (outdata, indata, insize);
         empty = FALSE;
       } else {
+        /* clear whole buffer */
         GST_LOG_OBJECT (adder, "channel %p: zeroing %d bytes from data %p",
-        memset (outbytes, 0, size);
+        memset (outdata, 0, outsize);
       }
     } else {
         GST_LOG_OBJECT (adder, "channel %p: mixing %d bytes from data %p",
-        /* other buffers, need to add them */
-        adder->func ((gpointer) outbytes, (gpointer) bytes, len);
+        /* further buffers, need to add them */
+        adder->func ((gpointer) outdata, (gpointer) indata, insize);
         GST_LOG_OBJECT (adder, "channel %p: skipping %d bytes from data %p",
-  next:
-    if (inbuf)
-      gst_buffer_unref (inbuf);
+    gst_buffer_unref (inbuf);
   }
   /* can only happen when no pads to collect or all EOS */
@@ -936,7 +963,7 @@
   /* for the next timestamp, use the sample counter, which will
    * never accumulate rounding errors */
-  adder->offset += size / adder->bps;
+  adder->offset += outsize / adder->bps;
   adder->timestamp = gst_util_uint64_scale_int (adder->offset,
       GST_SECOND, adder->rate);
@@ -1015,6 +1042,8 @@
 static gboolean
 plugin_init (GstPlugin * plugin)
+  /*oil_init (); */
   if (!gst_element_register (plugin, "adder", GST_RANK_NONE, GST_TYPE_ADDER)) {
     return FALSE;

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/