/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.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:element-caopengllayersink
 *
 * caopengllayersink renders incoming video frames to CAOpenGLLayer that
 * can be retrieved through the layer property and placed in the Core
 * Animation render tree.
 */

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

#include "caopengllayersink.h"
#include "gstglsinkbin.h"
#include <QuartzCore/QuartzCore.h>

GST_DEBUG_CATEGORY (gst_debug_ca_sink);
#define GST_CAT_DEFAULT gst_debug_ca_sink

typedef GstGLSinkBin GstCAOpenGLLayerSinkBin;
typedef GstGLSinkBinClass GstCAOpenGLLayerSinkBinClass;

G_DEFINE_TYPE (GstCAOpenGLLayerSinkBin, gst_ca_opengl_layer_sink_bin,
    GST_TYPE_GL_SINK_BIN);

enum
{
  PROP_BIN_0,
  PROP_BIN_QOS,
  PROP_BIN_FORCE_ASPECT_RATIO,
  PROP_BIN_LAST_SAMPLE,
  PROP_BIN_LAYER,
};

static void
_on_notify_layer (GObject * object, GParamSpec *pspec, gpointer user_data)
{
  GstCAOpenGLLayerSinkBin *self = user_data;

  g_object_notify (G_OBJECT (self), "layer");
}

static void
gst_ca_opengl_layer_sink_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * param_spec)
{
  g_object_set_property (G_OBJECT (GST_GL_SINK_BIN (object)->sink),
      param_spec->name, value);
}

static void
gst_ca_opengl_layer_sink_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * param_spec)
{
  g_object_get_property (G_OBJECT (GST_GL_SINK_BIN (object)->sink),
      param_spec->name, value);
}

static void
gst_ca_opengl_layer_sink_bin_init (GstCAOpenGLLayerSinkBin * self)
{
  GstGLCAOpenGLLayer *sink = g_object_new (GST_TYPE_CA_OPENGL_LAYER_SINK, NULL);

  g_signal_connect (sink, "notify::layer", G_CALLBACK (_on_notify_layer), self);

  gst_gl_sink_bin_finish_init_with_element (GST_GL_SINK_BIN (self),
      GST_ELEMENT (sink));
}

