summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2007-01-25 10:50:03 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-01-25 10:50:03 +0000
commit8be291377174d3e9ca6b171971ae8886e0a71a14 (patch)
tree8a2b3abb3e92313052742afc026fcb36e32549c4 /libs
parent00a8f6ac84924943c5162c248806d8edededc914 (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.c52
-rw-r--r--libs/gst/base/gstadapter.h2
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);