[gst-cvs] gstreamer: adapter: optimize taking the headbuffer

Wim Taymans wtay at kemper.freedesktop.org
Tue May 12 01:26:45 PDT 2009


Module: gstreamer
Branch: master
Commit: 605639a2bf839f5a856e92d19910e17e1795b4c3
URL:    http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=605639a2bf839f5a856e92d19910e17e1795b4c3

Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date:   Mon Apr 27 10:13:01 2009 +0200

adapter: optimize taking the headbuffer

When a are requested to take a buffer from the adapter that is exactly the
headbuffer, don't make a subbuffer of it but return that head buffer.

Add a unit-test for this new optimisation.

---

 libs/gst/base/gstadapter.c |   23 +++++++++++++----------
 tests/check/libs/adapter.c |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c
index 58c280d..981a2bb 100644
--- a/libs/gst/base/gstadapter.c
+++ b/libs/gst/base/gstadapter.c
@@ -523,6 +523,7 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
 {
   GstBuffer *buffer;
   GstBuffer *cur;
+  guint hsize;
 
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
   g_return_val_if_fail (nbytes > 0, NULL);
@@ -535,16 +536,20 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
   if (G_UNLIKELY (nbytes > adapter->size))
     return NULL;
 
-  /* our head buffer has enough data left, return it */
   cur = adapter->buflist->data;
-  if (GST_BUFFER_SIZE (cur) >= nbytes + adapter->skip) {
+  hsize = GST_BUFFER_SIZE (cur);
+
+  /* our head buffer has enough data left, return it */
+  if (adapter->skip == 0 && hsize == nbytes) {
+    GST_LOG_OBJECT (adapter, "providing buffer of %d bytes as head buffer",
+        nbytes);
+    buffer = gst_buffer_ref (cur);
+    goto done;
+  } else if (hsize >= nbytes + adapter->skip) {
     GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
         nbytes);
     buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes);
-
-    gst_adapter_flush (adapter, nbytes);
-
-    return buffer;
+    goto done;
   }
 
   if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
@@ -554,10 +559,7 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
       GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
           nbytes);
       buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes);
-
-      gst_adapter_flush (adapter, nbytes);
-
-      return buffer;
+      goto done;
     }
   }
 
@@ -572,6 +574,7 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
     gst_adapter_peek_into (adapter, GST_BUFFER_DATA (buffer), nbytes);
   }
 
+done:
   gst_adapter_flush (adapter, nbytes);
 
   return buffer;
diff --git a/tests/check/libs/adapter.c b/tests/check/libs/adapter.c
index e45c210..41924c7 100644
--- a/tests/check/libs/adapter.c
+++ b/tests/check/libs/adapter.c
@@ -149,6 +149,44 @@ GST_END_TEST;
  */
 GST_START_TEST (test_take1)
 {
+  GstAdapter *adapter;
+  GstBuffer *buffer, *buffer2;
+  guint avail;
+  guint8 *data, *data2;
+
+  adapter = gst_adapter_new ();
+  fail_unless (adapter != NULL);
+
+  buffer = gst_buffer_new_and_alloc (100);
+  fail_unless (buffer != NULL);
+  fail_unless (GST_BUFFER_DATA (buffer) != NULL);
+  fail_unless (GST_BUFFER_SIZE (buffer) == 100);
+
+  data = GST_BUFFER_DATA (buffer);
+
+  /* push in the adapter */
+  gst_adapter_push (adapter, buffer);
+
+  avail = gst_adapter_available (adapter);
+  fail_unless (avail == 100);
+
+  /* take out buffer */
+  buffer2 = gst_adapter_take_buffer (adapter, 100);
+  fail_unless (buffer2 != NULL);
+  fail_unless (GST_BUFFER_DATA (buffer2) != NULL);
+  fail_unless (GST_BUFFER_SIZE (buffer2) == 100);
+  data2 = GST_BUFFER_DATA (buffer2);
+
+  avail = gst_adapter_available (adapter);
+  fail_unless (avail == 0);
+
+  /* the buffer should be the same */
+  fail_unless (buffer == buffer2);
+  fail_unless (data == data2);
+
+  gst_buffer_unref (buffer2);
+
+  g_object_unref (adapter);
 }
 
 GST_END_TEST;





More information about the Gstreamer-commits mailing list