static void
gst_ca_opengl_layer_sink_bin_class_init (GstCAOpenGLLayerSinkBinClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->get_property = gst_ca_opengl_layer_sink_bin_get_property;
  gobject_class->set_property = gst_ca_opengl_layer_sink_bin_set_property;

  g_object_class_install_property (gobject_class, PROP_BIN_FORCE_ASPECT_RATIO,
      g_param_spec_boolean ("force-aspect-ratio",
          "Force aspect ratio",
          "When enabled, scaling will respect original aspect ratio", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_BIN_LAST_SAMPLE,
      g_param_spec_boxed ("last-sample", "Last Sample",
          "The last sample received in the sink", GST_TYPE_SAMPLE,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_BIN_LAYER,
      g_param_spec_pointer ("layer", "CAOpenGLLayer",
          "OpenGL Core Animation layer",
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_BIN_QOS,
      g_param_spec_boolean ("qos", "Quality of Service",
          "Generate Quality-of-Service events upstream", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

#define GST_CA_OPENGL_LAYER_SINK_GET_LOCK(glsink) \
  (GST_CA_OPENGL_LAYER_SINK(glsink)->drawing_lock)
#define GST_CA_OPENGL_LAYER_SINK_LOCK(glsink) \
  (g_mutex_lock(&GST_CA_OPENGL_LAYER_SINK_GET_LOCK (glsink)))
#define GST_CA_OPENGL_LAYER_SINK_UNLOCK(glsink) \
  (g_mutex_unlock(&GST_CA_OPENGL_LAYER_SINK_GET_LOCK (glsink)))

#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))

#define SUPPORTED_GL_APIS GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3

static void gst_ca_opengl_layer_sink_thread_init_redisplay (GstCAOpenGLLayerSink * ca_sink);
static void gst_ca_opengl_layer_sink_cleanup_glthread (GstCAOpenGLLayerSink * ca_sink);
static void gst_ca_opengl_layer_sink_on_resize (GstCAOpenGLLayerSink * ca_sink,
    gint width, gint height);
static void gst_ca_opengl_layer_sink_on_draw (GstCAOpenGLLayerSink * ca_sink);

static void gst_ca_opengl_layer_sink_finalize (GObject * object);
static void gst_ca_opengl_layer_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * param_spec);
static void gst_ca_opengl_layer_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * param_spec);

static gboolean gst_ca_opengl_layer_sink_stop (GstBaseSink * bsink);

static gboolean gst_ca_opengl_layer_sink_query (GstBaseSink * bsink, GstQuery * query);
static void gst_ca_opengl_layer_sink_set_context (GstElement * element,
    GstContext * context);

static GstStateChangeReturn gst_ca_opengl_layer_sink_change_state (GstElement *
    element, GstStateChange transition);

static void gst_ca_opengl_layer_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
    GstClockTime * start, GstClockTime * end);
static gboolean gst_ca_opengl_layer_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static GstFlowReturn gst_ca_opengl_layer_sink_prepare (GstBaseSink * bsink,
    GstBuffer * buf);
static GstFlowReturn gst_ca_opengl_layer_sink_show_frame (GstVideoSink * bsink,
    GstBuffer * buf);
static gboolean gst_ca_opengl_layer_sink_propose_allocation (GstBaseSink * bsink,
    GstQuery * query);

static GstStaticPadTemplate gst_ca_opengl_layer_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
      "format = (string) RGBA, "
      "width = " GST_VIDEO_SIZE_RANGE ", "
      "height = " GST_VIDEO_SIZE_RANGE ", "
      "framerate = " GST_VIDEO_FPS_RANGE ","
      "texture-target = (string) 2D")
    );

enum
{
  PROP_0,
  PROP_FORCE_ASPECT_RATIO,
  PROP_CONTEXT,
  PROP_LAYER,
};

#define gst_ca_opengl_layer_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstCAOpenGLLayerSink, gst_ca_opengl_layer_sink,
    GST_TYPE_VIDEO_SINK, GST_DEBUG_CATEGORY_INIT (gst_debug_ca_sink,
        "caopengllayersink", 0, "CAOpenGLLayer Video Sink"));

