From: Wim Taymans Date: Fri, 17 Sep 2010 13:51:08 +0000 (+0200) Subject: adapter: add function to get a list of buffers X-Git-Tag: RELEASE-0.10.31~105 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1afaa1680fa932cb0829c63240d96d60dbda0b7a;p=platform%2Fupstream%2Fgstreamer.git adapter: add function to get a list of buffers 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. --- diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 7f29ecb..09d75f3 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 gst_adapter_masked_scan_uint32_peek diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c index 6db0ad8..d76290c 100644 --- a/libs/gst/base/gstadapter.c +++ b/libs/gst/base/gstadapter.c @@ -709,6 +709,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 8a79543..a4b65e3 100644 --- a/libs/gst/base/gstadapter.h +++ b/libs/gst/base/gstadapter.h @@ -90,6 +90,7 @@ void gst_adapter_copy (GstAdapter *adapter, gu 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 0c3ebd3..e9db72a 100644 --- a/tests/check/libs/adapter.c +++ b/tests/check/libs/adapter.c @@ -728,6 +728,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) { @@ -745,6 +785,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; } diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def index c23b4bb..6676afe 100644 --- a/win32/common/libgstbase.def +++ b/win32/common/libgstbase.def @@ -13,6 +13,7 @@ EXPORTS gst_adapter_push gst_adapter_take gst_adapter_take_buffer + gst_adapter_take_list gst_base_sink_do_preroll gst_base_sink_get_blocksize gst_base_sink_get_last_buffer