/* 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_pad_template (element_class,
      gst_static_pad_template_get (&gst_smpte_alpha_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&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);
}