static void
gst_ca_opengl_layer_sink_class_init (GstCAOpenGLLayerSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;
  GstVideoSinkClass *gstvideosink_class;
  GstElementClass *element_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;
  gstvideosink_class = (GstVideoSinkClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = gst_ca_opengl_layer_sink_set_property;
  gobject_class->get_property = gst_ca_opengl_layer_sink_get_property;

  g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
      g_param_spec_boolean ("force-aspect-ratio",
          "Force aspect ratio",
          "When enabled, scaling will respect original aspect ratio", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CONTEXT,
      g_param_spec_object ("context",
          "OpenGL context",
          "Get OpenGL context",
          GST_GL_TYPE_CONTEXT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LAYER,
      g_param_spec_pointer ("layer", "CAOpenGLLayer",
          "OpenGL Core Animation layer",
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_metadata (element_class, "CAOpenGLLayer video sink",
      "Sink/Video", "A video sink based on CAOpenGLLayer",
      "Matthew Waters <matthew@centricular.com>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_ca_opengl_layer_sink_template));

  gobject_class->finalize = gst_ca_opengl_layer_sink_finalize;

  gstelement_class->change_state = gst_ca_opengl_layer_sink_change_state;
  gstelement_class->set_context = gst_ca_opengl_layer_sink_set_context;
  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_ca_opengl_layer_sink_query);
  gstbasesink_class->set_caps = gst_ca_opengl_layer_sink_set_caps;
  gstbasesink_class->get_times = gst_ca_opengl_layer_sink_get_times;
  gstbasesink_class->prepare = gst_ca_opengl_layer_sink_prepare;
  gstbasesink_class->propose_allocation = gst_ca_opengl_layer_sink_propose_allocation;
  gstbasesink_class->stop = gst_ca_opengl_layer_sink_stop;

  gstvideosink_class->show_frame =
      GST_DEBUG_FUNCPTR (gst_ca_opengl_layer_sink_show_frame);
}

static void
gst_ca_opengl_layer_sink_init (GstCAOpenGLLayerSink * ca_sink)
{
  ca_sink->display = NULL;
  ca_sink->keep_aspect_ratio = TRUE;
  ca_sink->pool = NULL;
  ca_sink->stored_buffer = NULL;
  ca_sink->redisplay_texture = 0;

  g_mutex_init (&ca_sink->drawing_lock);
}

static void
gst_ca_opengl_layer_sink_finalize (GObject * object)
{
  GstCAOpenGLLayerSink *ca_sink;

  g_return_if_fail (GST_IS_CA_OPENGL_LAYER_SINK (object));

  ca_sink = GST_CA_OPENGL_LAYER_SINK (object);

  g_mutex_clear (&ca_sink->drawing_lock);

  GST_DEBUG ("finalized");
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_ca_opengl_layer_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCAOpenGLLayerSink *ca_sink;

  g_return_if_fail (GST_IS_CA_OPENGL_LAYER_SINK (object));

  ca_sink = GST_CA_OPENGL_LAYER_SINK (object);

  switch (prop_id) {
    case PROP_FORCE_ASPECT_RATIO:
    {
      ca_sink->keep_aspect_ratio = g_value_get_boolean (value);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_ca_opengl_layer_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstCAOpenGLLayerSink *ca_sink;

  g_return_if_fail (GST_IS_CA_OPENGL_LAYER_SINK (object));

  ca_sink = GST_CA_OPENGL_LAYER_SINK (object);

  switch (prop_id) {
    case PROP_FORCE_ASPECT_RATIO:
      g_value_set_boolean (value, ca_sink->keep_aspect_ratio);
      break;
    case PROP_CONTEXT:
      g_value_set_object (value, ca_sink->context);
      break;
    case PROP_LAYER:
      g_value_set_pointer (value, ca_sink->layer);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
_create_layer (gpointer data)
{
  GstCAOpenGLLayerSink *ca_sink = data;

  if (!ca_sink->layer) {
    ca_sink->layer = [[NSClassFromString(@"GstGLCAOpenGLLayer") alloc]
        initWithGstGLContext:GST_GL_CONTEXT_COCOA (ca_sink->context)];
    [ca_sink->layer setDrawCallback:(GstGLWindowCB)gst_ca_opengl_layer_sink_on_draw
        data:ca_sink notify:NULL];
    [ca_sink->layer setResizeCallback:(GstGLWindowResizeCB)gst_ca_opengl_layer_sink_on_resize
        data:ca_sink notify:NULL];
    g_object_notify (G_OBJECT (ca_sink), "layer");
  }
}

static void
_invoke_on_main (GstGLWindowCB func, gpointer data)
{
  if ([NSThread isMainThread]) {
    func (data);
  } else {
    dispatch_sync (dispatch_get_main_queue (), ^{
      func (data);
    });
  }
}

static gboolean
_ensure_gl_setup (GstCAOpenGLLayerSink * ca_sink)
{
  GError *error = NULL;

  if (!gst_gl_ensure_element_data (ca_sink, &ca_sink->display,
          &ca_sink->other_context))
    return FALSE;

  gst_gl_display_filter_gl_api (ca_sink->display, SUPPORTED_GL_APIS);

  if (!ca_sink->context) {
    if (!gst_gl_display_create_context (ca_sink->display,
            ca_sink->other_context, &ca_sink->context, &error)) {
      goto context_error;
    }
  }

  if (!ca_sink->layer)
    _invoke_on_main ((GstGLWindowCB) _create_layer, ca_sink);

  return TRUE;

context_error:
  {
    GST_ELEMENT_ERROR (ca_sink, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    gst_object_unref (ca_sink->context);
    ca_sink->context = NULL;
    return FALSE;
  }
}

static gboolean
gst_ca_opengl_layer_sink_query (GstBaseSink * bsink, GstQuery * query)
{
  GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CONTEXT:
    {
      const gchar *context_type;
      GstContext *context, *old_context;
      gboolean ret;

      ret =
          gst_gl_handle_context_query ((GstElement *) ca_sink, query,
          &ca_sink->display, &ca_sink->other_context);
      if (ca_sink->display)
        gst_gl_display_filter_gl_api (ca_sink->display, SUPPORTED_GL_APIS);

      gst_query_parse_context_type (query, &context_type);

      if (g_strcmp0 (context_type, "gst.gl.local_context") == 0) {
        GstStructure *s;

        gst_query_parse_context (query, &old_context);

        if (old_context)
          context = gst_context_copy (old_context);
        else
          context = gst_context_new ("gst.gl.local_context", FALSE);

        s = gst_context_writable_structure (context);
        gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT,
            ca_sink->context, NULL);
        gst_query_set_context (query, context);
        gst_context_unref (context);

        ret = ca_sink->context != NULL;
      }
      GST_DEBUG_OBJECT (ca_sink, "context query of type %s %i",
          context_type, ret);

      if (ret)
        return ret;
    }
    case GST_QUERY_DRAIN:
    {
      GstBuffer *buf = NULL;

      GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);
      ca_sink->redisplay_texture = 0;
      buf = ca_sink->stored_buffer;
      ca_sink->stored_buffer = NULL;
      GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);

      if (buf)
        gst_buffer_unref (buf);

      gst_buffer_replace (&ca_sink->next_buffer, NULL);
      gst_buffer_replace (&ca_sink->next_sync, NULL);

      break;
    }
    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
}

static gboolean
gst_ca_opengl_layer_sink_stop (GstBaseSink * bsink)
{
  GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);

  if (ca_sink->pool) {
    gst_object_unref (ca_sink->pool);
    ca_sink->pool = NULL;
  }

  if (ca_sink->gl_caps) {
    gst_caps_unref (ca_sink->gl_caps);
    ca_sink->gl_caps = NULL;
  }

  return TRUE;
}

static void
gst_ca_opengl_layer_sink_set_context (GstElement * element, GstContext * context)
{
  GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (element);

  gst_gl_handle_set_context (element, context, &ca_sink->display,
      &ca_sink->other_context);

  if (ca_sink->display)
    gst_gl_display_filter_gl_api (ca_sink->display, SUPPORTED_GL_APIS);

  GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}

static GstStateChangeReturn
gst_ca_opengl_layer_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstCAOpenGLLayerSink *ca_sink;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  GST_DEBUG ("changing state: %s => %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  ca_sink = GST_CA_OPENGL_LAYER_SINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      _ensure_gl_setup (ca_sink);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      g_atomic_int_set (&ca_sink->to_quit, 0);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
    {
      /* mark the redisplay_texture as unavailable (=0)
       * to avoid drawing
       */
      GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);
      ca_sink->redisplay_texture = 0;

      gst_buffer_replace (&ca_sink->stored_sync, NULL);

      if (ca_sink->stored_buffer) {
        gst_buffer_unref (ca_sink->stored_buffer);
        ca_sink->stored_buffer = NULL;
      }
      gst_buffer_replace (&ca_sink->next_buffer, NULL);
      gst_buffer_replace (&ca_sink->next_sync, NULL);
      GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);

      if (ca_sink->pool) {
        gst_buffer_pool_set_active (ca_sink->pool, FALSE);
        gst_object_unref (ca_sink->pool);
        ca_sink->pool = NULL;
      }

      GST_VIDEO_SINK_WIDTH (ca_sink) = 1;
      GST_VIDEO_SINK_HEIGHT (ca_sink) = 1;
      if (ca_sink->context) {
        gst_object_unref (ca_sink->context);
        ca_sink->context = NULL;
      }

      if (ca_sink->display) {
        gst_object_unref (ca_sink->display);
        ca_sink->display = NULL;
      }
      break;
    }
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_ca_opengl_layer_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
    GstClockTime * start, GstClockTime * end)
{
  GstCAOpenGLLayerSink *ca_sink;

  ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    *start = GST_BUFFER_TIMESTAMP (buf);
    if (GST_BUFFER_DURATION_IS_VALID (buf))
      *end = *start + GST_BUFFER_DURATION (buf);
    else {
      if (GST_VIDEO_INFO_FPS_N (&ca_sink->info) > 0) {
        *end = *start +
            gst_util_uint64_scale_int (GST_SECOND,
            GST_VIDEO_INFO_FPS_D (&ca_sink->info),
            GST_VIDEO_INFO_FPS_N (&ca_sink->info));
      }
    }
  }
}

static gboolean
gst_ca_opengl_layer_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
  GstCAOpenGLLayerSink *ca_sink;
  gint width;
  gint height;
  gboolean ok;
  gint par_n, par_d;
  gint display_par_n, display_par_d;
  guint display_ratio_num, display_ratio_den;
  GstVideoInfo vinfo;

  GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);

  ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);

  ok = gst_video_info_from_caps (&vinfo, caps);
  if (!ok)
    return FALSE;

  width = GST_VIDEO_INFO_WIDTH (&vinfo);
  height = GST_VIDEO_INFO_HEIGHT (&vinfo);

  par_n = GST_VIDEO_INFO_PAR_N (&vinfo);
  par_d = GST_VIDEO_INFO_PAR_D (&vinfo);

  if (!par_n)
    par_n = 1;

  display_par_n = 1;
  display_par_d = 1;

  ok = gst_video_calculate_display_ratio (&display_ratio_num,
      &display_ratio_den, width, height, par_n, par_d, display_par_n,
      display_par_d);

  if (!ok)
    return FALSE;

  GST_TRACE ("PAR: %u/%u DAR:%u/%u", par_n, par_d, display_par_n,
      display_par_d);

  if (height % display_ratio_den == 0) {
    GST_DEBUG ("keeping video height");
    GST_VIDEO_SINK_WIDTH (ca_sink) = (guint)
        gst_util_uint64_scale_int (height, display_ratio_num,
        display_ratio_den);
    GST_VIDEO_SINK_HEIGHT (ca_sink) = height;
  } else if (width % display_ratio_num == 0) {
    GST_DEBUG ("keeping video width");
    GST_VIDEO_SINK_WIDTH (ca_sink) = width;
    GST_VIDEO_SINK_HEIGHT (ca_sink) = (guint)
        gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num);
  } else {
    GST_DEBUG ("approximating while keeping video height");
    GST_VIDEO_SINK_WIDTH (ca_sink) = (guint)
        gst_util_uint64_scale_int (height, display_ratio_num,
        display_ratio_den);
    GST_VIDEO_SINK_HEIGHT (ca_sink) = height;
  }
  GST_DEBUG ("scaling to %dx%d", GST_VIDEO_SINK_WIDTH (ca_sink),
      GST_VIDEO_SINK_HEIGHT (ca_sink));

  ca_sink->info = vinfo;
  if (!_ensure_gl_setup (ca_sink))
    return FALSE;

  ca_sink->caps_change = TRUE;

  return TRUE;
}

