/* GStreamer
 * Copyright (C) <2008> Wim Taymans <wim.taymans@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:element-smptealpha
 *
 * smptealpha can accept an I420 or AYUV video stream. An alpha channel is added
 * using an effect specific SMPTE mask in the I420 input case. In the AYUV case,
 * the alpha channel is modified using the effect specific SMPTE mask.
 *
 * The #GstSmpteAlpha:position property is a controllabe double between 0.0 and
 * 1.0 that specifies the position in the transition. 0.0 is the start of the
 * transition with the alpha channel to complete opaque where 1.0 has the alpha
 * channel set to completely transparent.
 *
 * The #GstSmpteAlpha:depth property defines the precision in bits of the mask.
 * A higher presision will create a mask with smoother gradients in order to
 * avoid banding.
 *
 * <refsect2>
 * <title>Sample pipelines</title>
 * <para>
 * Here is a pipeline to demonstrate the smpte transition :
 * <programlisting>
 * gst-launch-1.0 -v videotestsrc ! smptealpha border=20000 type=44
 * position=0.5 ! videomixer ! videoconvert ! ximagesink
 * </programlisting>
 * This shows a midway bowtie-h transition a from a videotestsrc to a
 * transparent image. The edges of the transition are smoothed with a
 * 20000 big border.
 * </para>
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>

#include "gstsmptealpha.h"
#include "paint.h"

GST_DEBUG_CATEGORY_STATIC (gst_smpte_alpha_debug);
#define GST_CAT_DEFAULT gst_smpte_alpha_debug

static GstStaticPadTemplate gst_smpte_alpha_src_template =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV") ";"
        GST_VIDEO_CAPS_MAKE ("ARGB") ";" GST_VIDEO_CAPS_MAKE ("BGRA") ";"
        GST_VIDEO_CAPS_MAKE ("RGBA") ";" GST_VIDEO_CAPS_MAKE ("ARGB"))
    );

static GstStaticPadTemplate gst_smpte_alpha_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420") ";"
        GST_VIDEO_CAPS_MAKE ("YV12")
        ";" GST_VIDEO_CAPS_MAKE ("AYUV")
        ";" GST_VIDEO_CAPS_MAKE ("ARGB") ";" GST_VIDEO_CAPS_MAKE ("BGRA")
        ";" GST_VIDEO_CAPS_MAKE ("RGBA") ";" GST_VIDEO_CAPS_MAKE ("ARGB"))
    );

/* SMPTE signals and properties */

#define DEFAULT_PROP_TYPE	1
#define DEFAULT_PROP_BORDER	0
#define DEFAULT_PROP_DEPTH	16
#define DEFAULT_PROP_POSITION	0.0
#define DEFAULT_PROP_INVERT   FALSE

enum
{
  PROP_0,
  PROP_TYPE,
  PROP_BORDER,
  PROP_DEPTH,
  PROP_POSITION,
  PROP_INVERT
};

#define AYUV_SIZE(w,h)     ((w) * (h) * 4)

#define GST_TYPE_SMPTE_TRANSITION_TYPE (gst_smpte_alpha_transition_type_get_type())
static GType
gst_smpte_alpha_transition_type_get_type (void)
{
  static GType smpte_transition_type = 0;
  GEnumValue *smpte_transitions;

  if (!smpte_transition_type) {
    const GList *definitions;
    gint i = 0;

    definitions = gst_mask_get_definitions ();
    smpte_transitions =
        g_new0 (GEnumValue, g_list_length ((GList *) definitions) + 1);

    while (definitions) {
      GstMaskDefinition *definition = (GstMaskDefinition *) definitions->data;

      definitions = g_list_next (definitions);

      smpte_transitions[i].value = definition->type;
      /* older GLib versions have the two fields as non-const, hence the cast */
      smpte_transitions[i].value_nick = (gchar *) definition->short_name;
      smpte_transitions[i].value_name = (gchar *) definition->long_name;

      i++;
    }

    smpte_transition_type =
        g_enum_register_static ("GstSMPTEAlphaTransitionType",
        smpte_transitions);
  }
  return smpte_transition_type;
}


static void gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte);

static void gst_smpte_alpha_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_smpte_alpha_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_smpte_alpha_set_info (GstVideoFilter * vfilter,
    GstCaps * incaps, GstVideoInfo * in_info,
    GstCaps * outcaps, GstVideoInfo * out_info);
static GstFlowReturn gst_smpte_alpha_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame);
static void gst_smpte_alpha_before_transform (GstBaseTransform * trans,
    GstBuffer * buf);
static GstCaps *gst_smpte_alpha_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * from, GstCaps * filter);

#define gst_smpte_alpha_parent_class parent_class
G_DEFINE_TYPE (GstSMPTEAlpha, gst_smpte_alpha, GST_TYPE_VIDEO_FILTER);

static void
gst_smpte_alpha_class_init (GstSMPTEAlphaClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = (GstElementClass *) (klass);
  GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;

  gobject_class->set_property = gst_smpte_alpha_set_property;
  gobject_class->get_property = gst_smpte_alpha_get_property;

  gobject_class->finalize = (GObjectFinalizeFunc) gst_smpte_alpha_finalize;

  _gst_mask_init ();

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TYPE,
      g_param_spec_enum ("type", "Type", "The type of transition to use",
          GST_TYPE_SMPTE_TRANSITION_TYPE, DEFAULT_PROP_TYPE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BORDER,
      g_param_spec_int ("border", "Border",
          "The border width of the transition", 0, G_MAXINT,
          DEFAULT_PROP_BORDER,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEPTH,
      g_param_spec_int ("depth", "Depth", "Depth of the mask in bits", 1, 24,
          DEFAULT_PROP_DEPTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_POSITION,
      g_param_spec_double ("position", "Position",
          "Position of the transition effect", 0.0, 1.0, DEFAULT_PROP_POSITION,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstSMPTEAlpha:invert:
   *
   * Set to TRUE to invert the transition mask (ie. flip it horizontally).
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INVERT,
      g_param_spec_boolean ("invert", "Invert",
          "Invert transition mask", DEFAULT_PROP_POSITION,
          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  trans_class->before_transform =
      GST_DEBUG_FUNCPTR (gst_smpte_alpha_before_transform);
  trans_class->transform_caps =
      GST_DEBUG_FUNCPTR (gst_smpte_alpha_transform_caps);

  vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_smpte_alpha_set_info);
  vfilter_class->transform_frame =
      GST_DEBUG_FUNCPTR (gst_smpte_alpha_transform_frame);

  gst_element_class_add_static_pad_template (element_class,
      &gst_smpte_alpha_sink_template);
  gst_element_class_add_static_pad_template (element_class,
      &gst_smpte_alpha_src_template);
  gst_element_class_set_static_metadata (element_class, "SMPTE transitions",
      "Filter/Editor/Video",
      "Apply the standard SMPTE transitions as alpha on video images",
      "Wim Taymans <wim.taymans@gmail.com>");
}

static gboolean
gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type,
    gboolean invert, gint depth, gint width, gint height)
{
  GstMask *newmask;

  /* try to avoid regenerating the mask if we already have one that is
   * correct */
  if (smpte->mask) {
    if (smpte->type == type &&
        smpte->invert == invert &&
        smpte->depth == depth &&
        smpte->width == width && smpte->height == height)
      return TRUE;
  }

  smpte->type = type;
  smpte->invert = invert;
  smpte->depth = depth;
  smpte->width = width;
  smpte->height = height;

  /* Not negotiated yet */
  if (width == 0 || height == 0) {
    return TRUE;
  }

  newmask = gst_mask_factory_new (type, invert, depth, width, height);
  if (!newmask)
    goto mask_failed;

  if (smpte->mask)
    gst_mask_destroy (smpte->mask);

  smpte->mask = newmask;

  return TRUE;

  /* ERRORS */
mask_failed:
  {
    GST_ERROR_OBJECT (smpte, "failed to create a mask");
    return FALSE;
  }
}

static void
gst_smpte_alpha_init (GstSMPTEAlpha * smpte)
{
  smpte->type = DEFAULT_PROP_TYPE;
  smpte->border = DEFAULT_PROP_BORDER;
  smpte->depth = DEFAULT_PROP_DEPTH;
  smpte->position = DEFAULT_PROP_POSITION;
  smpte->invert = DEFAULT_PROP_INVERT;
}

#define CREATE_ARGB_FUNC(name, A, R, G, B) \
static void \
gst_smpte_alpha_process_##name##_##name (GstSMPTEAlpha * smpte, \
    const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask, \
    gint border, gint pos) \
{ \
  gint i, j; \
  const guint32 *maskp; \
  gint value; \
  gint min, max; \
  gint width, height; \
  guint8 *in, *out; \
  gint src_wrap, dest_wrap; \
  \
  if (border == 0) \
    border++; \
  \
  min = pos - border; \
  max = pos; \
  GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max, \
      border); \
  \
  maskp = mask->data; \
  \
  width = GST_VIDEO_FRAME_WIDTH (out_frame); \
  height = GST_VIDEO_FRAME_HEIGHT (out_frame); \
  \
  in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0); \
  out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0); \
  src_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) - (width << 2); \
  dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2); \
  \
  /* we basically copy the source to dest but we scale the alpha channel with \
   * the mask */ \
  for (i = 0; i < height; i++) { \
    for (j = 0; j < width; j++) { \
      value = *maskp++; \
      out[A] = (in[A] * ((CLAMP (value, min, max) - min) << 8) / border) >> 8; \
      out[R] = in[R]; \
      out[G] = in[G]; \
      out[B] = in[B]; \
      out += 4; \
      in += 4; \
    } \
    in += src_wrap; \
    out += dest_wrap; \
  } \
}

