/* GStreamer Apple Core Video memory
 * Copyright (C) 2015 Ilya Konstantinov
 *
 * 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 mordetails.
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

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

#include "corevideomemory.h"

GST_DEBUG_CATEGORY_STATIC (GST_CAT_APPLE_CORE_VIDEO_MEMORY);
#define GST_CAT_DEFAULT GST_CAT_APPLE_CORE_VIDEO_MEMORY

static const char *_lock_state_names[] = {
  "Unlocked", "Locked Read-Only", "Locked Read-Write"
};

/**
 * gst_apple_core_video_pixel_buffer_new:
 * @buf: an unlocked CVPixelBuffer
 *
 * Initializes a wrapper to manage locking state for a CVPixelBuffer.
 * This function expects to receive unlocked CVPixelBuffer, and further assumes
 * that no one else will lock it (as long as the wrapper exists).
 *
 * This function retains @buf.
 *
 * Returns: The wrapped @buf.
 */
GstAppleCoreVideoPixelBuffer *
gst_apple_core_video_pixel_buffer_new (CVPixelBufferRef buf)
{
  GstAppleCoreVideoPixelBuffer *gpixbuf =
      g_slice_new (GstAppleCoreVideoPixelBuffer);
  gpixbuf->refcount = 1;
  g_mutex_init (&gpixbuf->mutex);
  gpixbuf->buf = CVPixelBufferRetain (buf);
  gpixbuf->lock_state = GST_APPLE_CORE_VIDEO_MEMORY_UNLOCKED;
  gpixbuf->lock_count = 0;
  return gpixbuf;
}

GstAppleCoreVideoPixelBuffer *
gst_apple_core_video_pixel_buffer_ref (GstAppleCoreVideoPixelBuffer * gpixbuf)
{
  g_atomic_int_inc (&gpixbuf->refcount);
  return gpixbuf;
}

void
gst_apple_core_video_pixel_buffer_unref (GstAppleCoreVideoPixelBuffer * gpixbuf)
{
  if (g_atomic_int_dec_and_test (&gpixbuf->refcount)) {
    if (gpixbuf->lock_state != GST_APPLE_CORE_VIDEO_MEMORY_UNLOCKED) {
      GST_ERROR
          ("%p: CVPixelBuffer memory still locked (lock_count = %d), likely forgot to unmap GstAppleCoreVideoMemory",
          gpixbuf, gpixbuf->lock_count);
    }
    CVPixelBufferRelease (gpixbuf->buf);
    g_mutex_clear (&gpixbuf->mutex);
    g_slice_free (GstAppleCoreVideoPixelBuffer, gpixbuf);
  }
}

/**
 * gst_apple_core_video_pixel_buffer_lock:
 * @gpixbuf: the wrapped CVPixelBuffer
 * @flags: mapping flags for either read-only or read-write locking
 *
 * Locks the pixel buffer into CPU memory for reading only, or
 * reading and writing. The desired lock mode is deduced from @flags.
 *
 * For planar buffers, each plane's #GstAppleCoreVideoMemory will reference
 * the same #GstAppleCoreVideoPixelBuffer; therefore this function will be
 * called multiple times for the same @gpixbuf. Each call to this function
 * should be matched by a call to gst_apple_core_video_pixel_buffer_unlock().
 *
 * Notes:
 *
 * - Read-only locking improves performance by preventing Core Video
 *   from invalidating existing caches of the buffer’s contents.
 *
 * - Only the first call actually locks; subsequent calls succeed
 *   as long as their requested flags are compatible with how the buffer
 *   is already locked.
 *
 *   For example, the following code will succeed:
 *   |[<!-- language="C" -->
 *   gst_memory_map(plane1, GST_MAP_READWRITE);
 *   gst_memory_map(plane2, GST_MAP_READ);
 *   ]|
 *   while the ƒollowing code will fail:
 *   |[<!-- language="C" -->
 *   gst_memory_map(plane1, GST_MAP_READ);
 *   gst_memory_map(plane2, GST_MAP_READWRITE); /<!-- -->* ERROR: already locked for read-only *<!-- -->/
 *   ]|
 *
 * Returns: %TRUE if the buffer was locked as requested
 */