static GstFlowReturn
gst_ca_opengl_layer_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
{
  GstCAOpenGLLayerSink *ca_sink;
  GstBuffer *next_sync, *old_sync, *old_buffer;
  GstVideoFrame gl_frame;
  GstGLSyncMeta *sync_meta;

  ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);

  GST_TRACE ("preparing buffer:%p", buf);

  if (GST_VIDEO_SINK_WIDTH (ca_sink) < 1 ||
      GST_VIDEO_SINK_HEIGHT (ca_sink) < 1) {
    return GST_FLOW_NOT_NEGOTIATED;
  }

  if (!_ensure_gl_setup (ca_sink))
    return GST_FLOW_NOT_NEGOTIATED;

  if (!gst_video_frame_map (&gl_frame, &ca_sink->info, buf,
          GST_MAP_READ | GST_MAP_GL)) {
    goto upload_failed;
  }

  ca_sink->next_tex = *(guint *) gl_frame.data[0];

  next_sync = gst_buffer_new ();
  sync_meta = gst_buffer_add_gl_sync_meta (ca_sink->context, next_sync);
  gst_gl_sync_meta_set_sync_point (sync_meta, ca_sink->context);

  GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);
  ca_sink->next_tex = *(guint *) gl_frame.data[0];

  old_buffer = ca_sink->next_buffer;
  ca_sink->next_buffer = gst_buffer_ref (buf);

  old_sync = ca_sink->next_sync;
  ca_sink->next_sync = next_sync;
  GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);

  if (old_buffer)
    gst_buffer_unref (old_buffer);
  if (old_sync)
    gst_buffer_unref (old_sync);

  gst_video_frame_unmap (&gl_frame);

  return GST_FLOW_OK;