CREATE_ARGB_FUNC (argb, 0, 1, 2, 3);
CREATE_ARGB_FUNC (bgra, 3, 2, 1, 0);
CREATE_ARGB_FUNC (abgr, 0, 3, 2, 1);
CREATE_ARGB_FUNC (rgba, 3, 0, 1, 2);

static void
gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte,
    const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask,
    gint border, gint pos)
{
  gint i, j;
  const guint32 *maskp;
  gint value;
  gint min, max;
  gint width, height;
  guint8 *in, *out;
  gint src_wrap, dest_wrap;

  if (border == 0)
    border++;

  min = pos - border;
  max = pos;
  GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max,
      border);

  maskp = mask->data;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
  src_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) - (width << 2);
  dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2);

  /* we basically copy the source to dest but we scale the alpha channel with
   * the mask */
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      value = *maskp++;
      *out++ = (*in++ * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
      *out++ = *in++;
      *out++ = *in++;
      *out++ = *in++;
    }
    in += src_wrap;
    out += dest_wrap;
  }
}

static void
gst_smpte_alpha_process_i420_ayuv (GstSMPTEAlpha * smpte,
    const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask,
    gint border, gint pos)
{
  const guint8 *srcY;
  const guint8 *srcU;
  const guint8 *srcV;
  guint8 *out;
  gint i, j;
  gint src_wrap, src_u_wrap, src_v_wrap, dest_wrap;
  gint y_stride, u_stride, v_stride;
  gboolean odd_width;
  const guint32 *maskp;
  gint value;
  gint min, max;
  gint width, height;

  if (border == 0)
    border++;

  min = pos - border;
  max = pos;
  GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max,
      border);

  maskp = mask->data;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
  u_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
  v_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 2);

  src_wrap = y_stride - width;
  src_u_wrap = u_stride - (width / 2);
  src_v_wrap = v_stride - (width / 2);

  srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
  srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
  srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);

  out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
  dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2);

  odd_width = (width % 2 != 0);

  for (i = 0; i < height; i++) {
    for (j = 0; j < width / 2; j++) {
      value = *maskp++;
      *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
      *out++ = *srcY++;
      *out++ = *srcU;
      *out++ = *srcV;
      value = *maskp++;
      *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
      *out++ = *srcY++;
      *out++ = *srcU++;
      *out++ = *srcV++;
    }
    /* Might have one odd column left to do */
    if (odd_width) {
      value = *maskp++;
      *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
      *out++ = *srcY++;
      *out++ = *srcU;
      *out++ = *srcV;
    }
    if (i % 2 == 0) {
      srcU -= width / 2;
      srcV -= width / 2;
    } else {
      srcU += src_u_wrap;
      srcV += src_v_wrap;
    }
    srcY += src_wrap;
    out += dest_wrap;
  }
}

static void
gst_smpte_alpha_before_transform (GstBaseTransform * trans, GstBuffer * buf)
{
  GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (trans);
  GstClockTime timestamp, stream_time;

  /* first sync the controller to the current stream_time of the buffer */
  timestamp = GST_BUFFER_TIMESTAMP (buf);
  stream_time =
      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (smpte, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (smpte), stream_time);
}

static GstFlowReturn
gst_smpte_alpha_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter);
  gdouble position;
  gint border;

  if (G_UNLIKELY (!smpte->process))
    goto not_negotiated;

  GST_OBJECT_LOCK (smpte);
  position = smpte->position;
  border = smpte->border;

  /* run the type specific filter code */
  smpte->process (smpte, in_frame, out_frame,
      smpte->mask, border, ((1 << smpte->depth) + border) * position);
  GST_OBJECT_UNLOCK (smpte);

  return GST_FLOW_OK;

  /* ERRORS */
