mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
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:
parent
ef9ad30fde
commit
605639a2bf
2 changed files with 51 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue