From 93074b899c3a24101de2ff5b928cf8ae782c874b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 20 Jan 2012 14:56:49 +0100 Subject: [PATCH] memory: add method to create mapped memory Add a method to create a GstMemory with the desired mapping. Makes a copy of the memory if it is currently in use. --- gst/gstbuffer.c | 18 +++----------- gst/gstmemory.c | 47 +++++++++++++++++++++++++++++++++++ gst/gstmemory.h | 1 + win32/common/libgstreamer.def | 1 + 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 6e87079486..fdfd6a43d8 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -963,23 +963,13 @@ gst_buffer_map (GstBuffer * buffer, GstMapInfo * info, GstMapFlags flags) goto not_writable; mem = gst_buffer_get_merged_memory (buffer); - if (mem == NULL) + if (G_UNLIKELY (mem == NULL)) goto no_memory; /* now try to map */ - if (!gst_memory_map (mem, info, flags) && write) { - GstMemory *copy; - /* make a (writable) copy */ - copy = gst_memory_copy (mem, 0, -1); - gst_memory_unref (mem); - mem = copy; - if (G_UNLIKELY (mem == NULL)) - goto cannot_map; - - /* try again */ - if (!gst_memory_map (mem, info, flags)) - goto cannot_map; - } + mem = gst_memory_make_mapped (mem, info, flags); + if (G_UNLIKELY (mem == NULL)) + goto cannot_map; /* if the buffer is writable, replace the memory */ if (writable) diff --git a/gst/gstmemory.c b/gst/gstmemory.c index 41e88b6e41..b72b6fcc00 100644 --- a/gst/gstmemory.c +++ b/gst/gstmemory.c @@ -499,6 +499,53 @@ gst_memory_unlock (GstMemory * mem) } while (!g_atomic_int_compare_and_exchange (&mem->state, state, newstate)); } + +/** + * gst_memory_make_mapped: + * @mem: (transfer full): a #GstMemory + * @info: (out): pointer for info + * @flags: mapping flags + * + * Create a #GstMemory object that is mapped with @flags. If @mem is mappable + * with @flags, this function returns the mapped @mem directly. Otherwise a + * mapped copy of @mem is returned. + * + * This function takes ownership of old @mem and returns a reference to a new + * #GstMemory. + * + * Returns: (transfer full): a #GstMemory object mapped with @flags or NULL when + * a mapping is not possible. + */ +GstMemory * +gst_memory_make_mapped (GstMemory * mem, GstMapInfo * info, GstMapFlags flags) +{ + GstMemory *result; + + if (gst_memory_map (mem, info, flags)) { + result = mem; + } else { + result = gst_memory_copy (mem, 0, -1); + if (result == NULL) + goto cannot_copy; + + if (!gst_memory_map (result, info, flags)) + goto cannot_map; + } + return result; + + /* ERRORS */ +cannot_copy: + { + GST_DEBUG ("cannot copy memory %p", mem); + return NULL; + } +cannot_map: + { + GST_DEBUG ("cannot map memory %p with flags %d", mem, flags); + return NULL; + } +} + /** * gst_memory_map: * @mem: a #GstMemory diff --git a/gst/gstmemory.h b/gst/gstmemory.h index 3013d6dfac..6231f74180 100644 --- a/gst/gstmemory.h +++ b/gst/gstmemory.h @@ -277,6 +277,7 @@ void gst_memory_resize (GstMemory *mem, gssize offset, gsize size); /* retrieving data */ gboolean gst_memory_is_writable (GstMemory *mem); +GstMemory * gst_memory_make_mapped (GstMemory *mem, GstMapInfo *info, GstMapFlags flags); gboolean gst_memory_map (GstMemory *mem, GstMapInfo *info, GstMapFlags flags); void gst_memory_unmap (GstMemory *mem, GstMapInfo *info); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index e2ae9028e2..76e80007ce 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -510,6 +510,7 @@ EXPORTS gst_memory_get_type gst_memory_is_span gst_memory_is_writable + gst_memory_make_mapped gst_memory_map gst_memory_new_wrapped gst_memory_ref