not_negotiated:
  {
    GST_ELEMENT_ERROR (smpte, CORE, NEGOTIATION, (NULL),
        ("No input format negotiated"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

static GstCaps *
gst_smpte_alpha_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * from, GstCaps * filter)
{
  GstCaps *result, *tmp_caps, *tmpl_caps = NULL;
  gint i, j;

  tmp_caps = gst_caps_new_empty ();

  for (i = 0; i < gst_caps_get_size (from); i++) {
    GstStructure *structure;
    const GValue *val, *lval;
    GValue list = { 0, };
    GValue aval = { 0, };
    const gchar *str;

    structure = gst_structure_copy (gst_caps_get_structure (from, i));
    /* we can transform I420 to AYUV,
     * so need to locate and substitute AYUV for the both of them */
    val = gst_structure_get_value (structure, "format");
    if (val && GST_VALUE_HOLDS_LIST (val)) {
      gboolean seen_ayuv = FALSE, seen_i420 = FALSE;

      g_value_init (&list, GST_TYPE_LIST);
      for (j = 0; j < gst_value_list_get_size (val); j++) {
        lval = gst_value_list_get_value (val, j);
        if ((str = g_value_get_string (lval))) {
          if (strcmp (str, "AYUV") == 0) {
            seen_ayuv = TRUE;
          } else if (strcmp (str, "I420") == 0) {
            seen_i420 = TRUE;
          }
        }
      }
      if (seen_ayuv && !seen_i420) {
        str = "I420";
      } else if (seen_i420 && !seen_ayuv) {
        str = "AYUV";
      } else
        str = NULL;
      if (str) {
        g_value_copy (val, &list);
        g_value_init (&aval, G_TYPE_STRING);
        g_value_set_string (&aval, str);
        gst_value_list_append_value (&list, &aval);
        g_value_reset (&aval);
        gst_structure_set_value (structure, "format", &list);
        g_value_unset (&list);
      }
    } else if (val && G_VALUE_HOLDS_STRING (val)) {
      if ((str = g_value_get_string (val)) &&
          ((strcmp (str, "AYUV") == 0) || (strcmp (str, "I420") == 0))) {
        g_value_init (&list, GST_TYPE_LIST);
        g_value_init (&aval, G_TYPE_STRING);
        g_value_set_string (&aval, "AYUV");
        gst_value_list_append_value (&list, &aval);
        g_value_reset (&aval);
        g_value_set_string (&aval, "I420");
        gst_value_list_append_value (&list, &aval);
        g_value_reset (&aval);
        gst_structure_set_value (structure, "format", &list);
        g_value_unset (&list);
      }
    } else {
      gst_structure_remove_field (structure, "format");
    }

    gst_structure_remove_field (structure, "colorimetry");
    gst_structure_remove_field (structure, "chroma-site");

    gst_caps_append_structure (tmp_caps, structure);
  }

  /* Get the appropriate template */
  if (direction == GST_PAD_SINK) {
    tmpl_caps =
        gst_static_pad_template_get_caps (&gst_smpte_alpha_src_template);
  } else if (direction == GST_PAD_SRC) {
    tmpl_caps =
        gst_static_pad_template_get_caps (&gst_smpte_alpha_sink_template);
  } else {
    g_assert_not_reached ();
  }

  /* Intersect with our template caps */
  result = gst_caps_intersect (tmp_caps, tmpl_caps);
  gst_caps_unref (tmpl_caps);
  gst_caps_unref (tmp_caps);

  result = gst_caps_simplify (result);

  GST_LOG_OBJECT (trans, "transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT,
      from, result);

  if (filter) {
    GstCaps *intersection;

    GST_DEBUG_OBJECT (trans, "Using filter caps %" GST_PTR_FORMAT, filter);
    intersection =
        gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (result);
    result = intersection;
    GST_DEBUG_OBJECT (trans, "Intersection %" GST_PTR_FORMAT, result);
  }

  return result;
}

static gboolean
gst_smpte_alpha_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
    GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
{
  GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter);
  gboolean ret;

  smpte->process = NULL;
  smpte->in_format = GST_VIDEO_INFO_FORMAT (in_info);
  smpte->out_format = GST_VIDEO_INFO_FORMAT (out_info);

  /* try to update the mask now, this will also adjust the width/height on
   * success */
  GST_OBJECT_LOCK (smpte);
  ret =
      gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert,
      smpte->depth, GST_VIDEO_INFO_WIDTH (out_info),
      GST_VIDEO_INFO_HEIGHT (out_info));
  GST_OBJECT_UNLOCK (smpte);

  if (!ret)
    goto mask_failed;

  switch (smpte->out_format) {
    case GST_VIDEO_FORMAT_AYUV:
      switch (smpte->in_format) {
        case GST_VIDEO_FORMAT_AYUV:
          smpte->process = gst_smpte_alpha_process_ayuv_ayuv;
          break;
        case GST_VIDEO_FORMAT_I420:
          smpte->process = gst_smpte_alpha_process_i420_ayuv;
          break;
        default:
          break;
      }
      break;
    case GST_VIDEO_FORMAT_ARGB:
      switch (smpte->in_format) {
        case GST_VIDEO_FORMAT_ARGB:
          smpte->process = gst_smpte_alpha_process_argb_argb;
          break;
        default:
          break;
      }
      break;
    case GST_VIDEO_FORMAT_RGBA:
      switch (smpte->in_format) {
        case GST_VIDEO_FORMAT_RGBA:
          smpte->process = gst_smpte_alpha_process_rgba_rgba;
          break;
        default:
          break;
      }
      break;
    case GST_VIDEO_FORMAT_ABGR:
      switch (smpte->in_format) {
        case GST_VIDEO_FORMAT_ABGR:
          smpte->process = gst_smpte_alpha_process_abgr_abgr;
          break;
        default:
          break;
      }
      break;
    case GST_VIDEO_FORMAT_BGRA:
      switch (smpte->in_format) {
        case GST_VIDEO_FORMAT_BGRA:
          smpte->process = gst_smpte_alpha_process_bgra_bgra;
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
mask_failed:
  {
    GST_ERROR_OBJECT (smpte, "failed creating the mask");
    return FALSE;
  }
}

static void
gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte)
{
  if (smpte->mask)
    gst_mask_destroy (smpte->mask);
  smpte->mask = NULL;

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) smpte);
}