upload_failed:
  {
    GST_ELEMENT_ERROR (ca_sink, RESOURCE, NOT_FOUND,
        ("%s", "Failed to upload buffer"), (NULL));
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_ca_opengl_layer_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
{
  GstCAOpenGLLayerSink *ca_sink;
  GstBuffer *stored_buffer, *old_sync;

  GST_TRACE ("rendering buffer:%p", buf);

  ca_sink = GST_CA_OPENGL_LAYER_SINK (vsink);

  GST_TRACE ("redisplay texture:%u of size:%ux%u, window size:%ux%u",
      ca_sink->next_tex, GST_VIDEO_INFO_WIDTH (&ca_sink->info),
      GST_VIDEO_INFO_HEIGHT (&ca_sink->info),
      GST_VIDEO_SINK_WIDTH (ca_sink),
      GST_VIDEO_SINK_HEIGHT (ca_sink));

  /* Avoid to release the texture while drawing */
  GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);
  ca_sink->redisplay_texture = ca_sink->next_tex;

  stored_buffer = ca_sink->stored_buffer;
  ca_sink->stored_buffer = gst_buffer_ref (ca_sink->next_buffer);

  old_sync = ca_sink->stored_sync;
  ca_sink->stored_sync = gst_buffer_ref (ca_sink->next_sync);
  GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);

  /* The layer will automatically call the draw callback to draw the new
   * content */
  [CATransaction begin];
  [ca_sink->layer setNeedsDisplay];
  [CATransaction commit];

  GST_TRACE ("post redisplay");

  if (stored_buffer)
    gst_buffer_unref (stored_buffer);
  if (old_sync)
    gst_buffer_unref (old_sync);

  if (g_atomic_int_get (&ca_sink->to_quit) != 0) {
    GST_ELEMENT_ERROR (ca_sink, RESOURCE, NOT_FOUND,
        ("%s", gst_gl_context_get_error ()), (NULL));
    return GST_FLOW_ERROR;
  }

  return GST_FLOW_OK;
}

