mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
adapter: Add function to return buffer composed of multiple memories
API: gst_adapter_take_fast()
This commit is contained in:
parent
3821cee574
commit
5920491597
4 changed files with 129 additions and 3 deletions
|
@ -708,6 +708,92 @@ gst_adapter_take (GstAdapter * adapter, gsize nbytes)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_adapter_take_buffer_fast:
|
||||||
|
* @adapter: a #GstAdapter
|
||||||
|
* @nbytes: the number of bytes to take
|
||||||
|
*
|
||||||
|
* Returns a #GstBuffer containing the first @nbytes of the @adapter.
|
||||||
|
* The returned bytes will be flushed from the adapter. This function
|
||||||
|
* is potentially more performant than gst_adapter_take_buffer() since
|
||||||
|
* it can reuse the memory in pushed buffers by subbuffering or
|
||||||
|
* merging. Unlike gst_adapter_take_buffer(), the returned buffer may
|
||||||
|
* be composed of multiple non-contiguous #GstMemory objects, no
|
||||||
|
* copies are made.
|
||||||
|
*
|
||||||
|
* Note that no assumptions should be made as to whether certain buffer
|
||||||
|
* flags such as the DISCONT flag are set on the returned buffer, or not.
|
||||||
|
* The caller needs to explicitly set or unset flags that should be set or
|
||||||
|
* unset.
|
||||||
|
*
|
||||||
|
* This function can return buffer up to the return value of
|
||||||
|
* gst_adapter_available() without making copies if possible.
|
||||||
|
*
|
||||||
|
* Caller owns a reference to the returned buffer. gst_buffer_unref() after
|
||||||
|
* usage.
|
||||||
|
*
|
||||||
|
* Free-function: gst_buffer_unref
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a #GstBuffer containing the first @nbytes of
|
||||||
|
* the adapter, or #NULL if @nbytes bytes are not available.
|
||||||
|
* gst_buffer_unref() when no longer needed.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
GstBuffer *
|
||||||
|
gst_adapter_take_buffer_fast (GstAdapter * adapter, gsize nbytes)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = NULL;
|
||||||
|
GstBuffer *cur;
|
||||||
|
GSList *item;
|
||||||
|
gsize skip;
|
||||||
|
gsize left = nbytes;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
|
||||||
|
g_return_val_if_fail (nbytes > 0, NULL);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (adapter, "taking buffer of %" G_GSIZE_FORMAT " bytes",
|
||||||
|
nbytes);
|
||||||
|
|
||||||
|
/* we don't have enough data, return NULL. This is unlikely
|
||||||
|
* as one usually does an _available() first instead of grabbing a
|
||||||
|
* random size. */
|
||||||
|
if (G_UNLIKELY (nbytes > adapter->size))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
skip = adapter->skip;
|
||||||
|
cur = adapter->buflist->data;
|
||||||
|
|
||||||
|
if (skip == 0 && gst_buffer_get_size (cur) == nbytes) {
|
||||||
|
GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
|
||||||
|
" as head buffer", nbytes);
|
||||||
|
buffer = gst_buffer_ref (cur);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item = adapter->buflist; item && left > 0; item = item->next) {
|
||||||
|
gsize size;
|
||||||
|
|
||||||
|
cur = item->data;
|
||||||
|
size = MIN (gst_buffer_get_size (cur), left);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (adapter, "appending %" G_GSIZE_FORMAT " bytes"
|
||||||
|
" via region copy", size);
|
||||||
|
if (buffer)
|
||||||
|
gst_buffer_copy_into (buffer, cur, GST_BUFFER_COPY_MEMORY, 0, size);
|
||||||
|
else
|
||||||
|
buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, size);
|
||||||
|
skip = 0;
|
||||||
|
left -= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
gst_adapter_flush_unchecked (adapter, nbytes);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_adapter_take_buffer:
|
* gst_adapter_take_buffer:
|
||||||
* @adapter: a #GstAdapter
|
* @adapter: a #GstAdapter
|
||||||
|
@ -715,9 +801,10 @@ gst_adapter_take (GstAdapter * adapter, gsize nbytes)
|
||||||
*
|
*
|
||||||
* Returns a #GstBuffer containing the first @nbytes bytes of the
|
* Returns a #GstBuffer containing the first @nbytes bytes of the
|
||||||
* @adapter. The returned bytes will be flushed from the adapter.
|
* @adapter. The returned bytes will be flushed from the adapter.
|
||||||
* This function is potentially more performant than gst_adapter_take()
|
* This function is potentially more performant than
|
||||||
* since it can reuse the memory in pushed buffers by subbuffering
|
* gst_adapter_take() since it can reuse the memory in pushed buffers
|
||||||
* or merging.
|
* by subbuffering or merging. This function will always return a
|
||||||
|
* buffer with a single memory region.
|
||||||
*
|
*
|
||||||
* Note that no assumptions should be made as to whether certain buffer
|
* Note that no assumptions should be made as to whether certain buffer
|
||||||
* flags such as the DISCONT flag are set on the returned buffer, or not.
|
* flags such as the DISCONT flag are set on the returned buffer, or not.
|
||||||
|
|
|
@ -60,6 +60,7 @@ void gst_adapter_flush (GstAdapter *adapter, gs
|
||||||
gpointer gst_adapter_take (GstAdapter *adapter, gsize nbytes);
|
gpointer gst_adapter_take (GstAdapter *adapter, gsize nbytes);
|
||||||
GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, gsize nbytes);
|
GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, gsize nbytes);
|
||||||
GList* gst_adapter_take_list (GstAdapter *adapter, gsize nbytes);
|
GList* gst_adapter_take_list (GstAdapter *adapter, gsize nbytes);
|
||||||
|
GstBuffer * gst_adapter_take_buffer_fast (GstAdapter *adapter, gsize nbytes);
|
||||||
gsize gst_adapter_available (GstAdapter *adapter);
|
gsize gst_adapter_available (GstAdapter *adapter);
|
||||||
gsize gst_adapter_available_fast (GstAdapter *adapter);
|
gsize gst_adapter_available_fast (GstAdapter *adapter);
|
||||||
|
|
||||||
|
|
|
@ -834,6 +834,42 @@ GST_START_TEST (test_merge)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_take_buffer_fast)
|
||||||
|
{
|
||||||
|
GstAdapter *adapter;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
|
||||||
|
adapter = gst_adapter_new ();
|
||||||
|
fail_if (adapter == NULL);
|
||||||
|
|
||||||
|
buffer = gst_buffer_new_and_alloc (5);
|
||||||
|
fail_if (buffer == NULL);
|
||||||
|
gst_adapter_push (adapter, buffer);
|
||||||
|
|
||||||
|
buffer = gst_buffer_new_and_alloc (10);
|
||||||
|
fail_if (buffer == NULL);
|
||||||
|
gst_adapter_push (adapter, buffer);
|
||||||
|
|
||||||
|
buffer = gst_buffer_new_and_alloc (15);
|
||||||
|
fail_if (buffer == NULL);
|
||||||
|
gst_adapter_push (adapter, buffer);
|
||||||
|
|
||||||
|
fail_unless (gst_adapter_available (adapter) == 30);
|
||||||
|
|
||||||
|
buffer = gst_adapter_take_buffer_fast (adapter, 30);
|
||||||
|
fail_unless (gst_adapter_available (adapter) == 0);
|
||||||
|
|
||||||
|
fail_unless (gst_buffer_n_memory (buffer) == 3);
|
||||||
|
fail_unless (gst_buffer_get_sizes_range (buffer, 0, 1, NULL, NULL) == 5);
|
||||||
|
fail_unless (gst_buffer_get_sizes_range (buffer, 1, 1, NULL, NULL) == 10);
|
||||||
|
fail_unless (gst_buffer_get_sizes_range (buffer, 2, 1, NULL, NULL) == 15);
|
||||||
|
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
g_object_unref (adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_adapter_suite (void)
|
gst_adapter_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -853,6 +889,7 @@ gst_adapter_suite (void)
|
||||||
tcase_add_test (tc_chain, test_scan);
|
tcase_add_test (tc_chain, test_scan);
|
||||||
tcase_add_test (tc_chain, test_take_list);
|
tcase_add_test (tc_chain, test_take_list);
|
||||||
tcase_add_test (tc_chain, test_merge);
|
tcase_add_test (tc_chain, test_merge);
|
||||||
|
tcase_add_test (tc_chain, test_take_buffer_fast);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ EXPORTS
|
||||||
gst_adapter_push
|
gst_adapter_push
|
||||||
gst_adapter_take
|
gst_adapter_take
|
||||||
gst_adapter_take_buffer
|
gst_adapter_take_buffer
|
||||||
|
gst_adapter_take_buffer_fast
|
||||||
gst_adapter_take_list
|
gst_adapter_take_list
|
||||||
gst_adapter_unmap
|
gst_adapter_unmap
|
||||||
gst_base_parse_add_index_entry
|
gst_base_parse_add_index_entry
|
||||||
|
|
Loading…
Reference in a new issue