/*
 * GStreamer
 * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
 * Copyright (C) 2013 Matthew Waters <ystreet00@gmail.com>
 *
 * 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:gstgldisplay
 * @short_description: window system display connection abstraction
 * @title: GstGLDisplay
 * @see_also: #GstContext, #GstGLContext, #GstGLWindow
 *
 * #GstGLDisplay represents a connection to the underlying windowing system.
 * Elements are required to make use of #GstContext to share and propogate
 * a #GstGLDisplay.
 *
 * There are a number of environment variables that influence the choice of
 * platform and window system specific functionality.
 * - GST_GL_WINDOW influences the window system to use.  Common values are
 *   'x11', 'wayland', 'win32' or 'cocoa'.
 * - GST_GL_PLATFORM influences the OpenGL platform to use.  Common values are
 *   'egl', 'glx', 'wgl' or 'cgl'.
 * - GST_GL_API influences the OpenGL API requested by the OpenGL platform.
 *   Common values are 'opengl', 'opengl3' and 'gles2'.
 *
 * > Certain window systems require a special function to be called to
 * > initialize threading support.  As this GStreamer GL library does not preclude
 * > concurrent access to the windowing system, it is strongly advised that
 * > applications ensure that threading support has been initialized before any
 * > other toolkit/library functionality is accessed.  Failure to do so could
 * > result in sudden application abortion during execution.  The most notably
 * > example of such a function is X11's XInitThreads\().
 */

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

#include "gl.h"
#include "gstgldisplay.h"

#if GST_GL_HAVE_WINDOW_COCOA
#include <gst/gl/cocoa/gstgldisplay_cocoa.h>
#endif
#if GST_GL_HAVE_WINDOW_X11
#include <gst/gl/x11/gstgldisplay_x11.h>
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
#include <gst/gl/wayland/gstgldisplay_wayland.h>
#endif
#if GST_GL_HAVE_PLATFORM_EGL
#include <gst/gl/egl/gstgldisplay_egl.h>
#include <gst/gl/egl/gsteglimage.h>
#include <gst/gl/egl/gstglmemoryegl.h>
#endif
#if GST_GL_HAVE_WINDOW_VIV_FB
#include <gst/gl/viv-fb/gstgldisplay_viv_fb.h>
#endif

GST_DEBUG_CATEGORY_STATIC (gst_context);
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0, "opengl display"); \
  GST_DEBUG_CATEGORY_GET (gst_context, "GST_CONTEXT");

G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, GST_TYPE_OBJECT,
    DEBUG_INIT);

#define GST_GL_DISPLAY_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_DISPLAY, GstGLDisplayPrivate))

enum
{
  SIGNAL_0,
  CREATE_CONTEXT,
  LAST_SIGNAL
};

static guint gst_gl_display_signals[LAST_SIGNAL] = { 0 };


static void gst_gl_display_dispose (GObject * object);
static void gst_gl_display_finalize (GObject * object);
static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);
static GstGLWindow *gst_gl_display_default_create_window (GstGLDisplay *
    display);

struct _GstGLDisplayPrivate
{
  GstGLAPI gl_api;

  GList *contexts;

  GThread *event_thread;

  GMutex thread_lock;
  GCond thread_cond;
};

static gboolean
_unlock_main_thread (GstGLDisplay * display)
{
  g_mutex_unlock (&display->priv->thread_lock);

  return G_SOURCE_REMOVE;
}

static gpointer
_event_thread_main (GstGLDisplay * display)
{
  g_mutex_lock (&display->priv->thread_lock);

  display->main_context = g_main_context_new ();
  display->main_loop = g_main_loop_new (display->main_context, FALSE);

  g_main_context_invoke (display->main_context,
      (GSourceFunc) _unlock_main_thread, display);

  g_cond_broadcast (&display->priv->thread_cond);

  g_main_loop_run (display->main_loop);

  g_mutex_lock (&display->priv->thread_lock);
  g_main_loop_unref (display->main_loop);
  g_main_context_unref (display->main_context);

  display->main_loop = NULL;
  display->main_context = NULL;

  g_cond_broadcast (&display->priv->thread_cond);
  g_mutex_unlock (&display->priv->thread_lock);

  return NULL;
}