static gboolean
gst_ca_opengl_layer_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
  GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
  GstStructure *config;
  GstCaps *caps;
  guint size;
  gboolean need_pool;

  if (!_ensure_gl_setup (ca_sink))
    return FALSE;

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (caps == NULL)
    goto no_caps;

  if (need_pool) {
    GstVideoInfo info;

    if (!gst_video_info_from_caps (&info, caps))
      goto invalid_caps;

    /* the normal size of a frame */
    size = info.size;

    if (ca_sink->pool) {
      GstCaps *pcaps;

      /* we had a pool, check caps */
      GST_DEBUG_OBJECT (ca_sink, "check existing pool caps");
      config = gst_buffer_pool_get_config (ca_sink->pool);
      gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);

      if (!gst_caps_is_equal (caps, pcaps)) {
        GST_DEBUG_OBJECT (ca_sink, "pool has different caps");
        /* different caps, we can't use this pool */
        gst_object_unref (ca_sink->pool);
        ca_sink->pool = NULL;
      }
      gst_structure_free (config);
    }

    if (ca_sink->pool == NULL) {
      GST_DEBUG_OBJECT (ca_sink, "create new pool");

      ca_sink->pool = gst_gl_buffer_pool_new (ca_sink->context);
      config = gst_buffer_pool_get_config (ca_sink->pool);
      gst_buffer_pool_config_set_params (config, caps, size, 0, 0);

      if (!gst_buffer_pool_set_config (ca_sink->pool, config))
        goto config_failed;
    }

    /* we need at least 2 buffer because we hold on to the last one */
    gst_query_add_allocation_pool (query, ca_sink->pool, size, 2, 0);
  }

  if (ca_sink->context->gl_vtable->FenceSync)
    gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, 0);

  return TRUE;

  /* ERRORS */