static gboolean
gst_apple_core_video_pixel_buffer_lock (GstAppleCoreVideoPixelBuffer * gpixbuf,
    GstMapFlags flags)
{
  CVReturn cvret;
  CVOptionFlags lockFlags;

  g_mutex_lock (&gpixbuf->mutex);

  switch (gpixbuf->lock_state) {
    case GST_APPLE_CORE_VIDEO_MEMORY_UNLOCKED:
      lockFlags = (flags & GST_MAP_WRITE) ? 0 : kCVPixelBufferLock_ReadOnly;
      cvret = CVPixelBufferLockBaseAddress (gpixbuf->buf, lockFlags);
      if (cvret != kCVReturnSuccess) {
        g_mutex_unlock (&gpixbuf->mutex);
        /* TODO: Map kCVReturnError etc. into strings */
        GST_ERROR ("%p: unable to lock base address for pixbuf %p: %d", gpixbuf,
            gpixbuf->buf, cvret);
        return FALSE;
      }
      gpixbuf->lock_state =
          (flags & GST_MAP_WRITE) ?
          GST_APPLE_CORE_VIDEO_MEMORY_LOCKED_READ_WRITE :
          GST_APPLE_CORE_VIDEO_MEMORY_LOCKED_READONLY;
      break;

    case GST_APPLE_CORE_VIDEO_MEMORY_LOCKED_READONLY:
      if (flags & GST_MAP_WRITE) {
        g_mutex_unlock (&gpixbuf->mutex);
        GST_ERROR ("%p: pixel buffer %p already locked for read-only access",
            gpixbuf, gpixbuf->buf);
        return FALSE;
      }
      break;

    case GST_APPLE_CORE_VIDEO_MEMORY_LOCKED_READ_WRITE:
      break;                    /* nothing to do, already most permissive mapping */
  }

  g_atomic_int_inc (&gpixbuf->lock_count);

  g_mutex_unlock (&gpixbuf->mutex);

  GST_DEBUG ("%p: pixbuf %p, %s (%d times)",
      gpixbuf,
      gpixbuf->buf,
      _lock_state_names[gpixbuf->lock_state], gpixbuf->lock_count);

  return TRUE;
}

/**
 * gst_apple_core_video_pixel_buffer_unlock:
 * @gpixbuf: the wrapped CVPixelBuffer
 *
 * Unlocks the pixel buffer from CPU memory. Should be called
 * for every gst_apple_core_video_pixel_buffer_lock() call.
 */
static gboolean
gst_apple_core_video_pixel_buffer_unlock (GstAppleCoreVideoPixelBuffer *
    gpixbuf)
{
  CVOptionFlags lockFlags;
  CVReturn cvret;

  if (gpixbuf->lock_state == GST_APPLE_CORE_VIDEO_MEMORY_UNLOCKED) {
    GST_ERROR ("%p: pixel buffer %p not locked", gpixbuf, gpixbuf->buf);
    return FALSE;
  }

  if (!g_atomic_int_dec_and_test (&gpixbuf->lock_count)) {
    return TRUE;                /* still locked, by current and/or other callers */
  }

  g_mutex_lock (&gpixbuf->mutex);

  lockFlags =
      (gpixbuf->lock_state ==
      GST_APPLE_CORE_VIDEO_MEMORY_LOCKED_READONLY) ? kCVPixelBufferLock_ReadOnly
      : 0;
  cvret = CVPixelBufferUnlockBaseAddress (gpixbuf->buf, lockFlags);
  if (cvret != kCVReturnSuccess) {
    g_mutex_unlock (&gpixbuf->mutex);
    g_atomic_int_inc (&gpixbuf->lock_count);
    /* TODO: Map kCVReturnError etc. into strings */
    GST_ERROR ("%p: unable to unlock base address for pixbuf %p: %d", gpixbuf,
        gpixbuf->buf, cvret);
    return FALSE;
  }

  gpixbuf->lock_state = GST_APPLE_CORE_VIDEO_MEMORY_UNLOCKED;

  g_mutex_unlock (&gpixbuf->mutex);

  GST_DEBUG ("%p: pixbuf %p, %s (%d locks remaining)",
      gpixbuf,
      gpixbuf->buf,
      _lock_state_names[gpixbuf->lock_state], gpixbuf->lock_count);

  return TRUE;
}

/*
 * GstAppleCoreVideoAllocator
 */

struct _GstAppleCoreVideoAllocatorClass
{
  GstAllocatorClass parent_class;
};

typedef struct _GstAppleCoreVideoAllocatorClass GstAppleCoreVideoAllocatorClass;

struct _GstAppleCoreVideoAllocator
{
  GstAllocator parent_instance;
};

typedef struct _GstAppleCoreVideoAllocator GstAppleCoreVideoAllocator;

