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.
This commit is contained in:
Wim Taymans 2009-04-27 10:13:01 +02:00
parent ef9ad30fde
commit 605639a2bf
2 changed files with 51 additions and 10 deletions

View file

@ -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;

View file

@ -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;