static void
gst_gl_display_class_init (GstGLDisplayClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));

  /**
   * GstGLDisplay::create-context:
   * @object: the #GstGLDisplay
   * @context: (transfer none): other context to share resources with.
   *
   * Overrides the @GstGLContext creation mechanism.
   * It can be called in any thread and it is emitted with
   * display's object lock held.
   *
   * Returns: (transfer full): the new context.
   */
  gst_gl_display_signals[CREATE_CONTEXT] =
      g_signal_new ("create-context", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_GL_CONTEXT, 1, GST_TYPE_GL_CONTEXT);

  klass->get_handle = gst_gl_display_default_get_handle;
  klass->create_window = gst_gl_display_default_create_window;

  G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
  G_OBJECT_CLASS (klass)->dispose = gst_gl_display_dispose;
}

static void
gst_gl_display_init (GstGLDisplay * display)
{
  display->priv = GST_GL_DISPLAY_GET_PRIVATE (display);

  display->type = GST_GL_DISPLAY_TYPE_ANY;
  display->priv->gl_api = GST_GL_API_ANY;

  g_mutex_init (&display->priv->thread_lock);
  g_cond_init (&display->priv->thread_cond);

  display->priv->event_thread = g_thread_new ("gldisplay-event",
      (GThreadFunc) _event_thread_main, display);

  g_mutex_lock (&display->priv->thread_lock);
  while (!display->main_loop)
    g_cond_wait (&display->priv->thread_cond, &display->priv->thread_lock);
  g_mutex_unlock (&display->priv->thread_lock);

  GST_TRACE ("init %p", display);

  gst_gl_buffer_init_once ();
  gst_gl_memory_pbo_init_once ();
  gst_gl_renderbuffer_init_once ();

#if GST_GL_HAVE_PLATFORM_EGL
  gst_gl_memory_egl_init_once ();
#endif
}

static void
gst_gl_display_dispose (GObject * object)
{
  GstGLDisplay *display = GST_GL_DISPLAY (object);

  if (display->main_loop)
    g_main_loop_quit (display->main_loop);

  if (display->priv->event_thread) {
    /* can't use g_thread_join() as we could lose the last ref from a user
     * function */
    g_mutex_lock (&display->priv->thread_lock);
    while (display->main_loop)
      g_cond_wait (&display->priv->thread_cond, &display->priv->thread_lock);
    g_mutex_unlock (&display->priv->thread_lock);
    g_thread_unref (display->priv->event_thread);
  }
  display->priv->event_thread = NULL;

  if (display->event_source) {
    g_source_destroy (display->event_source);
    g_source_unref (display->event_source);
  }
  display->event_source = NULL;

  G_OBJECT_CLASS (gst_gl_display_parent_class)->dispose (object);
}

static void
gst_gl_display_finalize (GObject * object)
{
  GstGLDisplay *display = GST_GL_DISPLAY (object);
  GList *l;

  GST_TRACE_OBJECT (object, "finalizing");

  for (l = display->priv->contexts; l; l = l->next) {
    g_weak_ref_clear ((GWeakRef *) l->data);
    g_free (l->data);
  }

  g_list_free (display->windows);
  g_list_free (display->priv->contexts);

  g_cond_clear (&display->priv->thread_cond);
  g_mutex_clear (&display->priv->thread_lock);

  G_OBJECT_CLASS (gst_gl_display_parent_class)->finalize (object);
}

/**
 * gst_gl_display_new:
 *
 * Returns: (transfer full): a new #GstGLDisplay
 *
 * Since: 1.4
 */
GstGLDisplay *
gst_gl_display_new (void)
{
  GstGLDisplay *display = NULL;
  const gchar *user_choice, *platform_choice;
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0,
        "gldisplay element");
    g_once_init_leave (&_init, 1);
  }

  user_choice = g_getenv ("GST_GL_WINDOW");
  platform_choice = g_getenv ("GST_GL_PLATFORM");
  GST_INFO ("creating a display, user choice:%s (platform: %s)",
      GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));

#if GST_GL_HAVE_WINDOW_COCOA
  if (!display && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) {
    display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
    if (!display)
      return NULL;
  }
#endif
#if GST_GL_HAVE_WINDOW_WAYLAND
  if (!display && (!user_choice || g_strstr_len (user_choice, 7, "wayland")))
    display = GST_GL_DISPLAY (gst_gl_display_wayland_new (NULL));