/* GType for GstAppleCoreVideoAllocator */
GType gst_apple_core_video_allocator_get_type (void);
#define GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR             (gst_apple_core_video_allocator_get_type())
#define GST_IS_APPLE_CORE_VIDEO_ALLOCATOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR))
#define GST_IS_APPLE_CORE_VIDEO_ALLOCATOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR))
#define GST_APPLE_CORE_VIDEO_ALLOCATOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR, GstAppleCoreVideoAllocatorClass))
#define GST_APPLE_CORE_VIDEO_ALLOCATOR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR, GstAppleCoreVideoAllocator))
#define GST_APPLE_CORE_VIDEO_ALLOCATOR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR, GstAppleCoreVideoAllocatorClass))

G_DEFINE_TYPE (GstAppleCoreVideoAllocator, gst_apple_core_video_allocator,
    GST_TYPE_ALLOCATOR);

/* Name for allocator registration */
#define GST_APPLE_CORE_VIDEO_ALLOCATOR_NAME "AppleCoreVideoMemory"

/* Singleton instance of GstAppleCoreVideoAllocator */
static GstAppleCoreVideoAllocator *_apple_core_video_allocator;

/**
 * gst_apple_core_video_memory_init:
 *
 * Initializes the Core Video Memory allocator. This function must be called
 * before #GstAppleCoreVideoMemory can be created.
 *
 * It is safe to call this function multiple times.
 */
void
gst_apple_core_video_memory_init (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (GST_CAT_APPLE_CORE_VIDEO_MEMORY, "corevideomemory",
        0, "Apple Core Video Memory");

    _apple_core_video_allocator =
        g_object_new (GST_TYPE_APPLE_CORE_VIDEO_ALLOCATOR, NULL);
    gst_object_ref_sink (_apple_core_video_allocator);

    gst_allocator_register (GST_APPLE_CORE_VIDEO_ALLOCATOR_NAME,
        gst_object_ref (_apple_core_video_allocator));
    g_once_init_leave (&_init, 1);
  }
}

/**
 * gst_is_apple_core_video_memory:
 * @mem: #GstMemory
 *
 * Checks whether @mem is backed by a CVPixelBuffer.
 * This has limited use since #GstAppleCoreVideoMemory is transparently
 * mapped into CPU memory on request.
 *
 * Returns: %TRUE when @mem is backed by a CVPixelBuffer
 */
gboolean
gst_is_apple_core_video_memory (GstMemory * mem)
{
  g_return_val_if_fail (mem != NULL, FALSE);

  return GST_IS_APPLE_CORE_VIDEO_ALLOCATOR (mem->allocator);
}

/**
 * gst_apple_core_video_memory_new:
 *
 * Helper function for gst_apple_core_video_mem_share().
 * Users should call gst_apple_core_video_memory_new_wrapped() instead.
 */
static GstAppleCoreVideoMemory *
gst_apple_core_video_memory_new (GstMemoryFlags flags, GstMemory * parent,
    GstAppleCoreVideoPixelBuffer * gpixbuf, gsize plane, gsize maxsize,
    gsize align, gsize offset, gsize size)
{
  GstAppleCoreVideoMemory *mem;

  g_return_val_if_fail (gpixbuf != NULL, NULL);

  mem = g_slice_new0 (GstAppleCoreVideoMemory);
  gst_memory_init (GST_MEMORY_CAST (mem), flags,
      GST_ALLOCATOR_CAST (_apple_core_video_allocator), parent, maxsize, align,
      offset, size);

  mem->gpixbuf = gst_apple_core_video_pixel_buffer_ref (gpixbuf);
  mem->plane = plane;

  GST_DEBUG ("%p: gpixbuf %p, plane: %" G_GSSIZE_FORMAT ", size %"
      G_GSIZE_FORMAT, mem, mem->gpixbuf, mem->plane, mem->mem.size);

  return mem;
}

/**
 * gst_apple_core_video_memory_new_wrapped:
 * @gpixbuf: the backing #GstAppleCoreVideoPixelBuffer
 * @plane: the plane this memory will represent, or 0 for non-planar buffer
 * @size: the size of the buffer or specific plane
 *
 * Returns: a newly allocated #GstAppleCoreVideoMemory
 */
GstAppleCoreVideoMemory *
gst_apple_core_video_memory_new_wrapped (GstAppleCoreVideoPixelBuffer * gpixbuf,
    gsize plane, gsize size)
{
  return gst_apple_core_video_memory_new (0, NULL, gpixbuf, plane, size, 0, 0,
      size);
}