static void
gst_smpte_alpha_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (object);

  switch (prop_id) {
    case PROP_TYPE:{
      gint type;

      type = g_value_get_enum (value);

      GST_OBJECT_LOCK (smpte);
      gst_smpte_alpha_update_mask (smpte, type, smpte->invert,
          smpte->depth, smpte->width, smpte->height);
      GST_OBJECT_UNLOCK (smpte);
      break;
    }
    case PROP_BORDER:
      GST_OBJECT_LOCK (smpte);
      smpte->border = g_value_get_int (value);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_DEPTH:{
      gint depth;

      depth = g_value_get_int (value);

      GST_OBJECT_LOCK (smpte);
      gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert,
          depth, smpte->width, smpte->height);
      GST_OBJECT_UNLOCK (smpte);
      break;
    }
    case PROP_POSITION:
      GST_OBJECT_LOCK (smpte);
      smpte->position = g_value_get_double (value);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_INVERT:{
      gboolean invert;

      invert = g_value_get_boolean (value);
      GST_OBJECT_LOCK (smpte);
      gst_smpte_alpha_update_mask (smpte, smpte->type, invert,
          smpte->depth, smpte->width, smpte->height);
      GST_OBJECT_UNLOCK (smpte);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_smpte_alpha_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstSMPTEAlpha *smpte;

  smpte = GST_SMPTE_ALPHA (object);

  switch (prop_id) {
    case PROP_TYPE:
      GST_OBJECT_LOCK (smpte);
      g_value_set_enum (value, smpte->type);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_BORDER:
      GST_OBJECT_LOCK (smpte);
      g_value_set_int (value, smpte->border);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_DEPTH:
      GST_OBJECT_LOCK (smpte);
      g_value_set_int (value, smpte->depth);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_POSITION:
      GST_OBJECT_LOCK (smpte);
      g_value_set_double (value, smpte->position);
      GST_OBJECT_UNLOCK (smpte);
      break;
    case PROP_INVERT:
      GST_OBJECT_LOCK (smpte);
      g_value_set_boolean (value, smpte->invert);
      GST_OBJECT_UNLOCK (smpte);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

gboolean
gst_smpte_alpha_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_smpte_alpha_debug, "smptealpha", 0,
      "SMPTE alpha effect");

  return gst_element_register (plugin, "smptealpha", GST_RANK_NONE,
      GST_TYPE_SMPTE_ALPHA);
}
