/* GStreamer
 * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.be>
 *
 * gstmemory.c: memory block handling
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstmemory
 * @title: GstMemory
 * @short_description: refcounted wrapper for memory blocks
 * @see_also: #GstBuffer
 *
 * GstMemory is a lightweight refcounted object that wraps a region of memory.
 * They are typically used to manage the data of a #GstBuffer.
 *
 * A GstMemory object has an allocated region of memory of maxsize. The maximum
 * size does not change during the lifetime of the memory object. The memory
 * also has an offset and size property that specifies the valid range of memory
 * in the allocated region.
 *
 * Memory is usually created by allocators with a gst_allocator_alloc()
 * method call. When %NULL is used as the allocator, the default allocator will
 * be used.
 *
 * New allocators can be registered with gst_allocator_register().
 * Allocators are identified by name and can be retrieved with
 * gst_allocator_find(). gst_allocator_set_default() can be used to change the
 * default allocator.
 *
 * New memory can be created with gst_memory_new_wrapped() that wraps the memory
 * allocated elsewhere.
 *
 * Refcounting of the memory block is performed with gst_memory_ref() and
 * gst_memory_unref().
 *
 * The size of the memory can be retrieved and changed with
 * gst_memory_get_sizes() and gst_memory_resize() respectively.
 *
 * Getting access to the data of the memory is performed with gst_memory_map().
 * The call will return a pointer to offset bytes into the region of memory.
 * After the memory access is completed, gst_memory_unmap() should be called.
 *
 * Memory can be copied with gst_memory_copy(), which will return a writable
 * copy. gst_memory_share() will create a new memory block that shares the
 * memory with an existing memory block at a custom offset and with a custom
 * size.
 *
 * Memory can be efficiently merged when gst_memory_is_span() returns %TRUE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gst_private.h"
#include "gstmemory.h"

GType _gst_memory_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstMemory, gst_memory);

static GstMemory *
_gst_memory_copy (GstMemory * mem)
{
  GST_CAT_DEBUG (GST_CAT_MEMORY, "copy memory %p", mem);
  return gst_memory_copy (mem, 0, -1);
}

static void
_gst_memory_free (GstMemory * mem)
{
  GstAllocator *allocator;

  GST_CAT_DEBUG (GST_CAT_MEMORY, "free memory %p", mem);

  if (mem->parent) {
    gst_memory_unlock (mem->parent, GST_LOCK_FLAG_EXCLUSIVE);
    gst_memory_unref (mem->parent);
  }

  allocator = mem->allocator;

  gst_allocator_free (allocator, mem);
  gst_object_unref (allocator);
}

/**
 * gst_memory_init: (skip)
 * @mem: a #GstMemory
 * @flags: #GstMemoryFlags
 * @allocator: the #GstAllocator
 * @parent: the parent of @mem
 * @maxsize: the total size of the memory
 * @align: the alignment of the memory
 * @offset: The offset in the memory
 * @size: the size of valid data in the memory

 * Initializes a newly allocated @mem with the given parameters. This function
 * will call gst_mini_object_init() with the default memory parameters.
 */
void
gst_memory_init (GstMemory * mem, GstMemoryFlags flags,
    GstAllocator * allocator, GstMemory * parent, gsize maxsize, gsize align,
    gsize offset, gsize size)
{
  gst_mini_object_init (GST_MINI_OBJECT_CAST (mem),
      flags | GST_MINI_OBJECT_FLAG_LOCKABLE, GST_TYPE_MEMORY,
      (GstMiniObjectCopyFunction) _gst_memory_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_memory_free);

  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);
  }
  mem->parent = parent;
  mem->maxsize = maxsize;
  mem->align = align;
  mem->offset = offset;
  mem->size = size;

  GST_CAT_DEBUG (GST_CAT_MEMORY, "new memory %p, maxsize:%" G_GSIZE_FORMAT
      " offset:%" G_GSIZE_FORMAT " size:%" G_GSIZE_FORMAT, mem, maxsize,
      offset, size);
}

/**
 * gst_memory_is_type:
 * @mem: a #GstMemory
 * @mem_type: a memory type
 *
 * Check if @mem if allocated with an allocator for @mem_type.
 *
 * Returns: %TRUE if @mem was allocated from an allocator for @mem_type.
 *
 * Since: 1.2
 */
gboolean
gst_memory_is_type (GstMemory * mem, const gchar * mem_type)
{
  g_return_val_if_fail (mem != NULL, FALSE);
  g_return_val_if_fail (mem->allocator != NULL, FALSE);
  g_return_val_if_fail (mem_type != NULL, FALSE);

  return (g_strcmp0 (mem->allocator->mem_type, mem_type) == 0);
}

/**
 * gst_memory_get_sizes:
 * @mem: a #GstMemory
 * @offset: (out) (allow-none): pointer to offset
 * @maxsize: (out) (allow-none): pointer to maxsize
 *
 * Get the current @size, @offset and @maxsize of @mem.
 *
 * Returns: the current sizes of @mem
 */
gsize
gst_memory_get_sizes (GstMemory * mem, gsize * offset, gsize * maxsize)
{
  g_return_val_if_fail (mem != NULL, 0);

  if (offset)
    *offset = mem->offset;
  if (maxsize)
    *maxsize = mem->maxsize;

  return mem->size;
}

/**
 * gst_memory_resize:
 * @mem: a #GstMemory
 * @offset: a new offset
 * @size: a new size
 *
 * Resize the memory region. @mem should be writable and offset + size should be
 * less than the maxsize of @mem.
 *
 * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED will be
 * cleared when offset or padding is increased respectively.
 */
