buffer: make function to find memory in a buffer
authorWim Taymans <wim.taymans@collabora.co.uk>
Sun, 1 Apr 2012 09:42:52 +0000 (11:42 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Sun, 1 Apr 2012 10:02:40 +0000 (12:02 +0200)
Make a function to find the memory blocks for a region in a buffer.

docs/gst/gstreamer-sections.txt
gst/gstbuffer.c
gst/gstbuffer.h
tests/check/gst/gstbuffer.c
win32/common/libgstreamer.def

index 55eaf92..3ec4319 100644 (file)
@@ -196,6 +196,7 @@ gst_buffer_insert_memory
 gst_buffer_replace_memory_range
 gst_buffer_get_memory_range
 gst_buffer_remove_memory_range
+gst_buffer_find_memory
 
 gst_buffer_prepend_memory
 gst_buffer_append_memory
index 43a02c6..2612419 100644 (file)
@@ -899,6 +899,79 @@ gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, gint length)
 }
 
 /**
+ * gst_buffer_find_memory:
+ * @buffer: a #GstBuffer.
+ * @offset: an offset
+ * @size: a size
+ * @idx: (out): pointer to index
+ * @length: (out): pointer to length
+ * @skip: (out): pointer to skip
+ *
+ * Find the memory blocks that span @size bytes starting from @offset
+ * in @buffer.
+ *
+ * When this function returns %TRUE, @idx will contain the index of the first
+ * memory bock where the byte for @offset can be found and @length contains the
+ * number of memory blocks containing the @size remaining bytes. @skip contains
+ * the number of bytes to skip in the memory bock at @idx to get to the byte
+ * for @offset.
+ *
+ * @size can be -1 to get all the memory blocks after @idx.
+ *
+ * Returns: %TRUE when @size bytes starting from @offset could be found in
+ * @buffer and @idx, @length and @skip will be filled.
+ */
+gboolean
+gst_buffer_find_memory (GstBuffer * buffer, gsize offset, gsize size,
+    guint * idx, guint * length, gsize * skip)
+{
+  guint i, len, found;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (idx != NULL, FALSE);
+  g_return_val_if_fail (length != NULL, FALSE);
+  g_return_val_if_fail (skip != NULL, FALSE);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  found = 0;
+  for (i = 0; i < len; i++) {
+    GstMemory *mem;
+    gsize s;
+
+    mem = GST_BUFFER_MEM_PTR (buffer, i);
+    s = gst_memory_get_sizes (mem, NULL, NULL);
+
+    if (s <= offset) {
+      /* block before offset, or empty block, skip */
+      offset -= s;
+    } else {
+      /* block after offset */
+      if (found == 0) {
+        /* first block, remember index and offset */
+        *idx = i;
+        *skip = offset;
+        if (size == -1) {
+          /* return remaining blocks */
+          *length = len - i;
+          return TRUE;
+        }
+        s -= offset;
+        offset = 0;
+      }
+      /* count the amount of found bytes */
+      found += s;
+      if (found >= size) {
+        /* we have enough bytes */
+        *length = i - *idx + 1;
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+/**
  * gst_buffer_get_sizes:
  * @buffer: a #GstBuffer.
  * @offset: a pointer to the offset
index cc8200a..38d6051 100644 (file)
@@ -289,6 +289,9 @@ void        gst_buffer_remove_memory_range  (GstBuffer *buffer, guint idx, gint
 #define     gst_buffer_remove_memory(b,i)      gst_buffer_remove_memory_range ((b), (i), 1)
 #define     gst_buffer_remove_all_memory(b)    gst_buffer_remove_memory_range ((b), 0, -1)
 
+gboolean    gst_buffer_find_memory         (GstBuffer *buffer, gsize offset, gsize size,
+                                            guint *idx, guint *length, gsize *skip);
+
 gsize       gst_buffer_fill                (GstBuffer *buffer, gsize offset,
                                             gconstpointer src, gsize size);
 gsize       gst_buffer_extract             (GstBuffer *buffer, gsize offset,
index 5e3496c..1344e13 100644 (file)
@@ -603,6 +603,89 @@ GST_START_TEST (test_map)
 
 GST_END_TEST;
 
+GST_START_TEST (test_find)
+{
+  GstBuffer *buf;
+  gsize maxalloc;
+  gsize size, offset;
+  guint idx, length;
+
+  buf = gst_buffer_new ();
+  gst_buffer_append_memory (buf, gst_allocator_alloc (NULL, 0, NULL));
+  gst_buffer_append_memory (buf, gst_allocator_alloc (NULL, 10, NULL));
+  gst_buffer_append_memory (buf, gst_allocator_alloc (NULL, 15, NULL));
+  gst_buffer_append_memory (buf, gst_allocator_alloc (NULL, 0, NULL));
+
+  size = gst_buffer_get_sizes (buf, &offset, &maxalloc);
+  fail_unless (size == 25);
+  fail_unless (offset >= 0);
+  fail_unless (maxalloc >= 25);
+  fail_unless (gst_buffer_n_memory (buf) == 4);
+
+  fail_unless (gst_buffer_find_memory (buf, 0, 5, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 1);
+  fail_unless (offset == 0);
+
+  fail_unless (gst_buffer_find_memory (buf, 0, 10, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 1);
+  fail_unless (offset == 0);
+
+  fail_unless (gst_buffer_find_memory (buf, 5, 4, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 1);
+  fail_unless (offset == 5);
+
+  fail_unless (gst_buffer_find_memory (buf, 5, 5, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 1);
+  fail_unless (offset == 5);
+
+  fail_unless (gst_buffer_find_memory (buf, 5, 6, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 2);
+  fail_unless (offset == 5);
+
+  fail_unless (gst_buffer_find_memory (buf, 10, 6, &idx, &length, &offset));
+  fail_unless (idx == 2);
+  fail_unless (length == 1);
+  fail_unless (offset == 0);
+
+  fail_unless (gst_buffer_find_memory (buf, 10, 15, &idx, &length, &offset));
+  fail_unless (idx == 2);
+  fail_unless (length == 1);
+  fail_unless (offset == 0);
+
+  fail_unless (gst_buffer_find_memory (buf, 11, 14, &idx, &length, &offset));
+  fail_unless (idx == 2);
+  fail_unless (length == 1);
+  fail_unless (offset == 1);
+
+  fail_unless (gst_buffer_find_memory (buf, 0, 25, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 2);
+  fail_unless (offset == 0);
+
+  fail_unless (gst_buffer_find_memory (buf, 24, 0, &idx, &length, &offset));
+  fail_unless (idx == 2);
+  fail_unless (length == 1);
+  fail_unless (offset == 14);
+
+  fail_if (gst_buffer_find_memory (buf, 11, 15, &idx, &length, &offset));
+  fail_if (gst_buffer_find_memory (buf, 0, 26, &idx, &length, &offset));
+  fail_if (gst_buffer_find_memory (buf, 25, 0, &idx, &length, &offset));
+
+  fail_unless (gst_buffer_find_memory (buf, 1, -1, &idx, &length, &offset));
+  fail_unless (idx == 1);
+  fail_unless (length == 3);
+  fail_unless (offset == 1);
+
+  gst_buffer_unref (buf);
+}
+
+GST_END_TEST;
+
 
 static Suite *
 gst_buffer_suite (void)
@@ -621,6 +704,7 @@ gst_buffer_suite (void)
   tcase_add_test (tc_chain, test_size);
   tcase_add_test (tc_chain, test_resize);
   tcase_add_test (tc_chain, test_map);
+  tcase_add_test (tc_chain, test_find);
 
   return s;
 }
index eabffe0..947a949 100644 (file)
@@ -96,6 +96,7 @@ EXPORTS
        gst_buffer_copy_region
        gst_buffer_extract
        gst_buffer_fill
+       gst_buffer_find_memory
        gst_buffer_flags_get_type
        gst_buffer_foreach_meta
        gst_buffer_get_memory_range