GstBuffer: Inline fast-path for merged memory
authorEdward Hervey <edward@centricular.com>
Wed, 21 Nov 2018 15:13:48 +0000 (16:13 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 27 Nov 2019 14:25:19 +0000 (14:25 +0000)
gst/gstbuffer.c

index dae87e4fbd68d0c79430e1cd2ad69659b78b9a3f..00ab8577a111bc6431db733318c3dd8dbdd66afe 100644 (file)
@@ -234,72 +234,79 @@ _is_span (GstMemory ** mem, gsize len, gsize * poffset, GstMemory ** parent)
 }
 
 static GstMemory *
-_get_merged_memory (GstBuffer * buffer, guint idx, guint length)
+_actual_merged_memory (GstBuffer * buffer, guint idx, guint length)
 {
   GstMemory **mem, *result = NULL;
-
-  GST_CAT_LOG (GST_CAT_BUFFER, "buffer %p, idx %u, length %u", buffer, idx,
-      length);
+  GstMemory *parent = NULL;
+  gsize size, poffset = 0;
 
   mem = GST_BUFFER_MEM_ARRAY (buffer);
 
-  if (G_UNLIKELY (length == 0)) {
-    result = NULL;
-  } else if (G_LIKELY (length == 1)) {
-    result = gst_memory_ref (mem[idx]);
+  size = gst_buffer_get_sizes_range (buffer, idx, length, NULL, NULL);
+
+  if (G_UNLIKELY (_is_span (mem + idx, length, &poffset, &parent))) {
+    if (!GST_MEMORY_IS_NO_SHARE (parent))
+      result = gst_memory_share (parent, poffset, size);
+    if (!result) {
+      GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy for merge %p", parent);
+      result = gst_memory_copy (parent, poffset, size);
+    }
   } else {
-    GstMemory *parent = NULL;
-    gsize size, poffset = 0;
+    gsize i, tocopy, left;
+    GstMapInfo sinfo, dinfo;
+    guint8 *ptr;
+
+    result = gst_allocator_alloc (NULL, size, NULL);
+    if (result == NULL || !gst_memory_map (result, &dinfo, GST_MAP_WRITE)) {
+      GST_CAT_ERROR (GST_CAT_BUFFER, "Failed to map memory writable");
+      if (result)
+        gst_memory_unref (result);
+      return NULL;
+    }
 
-    size = gst_buffer_get_sizes_range (buffer, idx, length, NULL, NULL);
+    ptr = dinfo.data;
+    left = size;
 
-    if (G_UNLIKELY (_is_span (mem + idx, length, &poffset, &parent))) {
-      if (!GST_MEMORY_IS_NO_SHARE (parent))
-        result = gst_memory_share (parent, poffset, size);
-      if (!result) {
-        GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy for merge %p", parent);
-        result = gst_memory_copy (parent, poffset, size);
-      }
-    } else {
-      gsize i, tocopy, left;
-      GstMapInfo sinfo, dinfo;
-      guint8 *ptr;
-
-      result = gst_allocator_alloc (NULL, size, NULL);
-      if (result == NULL || !gst_memory_map (result, &dinfo, GST_MAP_WRITE)) {
-        GST_CAT_ERROR (GST_CAT_BUFFER, "Failed to map memory writable");
-        if (result)
-          gst_memory_unref (result);
+    for (i = idx; i < (idx + length) && left > 0; i++) {
+      if (!gst_memory_map (mem[i], &sinfo, GST_MAP_READ)) {
+        GST_CAT_ERROR (GST_CAT_BUFFER,
+            "buffer %p, idx %u, length %u failed to map readable", buffer,
+            idx, length);
+        gst_memory_unmap (result, &dinfo);
+        gst_memory_unref (result);
         return NULL;
       }
-
-      ptr = dinfo.data;
-      left = size;
-
-      for (i = idx; i < (idx + length) && left > 0; i++) {
-        if (!gst_memory_map (mem[i], &sinfo, GST_MAP_READ)) {
-          GST_CAT_ERROR (GST_CAT_BUFFER,
-              "buffer %p, idx %u, length %u failed to map readable", buffer,
-              idx, length);
-          gst_memory_unmap (result, &dinfo);
-          gst_memory_unref (result);
-          return NULL;
-        }
-        tocopy = MIN (sinfo.size, left);
-        GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
-            "memcpy %" G_GSIZE_FORMAT " bytes for merge %p from memory %p",
-            tocopy, result, mem[i]);
-        memcpy (ptr, (guint8 *) sinfo.data, tocopy);
-        left -= tocopy;
-        ptr += tocopy;
-        gst_memory_unmap (mem[i], &sinfo);
-      }
-      gst_memory_unmap (result, &dinfo);
+      tocopy = MIN (sinfo.size, left);
+      GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
+          "memcpy %" G_GSIZE_FORMAT " bytes for merge %p from memory %p",
+          tocopy, result, mem[i]);
+      memcpy (ptr, (guint8 *) sinfo.data, tocopy);
+      left -= tocopy;
+      ptr += tocopy;
+      gst_memory_unmap (mem[i], &sinfo);
     }
+    gst_memory_unmap (result, &dinfo);
   }
+
   return result;
 }
 
+static inline GstMemory *
+_get_merged_memory (GstBuffer * buffer, guint idx, guint length)
+{
+  GST_CAT_LOG (GST_CAT_BUFFER, "buffer %p, idx %u, length %u", buffer, idx,
+      length);
+
+  if (G_UNLIKELY (length == 0))
+    return NULL;
+
+  if (G_LIKELY (length == 1))
+    return gst_memory_ref (GST_BUFFER_MEM_PTR (buffer, idx));
+
+  return _actual_merged_memory (buffer, idx, length);
+}
+
+
 static void
 _replace_memory (GstBuffer * buffer, guint len, guint idx, guint length,
     GstMemory * mem)