void
gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
{
  g_return_if_fail (mem != NULL);
  g_return_if_fail (gst_memory_is_writable (mem));
  g_return_if_fail (offset >= 0 || mem->offset >= -offset);
  g_return_if_fail (size + mem->offset + offset <= mem->maxsize);

  /* if we increase the prefix, we can't guarantee it is still 0 filled */
  if ((offset > 0) && GST_MEMORY_IS_ZERO_PREFIXED (mem))
    GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PREFIXED);

  /* if we increase the padding, we can't guarantee it is still 0 filled */
  if ((offset + size < mem->size) && GST_MEMORY_IS_ZERO_PADDED (mem))
    GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PADDED);

  mem->offset += offset;
  mem->size = size;
}

/**
 * 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) (nullable): 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);
    gst_memory_unref (mem);

    if (result == NULL)
      goto cannot_copy;

    if (!gst_memory_map (result, info, flags))
      goto cannot_map;
  }
  return result;

  /* ERRORS */
cannot_copy:
  {
    GST_CAT_DEBUG (GST_CAT_MEMORY, "cannot copy memory %p", mem);
    return NULL;
  }
cannot_map:
  {
    GST_CAT_DEBUG (GST_CAT_MEMORY, "cannot map memory %p with flags %d", mem,
        flags);
    gst_memory_unref (result);
    return NULL;
  }
}

/**
 * gst_memory_map:
 * @mem: a #GstMemory
 * @info: (out): pointer for info
 * @flags: mapping flags
 *
 * Fill @info with the pointer and sizes of the memory in @mem that can be
 * accessed according to @flags.
 *
 * This function can return %FALSE for various reasons:
 * - the memory backed by @mem is not accessible with the given @flags.
 * - the memory was already mapped with a different mapping.
 *
 * @info and its contents remain valid for as long as @mem is valid and
 * until gst_memory_unmap() is called.
 *
 * For each gst_memory_map() call, a corresponding gst_memory_unmap() call
 * should be done.
 *
 * Returns: %TRUE if the map operation was successful.
 */
gboolean
gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
{
  g_return_val_if_fail (mem != NULL, FALSE);
  g_return_val_if_fail (info != NULL, FALSE);

  if (!gst_memory_lock (mem, (GstLockFlags) flags))
    goto lock_failed;

  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->data = info->data + mem->offset;

  return TRUE;

  /* ERRORS */
lock_failed:
  {
    GST_CAT_DEBUG (GST_CAT_MEMORY, "mem %p: lock %d failed", mem, flags);
    memset (info, 0, sizeof (GstMapInfo));
    return FALSE;
  }
error:
  {
    /* something went wrong, restore the orginal 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;
  }
}

/**
 * gst_memory_unmap:
 * @mem: a #GstMemory
 * @info: a #GstMapInfo
 *
 * Release the memory obtained with gst_memory_map()
 */
void
gst_memory_unmap (GstMemory * mem, GstMapInfo * info)
{
  g_return_if_fail (mem != NULL);
  g_return_if_fail (info != NULL);
  g_return_if_fail (info->memory == 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);
}

/**
 * gst_memory_copy:
 * @mem: a #GstMemory
 * @offset: offset to copy from
 * @size: size to copy, or -1 to copy to the end of the memory region
 *
 * Return a copy of @size bytes from @mem starting from @offset. This copy is
 * guaranteed to be writable. @size can be set to -1 to return a copy
 * from @offset to the end of the memory region.
 *
 * Returns: a new #GstMemory.
 */
GstMemory *
gst_memory_copy (GstMemory * mem, gssize offset, gssize size)
{
  GstMemory *copy;

  g_return_val_if_fail (mem != NULL, NULL);

  copy = mem->allocator->mem_copy (mem, offset, size);

  return copy;
}

/**
 * gst_memory_share:
 * @mem: a #GstMemory
 * @offset: offset to share from
 * @size: size to share, or -1 to share to the end of the memory region
 *
 * Return a shared copy of @size bytes from @mem starting from @offset. No
 * memory copy is performed and the memory region is simply shared. The result
 * is guaranteed to be non-writable. @size can be set to -1 to return a shared
 * copy from @offset to the end of the memory region.
 *
 * Returns: a new #GstMemory.
 */
GstMemory *
gst_memory_share (GstMemory * mem, gssize offset, gssize size)
{
  GstMemory *shared;

  g_return_val_if_fail (mem != NULL, NULL);
  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: (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.
 *
 * If this is the case, the memory of @mem1 and @mem2 can be merged
 * efficiently by performing gst_memory_share() on the parent object from
 * the returned @offset.
 *
 * Returns: %TRUE if the memory is contiguous and of a common parent.
 */
gboolean
gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
{
  g_return_val_if_fail (mem1 != NULL, FALSE);
  g_return_val_if_fail (mem2 != NULL, FALSE);

  /* need to have the same allocators */
  if (mem1->allocator != mem2->allocator)
    return FALSE;

  /* need to have the same parent */
  if (mem1->parent == NULL || mem1->parent != mem2->parent)
    return FALSE;

  /* and memory is contiguous */
  if (!mem1->allocator->mem_is_span (mem1, mem2, offset))
    return FALSE;

  return TRUE;
}

void
_priv_gst_memory_initialize (void)
{
  _gst_memory_type = gst_memory_get_type ();
}
