diff options
author | David Schleef <ds@schleef.org> | 2007-01-25 10:50:03 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-01-25 10:50:03 +0000 |
commit | 8be291377174d3e9ca6b171971ae8886e0a71a14 (patch) | |
tree | 8a2b3abb3e92313052742afc026fcb36e32549c4 /libs | |
parent | 00a8f6ac84924943c5162c248806d8edededc914 (diff) |
API: gst_adapter_copy() that can reduce the amount of memcpy when getting data from the adapter. Fixes #388201.
Original commit message from CVS:
Patch by: David Schleef <ds at schleef dot org>
* docs/libs/gstreamer-libs-sections.txt:
* libs/gst/base/gstadapter.c: (gst_adapter_copy):
* libs/gst/base/gstadapter.h:
API: gst_adapter_copy() that can reduce the amount of memcpy when
getting data from the adapter. Fixes #388201.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gst/base/gstadapter.c | 52 | ||||
-rw-r--r-- | libs/gst/base/gstadapter.h | 2 |
2 files changed, 54 insertions, 0 deletions
diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c index 36af32cf9..1bd0e526b 100644 --- a/libs/gst/base/gstadapter.c +++ b/libs/gst/base/gstadapter.c @@ -303,6 +303,58 @@ gst_adapter_peek (GstAdapter * adapter, guint size) } /** + * gst_adapter_copy: + * @adapter: a #GstAdapter + * @dest: the memory where to copy to + * @offset: the bytes offset in the adapter to start from + * @size: the number of bytes to copy + * + * Copies @size bytes of data starting at @offset out of the buffers + * contained in @GstAdapter into an array @dest provided by the caller. + * + * The array @dest should be large enough to contain @size bytes. + * The user should check that the adapter has (@offset + @size) bytes + * available before calling this function. + * + * Since: 0.10.12 + */ +void +gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size) +{ + GSList *g; + int skip; + + g_return_if_fail (GST_IS_ADAPTER (adapter)); + g_return_if_fail (size > 0); + + /* we don't have enough data, return. This is unlikely + * as one usually does an _available() first instead of copying a + * random size. */ + if (G_UNLIKELY (offset + size > adapter->size)) + return; + + skip = adapter->skip; + for (g = adapter->buflist; g && size > 0; g = g_slist_next (g)) { + GstBuffer *buf; + + buf = g->data; + if (offset < GST_BUFFER_SIZE (buf) - skip) { + int n; + + n = MIN (GST_BUFFER_SIZE (buf) - skip - offset, size); + memcpy (dest, GST_BUFFER_DATA (buf) + skip + offset, n); + + dest += n; + offset = 0; + size -= n; + } else { + offset -= GST_BUFFER_SIZE (buf) - skip; + } + skip = 0; + } +} + +/** * gst_adapter_flush: * @adapter: a #GstAdapter * @flush: the number of bytes to flush diff --git a/libs/gst/base/gstadapter.h b/libs/gst/base/gstadapter.h index 1ae993b62..3dc52c0e3 100644 --- a/libs/gst/base/gstadapter.h +++ b/libs/gst/base/gstadapter.h @@ -78,6 +78,8 @@ GstAdapter * gst_adapter_new (void); void gst_adapter_clear (GstAdapter *adapter); void gst_adapter_push (GstAdapter *adapter, GstBuffer* buf); const guint8 * gst_adapter_peek (GstAdapter *adapter, guint size); +void gst_adapter_copy (GstAdapter *adapter, guint8 *dest, + guint offset, guint size); 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); |