#endif
#if GST_GL_HAVE_WINDOW_X11
  if (!display && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
    display = GST_GL_DISPLAY (gst_gl_display_x11_new (NULL));
#endif
#if GST_GL_HAVE_WINDOW_VIV_FB
  if (!display && (!user_choice || g_strstr_len (user_choice, 6, "viv-fb"))) {
    const gchar *disp_idx_str = NULL;
    gint disp_idx = 0;
    disp_idx_str = g_getenv ("GST_GL_VIV_FB");
    if (disp_idx_str) {
      gint64 v = g_ascii_strtoll (disp_idx_str, NULL, 10);
      if (v >= G_MININT && v <= G_MAXINT)
        disp_idx = v;
    }
    display = GST_GL_DISPLAY (gst_gl_display_viv_fb_new (disp_idx));
  }
#endif
#if GST_GL_HAVE_PLATFORM_EGL
  if (!display && (!platform_choice
          || g_strstr_len (platform_choice, 3, "egl")))
    display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
#endif
  if (!display) {
    GST_INFO ("Could not create platform/winsys display. user specified %s "
        "(platform: %s), creating dummy",
        GST_STR_NULL (user_choice), GST_STR_NULL (platform_choice));

    display = g_object_new (GST_TYPE_GL_DISPLAY, NULL);
    gst_object_ref_sink (display);
  }

  return display;
}

/**
 * gst_gl_display_get_handle:
 * @display: a #GstGLDisplay
 *
 * Returns: the native handle for the display
 *
 * Since: 1.4
 */
guintptr
gst_gl_display_get_handle (GstGLDisplay * display)
{
  GstGLDisplayClass *klass;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), 0);
  klass = GST_GL_DISPLAY_GET_CLASS (display);
  g_return_val_if_fail (klass->get_handle != NULL, 0);

  return klass->get_handle (display);
}

static guintptr
gst_gl_display_default_get_handle (GstGLDisplay * display)
{
  return 0;
}

/**
 * gst_gl_display_filter_gl_api:
 * @display: a #GstGLDisplay
 * @gl_api: a #GstGLAPI to filter with
 *
 * limit the use of OpenGL to the requested @gl_api.  This is intended to allow
 * application and elements to request a specific set of OpenGL API's based on
 * what they support.  See gst_gl_context_get_gl_api() for the retreiving the
 * API supported by a #GstGLContext.
 */
void
gst_gl_display_filter_gl_api (GstGLDisplay * display, GstGLAPI gl_api)
{
  gchar *gl_api_s;

  g_return_if_fail (GST_IS_GL_DISPLAY (display));

  gl_api_s = gst_gl_api_to_string (gl_api);
  GST_TRACE_OBJECT (display, "filtering with api %s", gl_api_s);
  g_free (gl_api_s);

  GST_OBJECT_LOCK (display);
  display->priv->gl_api &= gl_api;
  GST_OBJECT_UNLOCK (display);
}

GstGLAPI
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
{
  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);

  return display->priv->gl_api;
}

/**
 * gst_gl_display_get_gl_api:
 * @display: a #GstGLDisplay
 *
 * see gst_gl_display_filter_gl_api() for what the returned value represents
 *
 * Returns: the #GstGLAPI configured for @display
 */
GstGLAPI
gst_gl_display_get_gl_api (GstGLDisplay * display)
{
  GstGLAPI ret;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);

  GST_OBJECT_LOCK (display);
  ret = display->priv->gl_api;
  GST_OBJECT_UNLOCK (display);

  return ret;
}

/**
 * gst_gl_display_get_handle_type:
 * @display: a #GstGLDisplay
 *
 * Returns: the #GstGLDisplayType of @display
 *
 * Since: 1.4
 */
GstGLDisplayType
gst_gl_display_get_handle_type (GstGLDisplay * display)
{
  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_DISPLAY_TYPE_NONE);

  return display->type;
}

/**
 * gst_context_set_gl_display:
 * @context: a #GstContext
 * @display: (transfer none): resulting #GstGLDisplay
 *
 * Sets @display on @context
 *
 * Since: 1.4
 */
void
gst_context_set_gl_display (GstContext * context, GstGLDisplay * display)
{
  GstStructure *s;

  g_return_if_fail (context != NULL);

  if (display)
    GST_CAT_LOG (gst_context,
        "setting GstGLDisplay(%" GST_PTR_FORMAT ") on context(%" GST_PTR_FORMAT
        ")", display, context);

  s = gst_context_writable_structure (context);
  gst_structure_set (s, GST_GL_DISPLAY_CONTEXT_TYPE, GST_TYPE_GL_DISPLAY,
      display, NULL);
}