no_caps:
  {
    GST_DEBUG_OBJECT (bsink, "no caps specified");
    return FALSE;
  }
invalid_caps:
  {
    GST_DEBUG_OBJECT (bsink, "invalid caps specified");
    return FALSE;
  }
config_failed:
  {
    GST_DEBUG_OBJECT (bsink, "failed setting config");
    return FALSE;
  }
}

/* *INDENT-OFF* */
static const GLfloat vertices[] = {
     1.0f,  1.0f, 0.0f, 1.0f, 0.0f,
    -1.0f,  1.0f, 0.0f, 0.0f, 0.0f,
    -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
     1.0f, -1.0f, 0.0f, 1.0f, 1.0f
};

static const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
/* *INDENT-ON* */

static void
_bind_buffer (GstCAOpenGLLayerSink * ca_sink)
{
  const GstGLFuncs *gl = ca_sink->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, ca_sink->vbo_indices);
  gl->BindBuffer (GL_ARRAY_BUFFER, ca_sink->vertex_buffer);

  /* Load the vertex position */
  gl->VertexAttribPointer (ca_sink->attr_position, 3, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) 0);

  /* Load the texture coordinate */
  gl->VertexAttribPointer (ca_sink->attr_texture, 2, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));

  gl->EnableVertexAttribArray (ca_sink->attr_position);
  gl->EnableVertexAttribArray (ca_sink->attr_texture);
}

static void
_unbind_buffer (GstCAOpenGLLayerSink * ca_sink)
{
  const GstGLFuncs *gl = ca_sink->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  gl->DisableVertexAttribArray (ca_sink->attr_position);
  gl->DisableVertexAttribArray (ca_sink->attr_texture);
}

/* Called in the gl thread */
static void
gst_ca_opengl_layer_sink_thread_init_redisplay (GstCAOpenGLLayerSink * ca_sink)
{
  const GstGLFuncs *gl = ca_sink->context->gl_vtable;
  GError *error = NULL;

  if (!(ca_sink->redisplay_shader = gst_gl_shader_new_default (ca_sink->context, &error))) {
    GST_ERROR_OBJECT (ca_sink, "Failed to link shader: %s", error->message);
    gst_ca_opengl_layer_sink_cleanup_glthread (ca_sink);
    return;
  }

  ca_sink->attr_position =
      gst_gl_shader_get_attribute_location (ca_sink->redisplay_shader,
      "a_position");
  ca_sink->attr_texture =
      gst_gl_shader_get_attribute_location (ca_sink->redisplay_shader,
      "a_texcoord");

  if (gl->GenVertexArrays) {
    gl->GenVertexArrays (1, &ca_sink->vao);
    gl->BindVertexArray (ca_sink->vao);
  }

  if (!ca_sink->vertex_buffer) {
    gl->GenBuffers (1, &ca_sink->vertex_buffer);
    gl->BindBuffer (GL_ARRAY_BUFFER, ca_sink->vertex_buffer);
    gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
        GL_STATIC_DRAW);
  }

  if (!ca_sink->vbo_indices) {
    gl->GenBuffers (1, &ca_sink->vbo_indices);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, ca_sink->vbo_indices);
    gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices,
        GL_STATIC_DRAW);
  }

  if (gl->GenVertexArrays) {
    _bind_buffer (ca_sink);
    gl->BindVertexArray (0);
  }

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);
}

