/**
* SECTION:gstmemory
+ * @title: GstMemory
* @short_description: refcounted wrapper for memory blocks
* @see_also: #GstBuffer
*
allocator = mem->allocator;
gst_allocator_free (allocator, mem);
+
gst_object_unref (allocator);
}
mem->allocator = gst_object_ref (allocator);
if (parent) {
+ /* FIXME 2.0: this can fail if the memory is already write locked */
gst_memory_lock (parent, GST_LOCK_FLAG_EXCLUSIVE);
gst_memory_ref (parent);
}
/**
* gst_memory_get_sizes:
* @mem: a #GstMemory
- * @offset: pointer to offset
- * @maxsize: pointer to maxsize
+ * @offset: (out) (allow-none): pointer to offset
+ * @maxsize: (out) (allow-none): pointer to maxsize
*
* Get the current @size, @offset and @maxsize of @mem.
*
if (!gst_memory_lock (mem, (GstLockFlags) flags))
goto lock_failed;
- info->data = mem->allocator->mem_map (mem, mem->maxsize, flags);
+ info->flags = flags;
+ info->memory = mem;
+ info->size = mem->size;
+ info->maxsize = mem->maxsize - mem->offset;
+
+ if (mem->allocator->mem_map_full)
+ info->data = mem->allocator->mem_map_full (mem, info, mem->maxsize);
+ else
+ info->data = mem->allocator->mem_map (mem, mem->maxsize, flags);
if (G_UNLIKELY (info->data == NULL))
goto error;
- info->memory = mem;
- info->flags = flags;
- info->size = mem->size;
- info->maxsize = mem->maxsize - mem->offset;
info->data = info->data + mem->offset;
return TRUE;
}
error:
{
- /* something went wrong, restore the orginal state again */
- GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: subclass map failed", mem);
+ /* something went wrong, restore the original state again
+ * it is up to the subclass to log an error if needed. */
+ GST_CAT_INFO (GST_CAT_MEMORY, "mem %p: subclass map failed", mem);
gst_memory_unlock (mem, (GstLockFlags) flags);
memset (info, 0, sizeof (GstMapInfo));
return FALSE;
g_return_if_fail (info != NULL);
g_return_if_fail (info->memory == mem);
- mem->allocator->mem_unmap (mem);
+ if (mem->allocator->mem_unmap_full)
+ mem->allocator->mem_unmap_full (mem, info);
+ else
+ mem->allocator->mem_unmap (mem);
gst_memory_unlock (mem, (GstLockFlags) info->flags);
}
g_return_val_if_fail (!GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_NO_SHARE),
NULL);
+ /* whether we can lock the memory exclusively */
+ /* in order to maintain backwards compatibility by not requiring subclasses
+ * to lock the memory themselves and propagate the possible failure in their
+ * mem_share implementation */
+ /* FIXME 2.0: remove and fix gst_memory_init() and/or all memory subclasses
+ * to propagate this failure case */
+ if (!gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE))
+ return NULL;
+
+ /* double lock to ensure we are not mapped writable without an
+ * exclusive lock. */
+ if (!gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE)) {
+ gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
+ return NULL;
+ }
+
shared = mem->allocator->mem_share (mem, offset, size);
+ /* unlocking before calling the subclass would be racy */
+ gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
+ gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
+
return shared;
}
* gst_memory_is_span:
* @mem1: a #GstMemory
* @mem2: a #GstMemory
- * @offset: a pointer to a result offset
+ * @offset: (out): a pointer to a result offset
*
* Check if @mem1 and mem2 share the memory with a common parent memory object
* and that the memory is contiguous.