/**
 * gst_context_get_gl_display:
 * @context: a #GstContext
 * @display: (transfer full): resulting #GstGLDisplay
 *
 * Returns: Whether @display was in @context
 *
 * Since: 1.4
 */
gboolean
gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display)
{
  const GstStructure *s;
  gboolean ret;

  g_return_val_if_fail (display != NULL, FALSE);
  g_return_val_if_fail (context != NULL, FALSE);

  s = gst_context_get_structure (context);
  ret = gst_structure_get (s, GST_GL_DISPLAY_CONTEXT_TYPE,
      GST_TYPE_GL_DISPLAY, display, NULL);

  GST_CAT_LOG (gst_context, "got GstGLDisplay(%p) from context(%p)", *display,
      context);

  return ret;
}

/**
 * gst_gl_display_create_context:
 * @display: a #GstGLDisplay
 * @other_context: (transfer none): other #GstGLContext to share resources with.
 * @p_context: (transfer full) (out): resulting #GstGLContext
 * @error: (allow-none): resulting #GError
 *
 * It requires the display's object lock to be held.
 *
 * Returns: whether a new context could be created.
 *
 * Since: 1.6
 */
gboolean
gst_gl_display_create_context (GstGLDisplay * display,
    GstGLContext * other_context, GstGLContext ** p_context, GError ** error)
{
  GstGLContext *context = NULL;
  gboolean ret = FALSE;

  g_return_val_if_fail (display != NULL, FALSE);
  g_return_val_if_fail (p_context != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  g_signal_emit (display, gst_gl_display_signals[CREATE_CONTEXT], 0,
      other_context, &context);

  if (context) {
    *p_context = context;
    return TRUE;
  }

  context = gst_gl_context_new (display);
  if (!context) {
    g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
        "Failed to create GL context");
    return FALSE;
  }

  GST_DEBUG_OBJECT (display,
      "creating context %" GST_PTR_FORMAT " from other context %"
      GST_PTR_FORMAT, context, other_context);

  ret = gst_gl_context_create (context, other_context, error);

  if (ret)
    *p_context = context;

  return ret;
}

/**
 * gst_gl_display_create_window:
 * @display: a #GstGLDisplay
 *
 * It requires the display's object lock to be held.
 *
 * Returns: (transfer full): a new #GstGLWindow for @display or %NULL.
 */
GstGLWindow *
gst_gl_display_create_window (GstGLDisplay * display)
{
  GstGLDisplayClass *klass;
  GstGLWindow *window;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
  klass = GST_GL_DISPLAY_GET_CLASS (display);
  g_return_val_if_fail (klass->create_window != NULL, NULL);

  window = klass->create_window (display);

  if (window)
    display->windows = g_list_prepend (display->windows, window);

  return window;
}

static GstGLWindow *
gst_gl_display_default_create_window (GstGLDisplay * display)
{
  return gst_gl_window_new (display);
}

/**
 * gst_gl_display_remove_window:
 * @display: a #GstGLDisplay
 * @window: a #GstGLWindow to remove
 *
 * Returns: if @window could be removed from @display
 *
 * Since: 1.12
 */
gboolean
gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window)
{
  gboolean ret = FALSE;
  GList *l;

  GST_OBJECT_LOCK (display);
  l = g_list_find (display->windows, window);
  if (l) {
    display->windows = g_list_delete_link (display->windows, l);
    ret = TRUE;
  }
  GST_OBJECT_UNLOCK (display);

  return ret;
}

/**
 * gst_gl_display_find_window:
 * @display: a #GstGLDisplay
 * @data: (closure): some data to pass to @compare_func
 * @compare_func: (scope call): a comparison function to run
 *
 * Execute @compare_func over the list of windows stored by @display.  The
 * first argment to @compare_func is the #GstGLWindow being checked and the
 * second argument is @data.
 *
 * Returns: (transfer none): The first #GstGLWindow that causes a match
 *          from @compare_func
 *
 * Since: 1.12
 */
GstGLWindow *
gst_gl_display_find_window (GstGLDisplay * display, gpointer data,
    GCompareFunc compare_func)
{
  GstGLWindow *ret = NULL;
  GList *l;

  GST_OBJECT_LOCK (display);
  l = g_list_find_custom (display->windows, data, compare_func);
  if (l)
    ret = l->data;
  GST_OBJECT_UNLOCK (display);

  return ret;
}

