diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-07-10 18:37:14 +0100 |
---|---|---|
committer | Wim Taymans <wim@metal.(none)> | 2009-07-10 18:37:14 +0100 |
commit | cc5cdb1fba71fc8023a8f57f907bb7e7ff40899a (patch) | |
tree | 550726c2b68bff9d4225c71e22d4e7a1cb134d0b | |
parent | 8ecbf002b8629fc1ac2bca236fc97f38c9b5ef05 (diff) |
adapter: add function to get a list of buffersadapter-list
Add a function to retrieve a list of buffers containing the first N bytes from
the adapter. This can be done without a memcpy and should make it possible to
transfer the list to a GstBufferList later.
-rw-r--r-- | docs/libs/gstreamer-libs-sections.txt | 1 | ||||
-rw-r--r-- | libs/gst/base/gstadapter.c | 48 | ||||
-rw-r--r-- | libs/gst/base/gstadapter.h | 1 | ||||
-rw-r--r-- | tests/check/libs/adapter.c | 41 |
4 files changed, 91 insertions, 0 deletions
diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 44ed3e62d..c1d1a8777 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -205,6 +205,7 @@ gst_adapter_available gst_adapter_available_fast gst_adapter_take gst_adapter_take_buffer +gst_adapter_take_list gst_adapter_prev_timestamp gst_adapter_masked_scan_uint32 <SUBSECTION Standard> diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c index 3c44e8ec2..c8d4feb8c 100644 --- a/libs/gst/base/gstadapter.c +++ b/libs/gst/base/gstadapter.c @@ -652,6 +652,54 @@ done: } /** + * gst_adapter_take_list: + * @adapter: a #GstAdapter + * @nbytes: the number of bytes to take + * + * Returns a #GSList of buffers containing the first @nbytes bytes of the + * @adapter. The returned bytes will be flushed from the adapter. + * When the caller can deal with individual buffers, this function is more + * performant because no memory should be coppied. + * + * Caller owns returned list and contained buffers. gst_buffer_unref() each + * buffer in the list before freeng the list after usage. + * + * Since: 0.10.24 + * + * Returns: a #GSList of buffers containing the first @nbytes of the adapter, + * or #NULL if @nbytes bytes are not available + */ +GList * +gst_adapter_take_list (GstAdapter * adapter, guint nbytes) +{ + GList *result = NULL, *tail = NULL; + GstBuffer *cur; + guint hsize, skip; + + g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL); + g_return_val_if_fail (nbytes <= adapter->size, NULL); + + GST_LOG_OBJECT (adapter, "taking %u bytes", nbytes); + + while (nbytes > 0) { + cur = adapter->buflist->data; + skip = adapter->skip; + hsize = MIN (nbytes, GST_BUFFER_SIZE (cur) - skip); + + cur = gst_adapter_take_buffer (adapter, hsize); + + if (result == NULL) { + result = tail = g_list_append (result, cur); + } else { + tail = g_list_append (tail, cur); + tail = g_list_next (tail); + } + nbytes -= hsize; + } + return result; +} + +/** * gst_adapter_available: * @adapter: a #GstAdapter * diff --git a/libs/gst/base/gstadapter.h b/libs/gst/base/gstadapter.h index 49e408e0f..c6a2fefff 100644 --- a/libs/gst/base/gstadapter.h +++ b/libs/gst/base/gstadapter.h @@ -90,6 +90,7 @@ void gst_adapter_copy (GstAdapter *adapter, guint8 *dest, void gst_adapter_flush (GstAdapter *adapter, guint flush); guint8* gst_adapter_take (GstAdapter *adapter, guint nbytes); GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, guint nbytes); +GList* gst_adapter_take_list (GstAdapter *adapter, guint nbytes); guint gst_adapter_available (GstAdapter *adapter); guint gst_adapter_available_fast (GstAdapter *adapter); diff --git a/tests/check/libs/adapter.c b/tests/check/libs/adapter.c index 34cef2380..317d2ea6d 100644 --- a/tests/check/libs/adapter.c +++ b/tests/check/libs/adapter.c @@ -601,6 +601,46 @@ GST_START_TEST (test_scan) GST_END_TEST; +/* Fill a buffer with a sequence of 32 bit ints and read them back out + * using take_buffer, checking that they're still in the right order */ +GST_START_TEST (test_take_list) +{ + GstAdapter *adapter; + int i = 0; + + adapter = create_and_fill_adapter (); + while (gst_adapter_available (adapter) >= sizeof (guint32)) { + GList *list, *walk; + GstBuffer *buf; + guint size; + guint8 *data; + + list = gst_adapter_take_list (adapter, sizeof (guint32) * 5); + fail_unless (list != NULL); + + for (walk = list; walk; walk = g_list_next (walk)) { + buf = walk->data; + data = GST_BUFFER_DATA (buf); + size = GST_BUFFER_SIZE (buf); + + while (size > 0) { + fail_unless (GST_READ_UINT32_LE (data) == i); + i++; + data += sizeof (guint32); + size -= sizeof (guint32); + } + gst_buffer_unref (buf); + } + g_list_free (list); + } + fail_unless (gst_adapter_available (adapter) == 0, + "Data was left in the adapter"); + + g_object_unref (adapter); +} + +GST_END_TEST; + static Suite * gst_adapter_suite (void) { @@ -618,6 +658,7 @@ gst_adapter_suite (void) tcase_add_test (tc_chain, test_take_buf_order); tcase_add_test (tc_chain, test_timestamp); tcase_add_test (tc_chain, test_scan); + tcase_add_test (tc_chain, test_take_list); return s; } |