static void
gst_ca_opengl_layer_sink_cleanup_glthread (GstCAOpenGLLayerSink * ca_sink)
{
  const GstGLFuncs *gl = ca_sink->context->gl_vtable;

  if (ca_sink->redisplay_shader) {
    gst_object_unref (ca_sink->redisplay_shader);
    ca_sink->redisplay_shader = NULL;
  }

  if (ca_sink->vao) {
    gl->DeleteVertexArrays (1, &ca_sink->vao);
    ca_sink->vao = 0;
  }

  if (ca_sink->vbo_indices) {
    gl->DeleteBuffers (1, &ca_sink->vbo_indices);
    ca_sink->vbo_indices = 0;
  }

  if (ca_sink->vertex_buffer) {
    gl->DeleteBuffers (1, &ca_sink->vertex_buffer);
    ca_sink->vertex_buffer = 0;
  }
}

static void
gst_ca_opengl_layer_sink_on_resize (GstCAOpenGLLayerSink * ca_sink, gint width, gint height)
{
  /* Here ca_sink members (ex:ca_sink->info) have a life time of set_caps.
   * It means that they cannot not change between two set_caps
   */
  const GstGLFuncs *gl = ca_sink->context->gl_vtable;

  GST_TRACE ("GL Window resized to %ux%u", width, height);

  width = MAX (1, width);
  height = MAX (1, height);

  ca_sink->window_width = width;
  ca_sink->window_height = height;

  /* default reshape */
  if (ca_sink->keep_aspect_ratio) {
    GstVideoRectangle src, dst, result;

    src.x = 0;
    src.y = 0;
    src.w = GST_VIDEO_SINK_WIDTH (ca_sink);
    src.h = GST_VIDEO_SINK_HEIGHT (ca_sink);

    dst.x = 0;
    dst.y = 0;
    dst.w = width;
    dst.h = height;

    gst_video_sink_center_rect (src, dst, &result, TRUE);
    gl->Viewport (result.x, result.y, result.w, result.h);
  } else {
    gl->Viewport (0, 0, width, height);
  }
}

static void
gst_ca_opengl_layer_sink_on_draw (GstCAOpenGLLayerSink * ca_sink)
{
  /* Here ca_sink members (ex:ca_sink->info) have a life time of set_caps.
   * It means that they cannot not change between two set_caps as well as
   * for the redisplay_texture size.
   * Whereas redisplay_texture id changes every sink_render
   */

  const GstGLFuncs *gl = NULL;
  GstGLSyncMeta *sync_meta;

  g_return_if_fail (GST_IS_CA_OPENGL_LAYER_SINK (ca_sink));

  gl = ca_sink->context->gl_vtable;

  GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);

  if (G_UNLIKELY (!ca_sink->redisplay_shader)) {
    gst_ca_opengl_layer_sink_thread_init_redisplay (ca_sink);
  }

  /* check if texture is ready for being drawn */
  if (!ca_sink->redisplay_texture) {
    gl->ClearColor (0.0f, 0.0f, 0.0f, 1.0f);
    gl->Clear (GL_COLOR_BUFFER_BIT);
    GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);
    return;
  }

  /* opengl scene */
  GST_TRACE ("redrawing texture:%u", ca_sink->redisplay_texture);

  if (ca_sink->caps_change) {
    GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);
    gst_ca_opengl_layer_sink_on_resize (ca_sink, ca_sink->window_width,
        ca_sink->window_height);
    GST_CA_OPENGL_LAYER_SINK_LOCK (ca_sink);
    ca_sink->caps_change = TRUE;
  }

  sync_meta = gst_buffer_get_gl_sync_meta (ca_sink->stored_sync);
  if (sync_meta)
    gst_gl_sync_meta_wait (sync_meta, gst_gl_context_get_current ());

  gl->BindTexture (GL_TEXTURE_2D, 0);

  gl->ClearColor (0.0, 0.0, 0.0, 0.0);
  gl->Clear (GL_COLOR_BUFFER_BIT);

  gst_gl_shader_use (ca_sink->redisplay_shader);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (ca_sink->vao);
  else
    _bind_buffer (ca_sink);

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, ca_sink->redisplay_texture);
  gst_gl_shader_set_uniform_1i (ca_sink->redisplay_shader, "tex", 0);

  gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (0);
  else
    _unbind_buffer (ca_sink);

  /* end default opengl scene */
  GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);
}