static GstGLContext *
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
{
  GstGLContext *context = NULL;
  GList *prev = NULL, *l = display->priv->contexts;

  while (l) {
    GWeakRef *ref = l->data;
    GThread *context_thread;

    context = g_weak_ref_get (ref);
    if (!context) {
      /* remove dead contexts */
      g_weak_ref_clear (l->data);
      g_free (l->data);
      display->priv->contexts = g_list_delete_link (display->priv->contexts, l);
      l = prev ? prev->next : display->priv->contexts;
      continue;
    }

    if (thread == NULL) {
      GST_DEBUG_OBJECT (display, "Returning GL context %" GST_PTR_FORMAT " for "
          "NULL thread", context);
      return context;
    }

    context_thread = gst_gl_context_get_thread (context);
    if (thread != context_thread) {
      g_thread_unref (context_thread);
      gst_object_unref (context);
      prev = l;
      l = l->next;
      continue;
    }

    if (context_thread)
      g_thread_unref (context_thread);

    GST_DEBUG_OBJECT (display, "Returning GL context %" GST_PTR_FORMAT " for "
        "thread %p", context, thread);
    return context;
  }

  GST_DEBUG_OBJECT (display, "No GL context for thread %p", thread);
  return NULL;
}

/**
 * gst_gl_display_get_gl_context_for_thread:
 * @display: a #GstGLDisplay
 * @thread: a #GThread
 *
 * Returns: (transfer full): the #GstGLContext current on @thread or %NULL
 *
 * Must be called with the object lock held.
 *
 * Since: 1.6
 */
GstGLContext *
gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
    GThread * thread)
{
  GstGLContext *context;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);

  context = _get_gl_context_for_thread_unlocked (display, thread);
  GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread "
      "%p", context, thread);

  return context;
}

static gboolean
_check_collision (GstGLContext * context, GstGLContext * collision)
{
  GThread *thread, *collision_thread;
  gboolean ret = FALSE;

  if (!context || !collision)
    return FALSE;

  thread = gst_gl_context_get_thread (context);
  collision_thread = gst_gl_context_get_thread (collision);

  if (!thread || !collision_thread) {
    ret = FALSE;
    goto out;
  }

  if (thread == collision_thread) {
    ret = TRUE;
    goto out;
  }

out:
  if (thread)
    g_thread_unref (thread);
  if (collision_thread)
    g_thread_unref (collision_thread);

  return ret;
}

/**
 * gst_gl_display_add_context:
 * @display: a #GstGLDisplay
 * @context: (transfer none): a #GstGLContext
 *
 * Returns: whether @context was successfully added. %FALSE may be returned
 * if there already exists another context for @context's active thread.
 *
 * Must be called with the object lock held.
 *
 * Since: 1.6
 */
gboolean
gst_gl_display_add_context (GstGLDisplay * display, GstGLContext * context)
{
  GstGLContext *collision = NULL;
  GstGLDisplay *context_display;
  gboolean ret = TRUE;
  GThread *thread;
  GWeakRef *ref;

  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), FALSE);
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  context_display = gst_gl_context_get_display (context);
  g_assert (context_display == display);
  gst_object_unref (context_display);

  thread = gst_gl_context_get_thread (context);
  if (thread) {
    collision = _get_gl_context_for_thread_unlocked (display, thread);
    g_thread_unref (thread);

    /* adding the same context is a no-op */
    if (context == collision) {
      GST_LOG_OBJECT (display, "Attempting to add the same GL context %"
          GST_PTR_FORMAT ". Ignoring", context);
      ret = TRUE;
      goto out;
    }

    if (_check_collision (context, collision)) {
      GST_DEBUG_OBJECT (display, "Collision detected adding GL context "
          "%" GST_PTR_FORMAT, context);
      ret = FALSE;
      goto out;
    }
  }

  ref = g_new0 (GWeakRef, 1);
  g_weak_ref_init (ref, context);

  GST_DEBUG_OBJECT (display, "Adding GL context %" GST_PTR_FORMAT, context);
  display->priv->contexts = g_list_prepend (display->priv->contexts, ref);

out:
  if (collision)
    gst_object_unref (collision);

  GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT,
      ret ? "" : "un", context);

  return ret;
}