static gpointer
gst_apple_core_video_mem_map (GstMemory * gmem, gsize maxsize,
    GstMapFlags flags)
{
  GstAppleCoreVideoMemory *mem = (GstAppleCoreVideoMemory *) gmem;
  gpointer ret;

  if (!gst_apple_core_video_pixel_buffer_lock (mem->gpixbuf, flags))
    return NULL;

  if (CVPixelBufferIsPlanar (mem->gpixbuf->buf)) {
    ret = CVPixelBufferGetBaseAddressOfPlane (mem->gpixbuf->buf, mem->plane);

    if (ret != NULL)
      GST_DEBUG ("%p: pixbuf %p plane %" G_GSIZE_FORMAT
          " flags %08x: mapped %p", mem, mem->gpixbuf->buf, mem->plane, flags,
          ret);
    else
      GST_ERROR ("%p: invalid plane base address (NULL) for pixbuf %p plane %"
          G_GSIZE_FORMAT, mem, mem->gpixbuf->buf, mem->plane);
  } else {
    ret = CVPixelBufferGetBaseAddress (mem->gpixbuf->buf);

    if (ret != NULL)
      GST_DEBUG ("%p: pixbuf %p flags %08x: mapped %p", mem, mem->gpixbuf->buf,
          flags, ret);
    else
      GST_ERROR ("%p: invalid base address (NULL) for pixbuf %p"
          G_GSIZE_FORMAT, mem, mem->gpixbuf->buf);
  }

  return ret;
}

static void
gst_apple_core_video_mem_unmap (GstMemory * gmem)
{
  GstAppleCoreVideoMemory *mem = (GstAppleCoreVideoMemory *) gmem;
  (void) gst_apple_core_video_pixel_buffer_unlock (mem->gpixbuf);
  GST_DEBUG ("%p: pixbuf %p plane %" G_GSIZE_FORMAT, mem,
      mem->gpixbuf->buf, mem->plane);
}

static GstMemory *
gst_apple_core_video_mem_share (GstMemory * gmem, gssize offset, gssize size)
{
  GstAppleCoreVideoMemory *mem;
  GstMemory *parent, *sub;

  mem = (GstAppleCoreVideoMemory *) gmem;

  /* find the real parent */
  parent = gmem->parent;
  if (parent == NULL)
    parent = gmem;

  if (size == -1)
    size = gmem->size - offset;

  /* the shared memory is always readonly */
  sub =
      GST_MEMORY_CAST (gst_apple_core_video_memory_new (GST_MINI_OBJECT_FLAGS
          (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, parent, mem->gpixbuf,
          mem->plane, gmem->maxsize, gmem->align, gmem->offset + offset, size));

  return sub;
}

static gboolean
gst_apple_core_video_mem_is_span (GstMemory * mem1, GstMemory * mem2,
    gsize * offset)
{
  /* We may only return FALSE since:
   * 1) Core Video gives no guarantees about planes being consecutive.
   *    We may only know this after mapping.
   * 2) GstAppleCoreVideoMemory instances for planes do not share a common
   *    parent -- i.e. they're not offsets into the same parent
   *    memory instance.
   *
   * It's not unlikely that planes will be stored in consecutive memory
   * but it should be checked by the user after mapping.
   */
  return FALSE;
}

static void
gst_apple_core_video_mem_free (GstAllocator * allocator, GstMemory * gmem)
{
  GstAppleCoreVideoMemory *mem = (GstAppleCoreVideoMemory *) gmem;

  gst_apple_core_video_pixel_buffer_unref (mem->gpixbuf);

  g_slice_free (GstAppleCoreVideoMemory, mem);
}

static void
gst_apple_core_video_allocator_class_init (GstAppleCoreVideoAllocatorClass *
    klass)
{
  GstAllocatorClass *allocator_class;

  allocator_class = (GstAllocatorClass *) klass;

  /* we don't do allocations, only wrap existing pixel buffers */
  allocator_class->alloc = NULL;
  allocator_class->free = gst_apple_core_video_mem_free;
}

static void
gst_apple_core_video_allocator_init (GstAppleCoreVideoAllocator * allocator)
{
  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);

  alloc->mem_type = GST_APPLE_CORE_VIDEO_ALLOCATOR_NAME;
  alloc->mem_map = gst_apple_core_video_mem_map;
  alloc->mem_unmap = gst_apple_core_video_mem_unmap;
  alloc->mem_share = gst_apple_core_video_mem_share;
  alloc->mem_is_span = gst_apple_core_video_mem_is_span;

  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}
