Blame gst/alpha/gstalpha.c

Packit 1f69a5
/* GStreamer
Packit 1f69a5
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
Packit 1f69a5
 * Copyright (C) <2007> Wim Taymans <wim.taymans@collabora.co.uk>
Packit 1f69a5
 * Copyright (C) <2007> Edward Hervey <edward.hervey@collabora.co.uk>
Packit 1f69a5
 * Copyright (C) <2007> Jan Schmidt <thaytan@noraisin.net>
Packit 1f69a5
 *
Packit 1f69a5
 * This library is free software; you can redistribute it and/or
Packit 1f69a5
 * modify it under the terms of the GNU Library General Public
Packit 1f69a5
 * License as published by the Free Software Foundation; either
Packit 1f69a5
 * version 2 of the License, or (at your option) any later version.
Packit 1f69a5
 *
Packit 1f69a5
 * This library is distributed in the hope that it will be useful,
Packit 1f69a5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1f69a5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 1f69a5
 * Library General Public License for more details.
Packit 1f69a5
 *
Packit 1f69a5
 * You should have received a copy of the GNU Library General Public
Packit 1f69a5
 * License along with this library; if not, write to the
Packit 1f69a5
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 1f69a5
 * Boston, MA 02110-1301, USA.
Packit 1f69a5
 */
Packit 1f69a5
Packit 1f69a5
/**
Packit 1f69a5
 * SECTION:element-alpha
Packit 1f69a5
 * 
Packit 1f69a5
 * The alpha element adds an alpha channel to a video stream. The values
Packit 1f69a5
 * of the alpha channel can be either be set to a constant or can be
Packit 1f69a5
 * dynamically calculated via chroma keying, e.g. blue can be set as
Packit 1f69a5
 * the transparent color.
Packit 1f69a5
 *
Packit 1f69a5
 * Sample pipeline:
Packit 1f69a5
 * |[
Packit 1f69a5
 * gst-launch-1.0 videotestsrc pattern=snow ! mixer.sink_0 \
Packit 1f69a5
 *   videotestsrc pattern=smpte75 ! alpha method=green ! mixer.sink_1 \
Packit 1f69a5
 *   videomixer name=mixer sink_0::zorder=0 sink_1::zorder=1 ! \
Packit 1f69a5
 *   videoconvert ! autovideosink
Packit 1f69a5
 * ]| This pipeline adds a alpha channel to the SMPTE color bars
Packit 1f69a5
 * with green as the transparent color and overlays the output on
Packit 1f69a5
 * top of a snow video stream.
Packit 1f69a5
 */
Packit 1f69a5
Packit 1f69a5
Packit 1f69a5
#ifdef HAVE_CONFIG_H
Packit 1f69a5
#include "config.h"
Packit 1f69a5
#endif
Packit 1f69a5
Packit 1f69a5
#include "gstalpha.h"
Packit 1f69a5
Packit 1f69a5
#include <stdlib.h>
Packit 1f69a5
#include <string.h>
Packit 1f69a5
#include <math.h>
Packit 1f69a5
Packit 1f69a5
#ifndef M_PI
Packit 1f69a5
#define M_PI  3.14159265358979323846
Packit 1f69a5
#endif
Packit 1f69a5
Packit 1f69a5
/* Generated by -bad/ext/cog/generate_tables */
Packit 1f69a5
static const int cog_ycbcr_to_rgb_matrix_8bit_hdtv[] = {
Packit 1f69a5
  298, 0, 459, -63514,
Packit 1f69a5
  298, -55, -136, 19681,
Packit 1f69a5
  298, 541, 0, -73988,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = {
Packit 1f69a5
  298, 0, 409, -57068,
Packit 1f69a5
  298, -100, -208, 34707,
Packit 1f69a5
  298, 516, 0, -70870,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static const gint cog_rgb_to_ycbcr_matrix_8bit_hdtv[] = {
Packit 1f69a5
  47, 157, 16, 4096,
Packit 1f69a5
  -26, -87, 112, 32768,
Packit 1f69a5
  112, -102, -10, 32768,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static const gint cog_rgb_to_ycbcr_matrix_8bit_sdtv[] = {
Packit 1f69a5
  66, 129, 25, 4096,
Packit 1f69a5
  -38, -74, 112, 32768,
Packit 1f69a5
  112, -94, -18, 32768,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static const gint cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit[] = {
Packit 1f69a5
  256, -30, -53, 10600,
Packit 1f69a5
  0, 261, 29, -4367,
Packit 1f69a5
  0, 19, 262, -3289,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static const gint cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit[] = {
Packit 1f69a5
  256, 25, 49, -9536,
Packit 1f69a5
  0, 253, -28, 3958,
Packit 1f69a5
  0, -19, 252, 2918,
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
/* Alpha signals and args */
Packit 1f69a5
enum
Packit 1f69a5
{
Packit 1f69a5
  /* FILL ME */
Packit 1f69a5
  LAST_SIGNAL
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
#define DEFAULT_METHOD ALPHA_METHOD_SET
Packit 1f69a5
#define DEFAULT_ALPHA 1.0
Packit 1f69a5
#define DEFAULT_TARGET_R 0
Packit 1f69a5
#define DEFAULT_TARGET_G 255
Packit 1f69a5
#define DEFAULT_TARGET_B 0
Packit 1f69a5
#define DEFAULT_ANGLE 20.0
Packit 1f69a5
#define DEFAULT_NOISE_LEVEL 2.0
Packit 1f69a5
#define DEFAULT_BLACK_SENSITIVITY 100
Packit 1f69a5
#define DEFAULT_WHITE_SENSITIVITY 100
Packit 1f69a5
#define DEFAULT_PREFER_PASSTHROUGH FALSE
Packit 1f69a5
Packit 1f69a5
enum
Packit 1f69a5
{
Packit 1f69a5
  PROP_0,
Packit 1f69a5
  PROP_METHOD,
Packit 1f69a5
  PROP_ALPHA,
Packit 1f69a5
  PROP_TARGET_R,
Packit 1f69a5
  PROP_TARGET_G,
Packit 1f69a5
  PROP_TARGET_B,
Packit 1f69a5
  PROP_ANGLE,
Packit 1f69a5
  PROP_NOISE_LEVEL,
Packit 1f69a5
  PROP_BLACK_SENSITIVITY,
Packit 1f69a5
  PROP_WHITE_SENSITIVITY,
Packit 1f69a5
  PROP_PREFER_PASSTHROUGH
Packit 1f69a5
};
Packit 1f69a5
Packit 1f69a5
static GstStaticPadTemplate gst_alpha_src_template =
Packit 1f69a5
GST_STATIC_PAD_TEMPLATE ("src",
Packit 1f69a5
    GST_PAD_SRC,
Packit 1f69a5
    GST_PAD_ALWAYS,
Packit 1f69a5
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
Packit 1f69a5
            "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, BGRx, xBGR, "
Packit 1f69a5
            "RGBx, RGB, BGR, Y42B, YUY2, YVYU, UYVY, I420, YV12, Y41B } "))
Packit 1f69a5
    );
Packit 1f69a5
Packit 1f69a5
static GstStaticPadTemplate gst_alpha_sink_template =
Packit 1f69a5
GST_STATIC_PAD_TEMPLATE ("sink",
Packit 1f69a5
    GST_PAD_SINK,
Packit 1f69a5
    GST_PAD_ALWAYS,
Packit 1f69a5
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
Packit 1f69a5
            "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, BGRx, xBGR, "
Packit 1f69a5
            "RGBx, RGB, BGR, Y42B, YUY2, YVYU, UYVY, I420, YV12, " "Y41B } "))
Packit 1f69a5
    );
Packit 1f69a5
Packit 1f69a5
static GstStaticCaps gst_alpha_alpha_caps =
Packit 1f69a5
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, ARGB, BGRA, ABGR, RGBA }"));
Packit 1f69a5
Packit 1f69a5
/* FIXME: why do we need our own lock for this? */
Packit 1f69a5
#define GST_ALPHA_LOCK(alpha) G_STMT_START { \
Packit 1f69a5
  GST_LOG_OBJECT (alpha, "Locking alpha from thread %p", g_thread_self ()); \
Packit 1f69a5
  g_mutex_lock (&alpha->lock); \
Packit 1f69a5
  GST_LOG_OBJECT (alpha, "Locked alpha from thread %p", g_thread_self ()); \
Packit 1f69a5
} G_STMT_END
Packit 1f69a5
Packit 1f69a5
#define GST_ALPHA_UNLOCK(alpha) G_STMT_START { \
Packit 1f69a5
  GST_LOG_OBJECT (alpha, "Unlocking alpha from thread %p", g_thread_self ()); \
Packit 1f69a5
  g_mutex_unlock (&alpha->lock); \
Packit 1f69a5
} G_STMT_END
Packit 1f69a5
Packit 1f69a5
static GstCaps *gst_alpha_transform_caps (GstBaseTransform * btrans,
Packit 1f69a5
    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
Packit 1f69a5
static void gst_alpha_before_transform (GstBaseTransform * btrans,
Packit 1f69a5
    GstBuffer * buf);
Packit 1f69a5
Packit 1f69a5
static gboolean gst_alpha_set_info (GstVideoFilter * filter,
Packit 1f69a5
    GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
Packit 1f69a5
    GstVideoInfo * out_info);
Packit 1f69a5
static GstFlowReturn gst_alpha_transform_frame (GstVideoFilter * filter,
Packit 1f69a5
    GstVideoFrame * in_frame, GstVideoFrame * out_frame);
Packit 1f69a5
Packit 1f69a5
static void gst_alpha_init_params_full (GstAlpha * alpha,
Packit 1f69a5
    const GstVideoFormatInfo * in_info, const GstVideoFormatInfo * out_info);
Packit 1f69a5
static void gst_alpha_init_params (GstAlpha * alpha);
Packit 1f69a5
static void gst_alpha_set_process_function (GstAlpha * alpha);
Packit 1f69a5
static gboolean gst_alpha_set_process_function_full (GstAlpha * alpha,
Packit 1f69a5
    GstVideoInfo * in_info, GstVideoInfo * out_info);
Packit 1f69a5
Packit 1f69a5
static void gst_alpha_set_property (GObject * object, guint prop_id,
Packit 1f69a5
    const GValue * value, GParamSpec * pspec);
Packit 1f69a5
static void gst_alpha_get_property (GObject * object, guint prop_id,
Packit 1f69a5
    GValue * value, GParamSpec * pspec);
Packit 1f69a5
static void gst_alpha_finalize (GObject * object);
Packit 1f69a5
Packit 1f69a5
#define gst_alpha_parent_class parent_class
Packit 1f69a5
G_DEFINE_TYPE (GstAlpha, gst_alpha, GST_TYPE_VIDEO_FILTER);
Packit 1f69a5
Packit 1f69a5
#define GST_TYPE_ALPHA_METHOD (gst_alpha_method_get_type())
Packit 1f69a5
static GType
Packit 1f69a5
gst_alpha_method_get_type (void)
Packit 1f69a5
{
Packit 1f69a5
  static GType alpha_method_type = 0;
Packit 1f69a5
  static const GEnumValue alpha_method[] = {
Packit 1f69a5
    {ALPHA_METHOD_SET, "Set/adjust alpha channel", "set"},
Packit 1f69a5
    {ALPHA_METHOD_GREEN, "Chroma Key on pure green", "green"},
Packit 1f69a5
    {ALPHA_METHOD_BLUE, "Chroma Key on pure blue", "blue"},
Packit 1f69a5
    {ALPHA_METHOD_CUSTOM, "Chroma Key on custom RGB values", "custom"},
Packit 1f69a5
    {0, NULL, NULL},
Packit 1f69a5
  };
Packit 1f69a5
Packit 1f69a5
  if (!alpha_method_type) {
Packit 1f69a5
    alpha_method_type = g_enum_register_static ("GstAlphaMethod", alpha_method);
Packit 1f69a5
  }
Packit 1f69a5
  return alpha_method_type;
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_class_init (GstAlphaClass * klass)
Packit 1f69a5
{
Packit 1f69a5
  GObjectClass *gobject_class = (GObjectClass *) klass;
Packit 1f69a5
  GstElementClass *gstelement_class = (GstElementClass *) klass;
Packit 1f69a5
  GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
Packit 1f69a5
  GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;
Packit 1f69a5
Packit 1f69a5
  GST_DEBUG_CATEGORY_INIT (gst_alpha_debug, "alpha", 0,
Packit 1f69a5
      "alpha - Element for adding alpha channel to streams");
Packit 1f69a5
Packit 1f69a5
  gobject_class->set_property = gst_alpha_set_property;
Packit 1f69a5
  gobject_class->get_property = gst_alpha_get_property;
Packit 1f69a5
  gobject_class->finalize = gst_alpha_finalize;
Packit 1f69a5
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_METHOD,
Packit 1f69a5
      g_param_spec_enum ("method", "Method",
Packit 1f69a5
          "How the alpha channels should be created", GST_TYPE_ALPHA_METHOD,
Packit 1f69a5
          DEFAULT_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ALPHA,
Packit 1f69a5
      g_param_spec_double ("alpha", "Alpha", "The value for the alpha channel",
Packit 1f69a5
          0.0, 1.0, DEFAULT_ALPHA,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_R,
Packit 1f69a5
      g_param_spec_uint ("target-r", "Target Red",
Packit 1f69a5
          "The red color value for custom RGB chroma keying", 0, 255,
Packit 1f69a5
          DEFAULT_TARGET_R,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_G,
Packit 1f69a5
      g_param_spec_uint ("target-g", "Target Green",
Packit 1f69a5
          "The green color value for custom RGB chroma keying", 0, 255,
Packit 1f69a5
          DEFAULT_TARGET_G,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TARGET_B,
Packit 1f69a5
      g_param_spec_uint ("target-b", "Target Blue",
Packit 1f69a5
          "The blue color value for custom RGB chroma keying", 0, 255,
Packit 1f69a5
          DEFAULT_TARGET_B,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ANGLE,
Packit 1f69a5
      g_param_spec_float ("angle", "Angle", "Size of the colorcube to change",
Packit 1f69a5
          0.0, 90.0, DEFAULT_ANGLE,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NOISE_LEVEL,
Packit 1f69a5
      g_param_spec_float ("noise-level", "Noise Level", "Size of noise radius",
Packit 1f69a5
          0.0, 64.0, DEFAULT_NOISE_LEVEL,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass),
Packit 1f69a5
      PROP_BLACK_SENSITIVITY, g_param_spec_uint ("black-sensitivity",
Packit 1f69a5
          "Black Sensitivity", "Sensitivity to dark colors", 0, 128,
Packit 1f69a5
          DEFAULT_BLACK_SENSITIVITY,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass),
Packit 1f69a5
      PROP_WHITE_SENSITIVITY, g_param_spec_uint ("white-sensitivity",
Packit 1f69a5
          "White Sensitivity", "Sensitivity to bright colors", 0, 128,
Packit 1f69a5
          DEFAULT_WHITE_SENSITIVITY,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
  g_object_class_install_property (G_OBJECT_CLASS (klass),
Packit 1f69a5
      PROP_PREFER_PASSTHROUGH, g_param_spec_boolean ("prefer-passthrough",
Packit 1f69a5
          "Prefer Passthrough",
Packit 1f69a5
          "Don't do any processing for alpha=1.0 if possible",
Packit 1f69a5
          DEFAULT_PREFER_PASSTHROUGH,
Packit 1f69a5
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
Packit 1f69a5
Packit 1f69a5
  gst_element_class_set_static_metadata (gstelement_class, "Alpha filter",
Packit 1f69a5
      "Filter/Effect/Video",
Packit 1f69a5
      "Adds an alpha channel to video - uniform or via chroma-keying",
Packit 1f69a5
      "Wim Taymans <wim.taymans@gmail.com>\n"
Packit 1f69a5
      "Edward Hervey <edward.hervey@collabora.co.uk>\n"
Packit 1f69a5
      "Jan Schmidt <thaytan@noraisin.net>");
Packit 1f69a5
Packit 1f69a5
  gst_element_class_add_static_pad_template (gstelement_class,
Packit 1f69a5
      &gst_alpha_sink_template);
Packit 1f69a5
  gst_element_class_add_static_pad_template (gstelement_class,
Packit 1f69a5
      &gst_alpha_src_template);
Packit 1f69a5
Packit 1f69a5
  btrans_class->before_transform =
Packit 1f69a5
      GST_DEBUG_FUNCPTR (gst_alpha_before_transform);
Packit 1f69a5
  btrans_class->transform_caps = GST_DEBUG_FUNCPTR (gst_alpha_transform_caps);
Packit 1f69a5
Packit 1f69a5
  vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_alpha_set_info);
Packit 1f69a5
  vfilter_class->transform_frame =
Packit 1f69a5
      GST_DEBUG_FUNCPTR (gst_alpha_transform_frame);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_init (GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  alpha->alpha = DEFAULT_ALPHA;
Packit 1f69a5
  alpha->method = DEFAULT_METHOD;
Packit 1f69a5
  alpha->target_r = DEFAULT_TARGET_R;
Packit 1f69a5
  alpha->target_g = DEFAULT_TARGET_G;
Packit 1f69a5
  alpha->target_b = DEFAULT_TARGET_B;
Packit 1f69a5
  alpha->angle = DEFAULT_ANGLE;
Packit 1f69a5
  alpha->noise_level = DEFAULT_NOISE_LEVEL;
Packit 1f69a5
  alpha->black_sensitivity = DEFAULT_BLACK_SENSITIVITY;
Packit 1f69a5
  alpha->white_sensitivity = DEFAULT_WHITE_SENSITIVITY;
Packit 1f69a5
Packit 1f69a5
  g_mutex_init (&alpha->lock);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_finalize (GObject * object)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (object);
Packit 1f69a5
Packit 1f69a5
  g_mutex_clear (&alpha->lock);
Packit 1f69a5
Packit 1f69a5
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_property (GObject * object, guint prop_id,
Packit 1f69a5
    const GValue * value, GParamSpec * pspec)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (object);
Packit 1f69a5
  gboolean reconfigure = FALSE;
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_LOCK (alpha);
Packit 1f69a5
  switch (prop_id) {
Packit 1f69a5
    case PROP_METHOD:{
Packit 1f69a5
      gint method = g_value_get_enum (value);
Packit 1f69a5
Packit 1f69a5
      reconfigure = (method != alpha->method) && (method == ALPHA_METHOD_SET
Packit 1f69a5
          || alpha->method == ALPHA_METHOD_SET) && (alpha->alpha == 1.0)
Packit 1f69a5
          && (alpha->prefer_passthrough);
Packit 1f69a5
      alpha->method = method;
Packit 1f69a5
Packit 1f69a5
      gst_alpha_set_process_function (alpha);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    }
Packit 1f69a5
    case PROP_ALPHA:{
Packit 1f69a5
      gdouble a = g_value_get_double (value);
Packit 1f69a5
Packit 1f69a5
      reconfigure = (a != alpha->alpha) && (a == 1.0 || alpha->alpha == 1.0)
Packit 1f69a5
          && (alpha->method == ALPHA_METHOD_SET) && (alpha->prefer_passthrough);
Packit 1f69a5
      alpha->alpha = a;
Packit 1f69a5
      break;
Packit 1f69a5
    }
Packit 1f69a5
    case PROP_TARGET_R:
Packit 1f69a5
      alpha->target_r = g_value_get_uint (value);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_TARGET_G:
Packit 1f69a5
      alpha->target_g = g_value_get_uint (value);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_TARGET_B:
Packit 1f69a5
      alpha->target_b = g_value_get_uint (value);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_ANGLE:
Packit 1f69a5
      alpha->angle = g_value_get_float (value);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_NOISE_LEVEL:
Packit 1f69a5
      alpha->noise_level = g_value_get_float (value);
Packit 1f69a5
      gst_alpha_init_params (alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_BLACK_SENSITIVITY:
Packit 1f69a5
      alpha->black_sensitivity = g_value_get_uint (value);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_WHITE_SENSITIVITY:
Packit 1f69a5
      alpha->white_sensitivity = g_value_get_uint (value);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_PREFER_PASSTHROUGH:{
Packit 1f69a5
      gboolean prefer_passthrough = g_value_get_boolean (value);
Packit 1f69a5
Packit 1f69a5
      reconfigure = ((! !prefer_passthrough) != (! !alpha->prefer_passthrough))
Packit 1f69a5
          && (alpha->method == ALPHA_METHOD_SET) && (alpha->alpha == 1.0);
Packit 1f69a5
      alpha->prefer_passthrough = prefer_passthrough;
Packit 1f69a5
      break;
Packit 1f69a5
    }
Packit 1f69a5
    default:
Packit 1f69a5
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 1f69a5
      break;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  if (reconfigure)
Packit 1f69a5
    gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM_CAST (alpha));
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_get_property (GObject * object, guint prop_id, GValue * value,
Packit 1f69a5
    GParamSpec * pspec)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (object);
Packit 1f69a5
Packit 1f69a5
  switch (prop_id) {
Packit 1f69a5
    case PROP_METHOD:
Packit 1f69a5
      g_value_set_enum (value, alpha->method);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_ALPHA:
Packit 1f69a5
      g_value_set_double (value, alpha->alpha);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_TARGET_R:
Packit 1f69a5
      g_value_set_uint (value, alpha->target_r);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_TARGET_G:
Packit 1f69a5
      g_value_set_uint (value, alpha->target_g);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_TARGET_B:
Packit 1f69a5
      g_value_set_uint (value, alpha->target_b);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_ANGLE:
Packit 1f69a5
      g_value_set_float (value, alpha->angle);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_NOISE_LEVEL:
Packit 1f69a5
      g_value_set_float (value, alpha->noise_level);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_BLACK_SENSITIVITY:
Packit 1f69a5
      g_value_set_uint (value, alpha->black_sensitivity);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_WHITE_SENSITIVITY:
Packit 1f69a5
      g_value_set_uint (value, alpha->white_sensitivity);
Packit 1f69a5
      break;
Packit 1f69a5
    case PROP_PREFER_PASSTHROUGH:
Packit 1f69a5
      g_value_set_boolean (value, alpha->prefer_passthrough);
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 1f69a5
      break;
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static GstCaps *
Packit 1f69a5
gst_alpha_transform_caps (GstBaseTransform * btrans,
Packit 1f69a5
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (btrans);
Packit 1f69a5
  GstCaps *ret, *tmp, *tmp2;
Packit 1f69a5
  GstStructure *structure;
Packit 1f69a5
  gint i;
Packit 1f69a5
Packit 1f69a5
  tmp = gst_caps_new_empty ();
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_LOCK (alpha);
Packit 1f69a5
  for (i = 0; i < gst_caps_get_size (caps); i++) {
Packit 1f69a5
    structure = gst_structure_copy (gst_caps_get_structure (caps, i));
Packit 1f69a5
Packit 1f69a5
    gst_structure_remove_field (structure, "format");
Packit 1f69a5
    gst_structure_remove_field (structure, "colorimetry");
Packit 1f69a5
    gst_structure_remove_field (structure, "chroma-site");
Packit 1f69a5
Packit 1f69a5
    gst_caps_append_structure (tmp, structure);
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  if (direction == GST_PAD_SINK) {
Packit 1f69a5
    tmp2 = gst_static_caps_get (&gst_alpha_alpha_caps);
Packit 1f69a5
    ret = gst_caps_intersect (tmp, tmp2);
Packit 1f69a5
    gst_caps_unref (tmp);
Packit 1f69a5
    gst_caps_unref (tmp2);
Packit 1f69a5
    tmp = ret;
Packit 1f69a5
    ret = NULL;
Packit 1f69a5
Packit 1f69a5
    if (alpha->prefer_passthrough && alpha->method == ALPHA_METHOD_SET
Packit 1f69a5
        && alpha->alpha == 1.0) {
Packit 1f69a5
      ret = gst_caps_copy (caps);
Packit 1f69a5
      gst_caps_append (ret, tmp);
Packit 1f69a5
      tmp = NULL;
Packit 1f69a5
    } else {
Packit 1f69a5
      ret = tmp;
Packit 1f69a5
      tmp = NULL;
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    ret = tmp;
Packit 1f69a5
    tmp = NULL;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  GST_DEBUG_OBJECT (alpha,
Packit 1f69a5
      "Transformed %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT, caps, ret);
Packit 1f69a5
Packit 1f69a5
  if (filter) {
Packit 1f69a5
    GstCaps *intersection;
Packit 1f69a5
Packit 1f69a5
    GST_DEBUG_OBJECT (alpha, "Using filter caps %" GST_PTR_FORMAT, filter);
Packit 1f69a5
    intersection =
Packit 1f69a5
        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
Packit 1f69a5
    gst_caps_unref (ret);
Packit 1f69a5
    ret = intersection;
Packit 1f69a5
    GST_DEBUG_OBJECT (alpha, "Intersection %" GST_PTR_FORMAT, ret);
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
Packit 1f69a5
  return ret;
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static gboolean
Packit 1f69a5
gst_alpha_set_info (GstVideoFilter * filter,
Packit 1f69a5
    GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
Packit 1f69a5
    GstVideoInfo * out_info)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (filter);
Packit 1f69a5
  gboolean passthrough;
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_LOCK (alpha);
Packit 1f69a5
Packit 1f69a5
  alpha->in_sdtv = in_info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601;
Packit 1f69a5
  alpha->out_sdtv =
Packit 1f69a5
      out_info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_BT601;
Packit 1f69a5
Packit 1f69a5
  passthrough = alpha->prefer_passthrough &&
Packit 1f69a5
      GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_INFO_FORMAT (out_info)
Packit 1f69a5
      && alpha->in_sdtv == alpha->out_sdtv && alpha->method == ALPHA_METHOD_SET
Packit 1f69a5
      && alpha->alpha == 1.0;
Packit 1f69a5
Packit 1f69a5
  GST_DEBUG_OBJECT (alpha,
Packit 1f69a5
      "Setting caps %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT
Packit 1f69a5
      " (passthrough: %d)", incaps, outcaps, passthrough);
Packit 1f69a5
  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM_CAST (filter),
Packit 1f69a5
      passthrough);
Packit 1f69a5
Packit 1f69a5
  if (!gst_alpha_set_process_function_full (alpha, in_info, out_info)
Packit 1f69a5
      && !passthrough)
Packit 1f69a5
    goto no_process;
Packit 1f69a5
Packit 1f69a5
  gst_alpha_init_params_full (alpha, in_info->finfo, out_info->finfo);
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
Packit 1f69a5
  return TRUE;
Packit 1f69a5
Packit 1f69a5
  /* ERRORS */
Packit 1f69a5
no_process:
Packit 1f69a5
  {
Packit 1f69a5
    GST_WARNING_OBJECT (alpha,
Packit 1f69a5
        "No processing function for this caps and no passthrough mode");
Packit 1f69a5
    GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
    return FALSE;
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
/* based on http://www.cs.utah.edu/~michael/chroma/
Packit 1f69a5
 */
Packit 1f69a5
static inline gint
Packit 1f69a5
chroma_keying_yuv (gint a, gint * y, gint * u,
Packit 1f69a5
    gint * v, gint cr, gint cb, gint smin, gint smax, guint8 accept_angle_tg,
Packit 1f69a5
    guint8 accept_angle_ctg, guint8 one_over_kc, guint8 kfgy_scale, gint8 kg,
Packit 1f69a5
    guint noise_level2)
Packit 1f69a5
{
Packit 1f69a5
  gint tmp, tmp1;
Packit 1f69a5
  gint x1, y1;
Packit 1f69a5
  gint x, z;
Packit 1f69a5
  gint b_alpha;
Packit 1f69a5
Packit 1f69a5
  /* too dark or too bright, keep alpha */
Packit 1f69a5
  if (*y < smin || *y > smax)
Packit 1f69a5
    return a;
Packit 1f69a5
Packit 1f69a5
  /* Convert foreground to XZ coords where X direction is defined by
Packit 1f69a5
     the key color */
Packit 1f69a5
  tmp = ((*u) * cb + (*v) * cr) >> 7;
Packit 1f69a5
  x = CLAMP (tmp, -128, 127);
Packit 1f69a5
  tmp = ((*v) * cb - (*u) * cr) >> 7;
Packit 1f69a5
  z = CLAMP (tmp, -128, 127);
Packit 1f69a5
Packit 1f69a5
  /* WARNING: accept angle should never be set greater than "somewhat less
Packit 1f69a5
     than 90 degrees" to avoid dealing with negative/infinite tg. In reality,
Packit 1f69a5
     80 degrees should be enough if foreground is reasonable. If this seems
Packit 1f69a5
     to be a problem, go to alternative ways of checking point position
Packit 1f69a5
     (scalar product or line equations). This angle should not be too small
Packit 1f69a5
     either to avoid infinite ctg (used to suppress foreground without use of
Packit 1f69a5
     division) */
Packit 1f69a5
Packit 1f69a5
  tmp = (x * accept_angle_tg) >> 4;
Packit 1f69a5
  tmp = MIN (tmp, 127);
Packit 1f69a5
Packit 1f69a5
  if (abs (z) > tmp) {
Packit 1f69a5
    /* keep foreground Kfg = 0 */
Packit 1f69a5
    return a;
Packit 1f69a5
  }
Packit 1f69a5
  /* Compute Kfg (implicitly) and Kbg, suppress foreground in XZ coord
Packit 1f69a5
     according to Kfg */
Packit 1f69a5
  tmp = (z * accept_angle_ctg) >> 4;
Packit 1f69a5
  tmp = CLAMP (tmp, -128, 127);
Packit 1f69a5
  x1 = abs (tmp);
Packit 1f69a5
  y1 = z;
Packit 1f69a5
Packit 1f69a5
  tmp1 = x - x1;
Packit 1f69a5
  tmp1 = MAX (tmp1, 0);
Packit 1f69a5
  b_alpha = (tmp1 * one_over_kc) / 2;
Packit 1f69a5
  b_alpha = 255 - CLAMP (b_alpha, 0, 255);
Packit 1f69a5
  b_alpha = (a * b_alpha) >> 8;
Packit 1f69a5
Packit 1f69a5
  tmp = (tmp1 * kfgy_scale) >> 4;
Packit 1f69a5
  tmp1 = MIN (tmp, 255);
Packit 1f69a5
Packit 1f69a5
  *y = (*y < tmp1) ? 0 : *y - tmp1;
Packit 1f69a5
Packit 1f69a5
  /* Convert suppressed foreground back to CbCr */
Packit 1f69a5
  tmp = (x1 * cb - y1 * cr) >> 7;
Packit 1f69a5
  *u = CLAMP (tmp, -128, 127);
Packit 1f69a5
Packit 1f69a5
  tmp = (x1 * cr + y1 * cb) >> 7;
Packit 1f69a5
  *v = CLAMP (tmp, -128, 127);
Packit 1f69a5
Packit 1f69a5
  /* Deal with noise. For now, a circle around the key color with
Packit 1f69a5
     radius of noise_level treated as exact key color. Introduces
Packit 1f69a5
     sharp transitions.
Packit 1f69a5
   */
Packit 1f69a5
  tmp = z * z + (x - kg) * (x - kg);
Packit 1f69a5
  tmp = MIN (tmp, 0xffff);
Packit 1f69a5
Packit 1f69a5
  if (tmp < noise_level2)
Packit 1f69a5
    b_alpha = 0;
Packit 1f69a5
Packit 1f69a5
  return b_alpha;
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
#define APPLY_MATRIX(m,o,v1,v2,v3) ((m[o*4] * v1 + m[o*4+1] * v2 + m[o*4+2] * v3 + m[o*4+3]) >> 8)
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_argb_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint y, u, v;
Packit 1f69a5
  gint o[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 3);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
      cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      dest[0] = (src[o[0]] * s_alpha) >> 8;
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, src[o[1]], src[o[2]], src[o[3]]);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, src[o[1]], src[o[2]], src[o[3]]);
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, src[o[1]], src[o[2]], src[o[3]]);
Packit 1f69a5
Packit 1f69a5
      dest[1] = y;
Packit 1f69a5
      dest[2] = u;
Packit 1f69a5
      dest[3] = v;
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      src += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_argb_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint o[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 3);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
      cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = (src[o[0]] * pa) >> 8;
Packit 1f69a5
      r = src[o[1]];
Packit 1f69a5
      g = src[o[2]];
Packit 1f69a5
      b = src[o[3]];
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, r, g, b);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, r, g, b) - 128;
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, r, g, b) - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      dest[0] = a;
Packit 1f69a5
      dest[1] = y;
Packit 1f69a5
      dest[2] = u;
Packit 1f69a5
      dest[3] = v;
Packit 1f69a5
Packit 1f69a5
      src += 4;
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_argb_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint p[4], o[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 3);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      dest[p[0]] = (src[o[0]] * s_alpha) >> 8;
Packit 1f69a5
Packit 1f69a5
      dest[p[1]] = src[o[1]];
Packit 1f69a5
      dest[p[2]] = src[o[2]];
Packit 1f69a5
      dest[p[3]] = src[o[3]];
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      src += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_argb_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12], matrix2[12];
Packit 1f69a5
  gint p[4], o[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 3);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix, cog_rgb_to_ycbcr_matrix_8bit_sdtv, 12 * sizeof (gint));
Packit 1f69a5
  memcpy (matrix2, cog_ycbcr_to_rgb_matrix_8bit_sdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = (src[o[0]] * pa) >> 8;
Packit 1f69a5
      r = src[o[1]];
Packit 1f69a5
      g = src[o[2]];
Packit 1f69a5
      b = src[o[3]];
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, r, g, b);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, r, g, b) - 128;
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, r, g, b) - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix2, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix2, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix2, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      src += 4;
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_ayuv_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint y, x;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint p[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (y = 0; y < height; y++) {
Packit 1f69a5
    for (x = 0; x < width; x++) {
Packit 1f69a5
      dest[p[0]] = (src[0] * s_alpha) >> 8;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]);
Packit 1f69a5
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      src += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_ayuv_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint p[4];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = (src[0] * pa) >> 8;
Packit 1f69a5
      y = src[1];
Packit 1f69a5
      u = src[2] - 128;
Packit 1f69a5
      v = src[3] - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      src += 4;
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_ayuv_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint y, x;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv == alpha->out_sdtv) {
Packit 1f69a5
    for (y = 0; y < height; y++) {
Packit 1f69a5
      for (x = 0; x < width; x++) {
Packit 1f69a5
        dest[0] = (src[0] * s_alpha) >> 8;
Packit 1f69a5
        dest[1] = src[1];
Packit 1f69a5
        dest[2] = src[2];
Packit 1f69a5
        dest[3] = src[3];
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (y = 0; y < height; y++) {
Packit 1f69a5
      for (x = 0; x < width; x++) {
Packit 1f69a5
        dest[0] = (src[0] * s_alpha) >> 8;
Packit 1f69a5
        dest[1] = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]);
Packit 1f69a5
        dest[2] = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]);
Packit 1f69a5
        dest[3] = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]);
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_ayuv_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv == alpha->out_sdtv) {
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        a = (src[0] * pa) >> 8;
Packit 1f69a5
        y = src[1];
Packit 1f69a5
        u = src[2] - 128;
Packit 1f69a5
        v = src[3] - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        u += 128;
Packit 1f69a5
        v += 128;
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        src += 4;
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        a = (src[0] * pa) >> 8;
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]) - 128;
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]) - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        u += 128;
Packit 1f69a5
        v += 128;
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        src += 4;
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_rgb_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint y, u, v;
Packit 1f69a5
  gint o[3];
Packit 1f69a5
  gint bpp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
      cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      dest[0] = s_alpha;
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[2]]);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[2]]);
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[2]]);
Packit 1f69a5
Packit 1f69a5
      dest[1] = y;
Packit 1f69a5
      dest[2] = u;
Packit 1f69a5
      dest[3] = v;
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      src += bpp;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_rgb_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint o[3];
Packit 1f69a5
  gint bpp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
      cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = pa;
Packit 1f69a5
      r = src[o[0]];
Packit 1f69a5
      g = src[o[1]];
Packit 1f69a5
      b = src[o[2]];
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, r, g, b);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, r, g, b) - 128;
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, r, g, b) - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      dest[0] = a;
Packit 1f69a5
      dest[1] = y;
Packit 1f69a5
      dest[2] = u;
Packit 1f69a5
      dest[3] = v;
Packit 1f69a5
Packit 1f69a5
      src += bpp;
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_rgb_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint p[4], o[3];
Packit 1f69a5
  gint bpp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      dest[p[0]] = s_alpha;
Packit 1f69a5
Packit 1f69a5
      dest[p[1]] = src[o[0]];
Packit 1f69a5
      dest[p[2]] = src[o[1]];
Packit 1f69a5
      dest[p[3]] = src[o[2]];
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      src += bpp;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_rgb_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12], matrix2[12];
Packit 1f69a5
  gint p[4], o[3];
Packit 1f69a5
  gint bpp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[2] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix, cog_rgb_to_ycbcr_matrix_8bit_sdtv, 12 * sizeof (gint));
Packit 1f69a5
  memcpy (matrix2, cog_ycbcr_to_rgb_matrix_8bit_sdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = pa;
Packit 1f69a5
      r = src[o[0]];
Packit 1f69a5
      g = src[o[1]];
Packit 1f69a5
      b = src[o[2]];
Packit 1f69a5
Packit 1f69a5
      y = APPLY_MATRIX (matrix, 0, r, g, b);
Packit 1f69a5
      u = APPLY_MATRIX (matrix, 1, r, g, b) - 128;
Packit 1f69a5
      v = APPLY_MATRIX (matrix, 2, r, g, b) - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix2, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix2, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix2, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      src += bpp;
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_planar_yuv_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  const guint8 *srcY, *srcY_tmp;
Packit 1f69a5
  const guint8 *srcU, *srcU_tmp;
Packit 1f69a5
  const guint8 *srcV, *srcV_tmp;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint y_stride, uv_stride;
Packit 1f69a5
  gint v_subs, h_subs;
Packit 1f69a5
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
  uv_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
Packit 1f69a5
Packit 1f69a5
  srcY_tmp = srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
Packit 1f69a5
  srcU_tmp = srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
Packit 1f69a5
  srcV_tmp = srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  switch (GST_VIDEO_FRAME_FORMAT (in_frame)) {
Packit 1f69a5
    case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
    case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
      v_subs = h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
      v_subs = h_subs = 1;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 4;
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      g_assert_not_reached ();
Packit 1f69a5
      return;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv == alpha->out_sdtv) {
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        dest[0] = b_alpha;
Packit 1f69a5
        dest[1] = srcY[0];
Packit 1f69a5
        dest[2] = srcU[0];
Packit 1f69a5
        dest[3] = srcV[0];
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        srcY++;
Packit 1f69a5
        if ((j + 1) % h_subs == 0) {
Packit 1f69a5
          srcU++;
Packit 1f69a5
          srcV++;
Packit 1f69a5
        }
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
      if ((i + 1) % v_subs == 0) {
Packit 1f69a5
        srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
        srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
      } else {
Packit 1f69a5
        srcU = srcU_tmp;
Packit 1f69a5
        srcV = srcV_tmp;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
    gint a, y, u, v;
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        a = b_alpha;
Packit 1f69a5
        y = srcY[0];
Packit 1f69a5
        u = srcU[0];
Packit 1f69a5
        v = srcV[0];
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
        dest[2] = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
        dest[3] = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        srcY++;
Packit 1f69a5
        if ((j + 1) % h_subs == 0) {
Packit 1f69a5
          srcU++;
Packit 1f69a5
          srcV++;
Packit 1f69a5
        }
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
      if ((i + 1) % v_subs == 0) {
Packit 1f69a5
        srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
        srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
      } else {
Packit 1f69a5
        srcU = srcU_tmp;
Packit 1f69a5
        srcV = srcV_tmp;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_planar_yuv_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  const guint8 *srcY, *srcY_tmp;
Packit 1f69a5
  const guint8 *srcU, *srcU_tmp;
Packit 1f69a5
  const guint8 *srcV, *srcV_tmp;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint y_stride, uv_stride;
Packit 1f69a5
  gint v_subs, h_subs;
Packit 1f69a5
  gint smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  gint smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
  uv_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
Packit 1f69a5
Packit 1f69a5
  srcY_tmp = srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
Packit 1f69a5
  srcU_tmp = srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
Packit 1f69a5
  srcV_tmp = srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  switch (GST_VIDEO_FRAME_FORMAT (in_frame)) {
Packit 1f69a5
    case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
    case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
      v_subs = h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
      v_subs = h_subs = 1;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 4;
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      g_assert_not_reached ();
Packit 1f69a5
      return;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv == alpha->out_sdtv) {
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        a = b_alpha;
Packit 1f69a5
        y = srcY[0];
Packit 1f69a5
        u = srcU[0] - 128;
Packit 1f69a5
        v = srcV[0] - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin,
Packit 1f69a5
            smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        u += 128;
Packit 1f69a5
        v += 128;
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        srcY++;
Packit 1f69a5
        if ((j + 1) % h_subs == 0) {
Packit 1f69a5
          srcU++;
Packit 1f69a5
          srcV++;
Packit 1f69a5
        }
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
      if ((i + 1) % v_subs == 0) {
Packit 1f69a5
        srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
        srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
      } else {
Packit 1f69a5
        srcU = srcU_tmp;
Packit 1f69a5
        srcV = srcV_tmp;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      for (j = 0; j < width; j++) {
Packit 1f69a5
        a = b_alpha;
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]) - 128;
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]) - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin,
Packit 1f69a5
            smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u + 128;
Packit 1f69a5
        dest[3] = v + 128;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
        srcY++;
Packit 1f69a5
        if ((j + 1) % h_subs == 0) {
Packit 1f69a5
          srcU++;
Packit 1f69a5
          srcV++;
Packit 1f69a5
        }
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
      if ((i + 1) % v_subs == 0) {
Packit 1f69a5
        srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
        srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
      } else {
Packit 1f69a5
        srcU = srcU_tmp;
Packit 1f69a5
        srcV = srcV_tmp;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_planar_yuv_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  const guint8 *srcY, *srcY_tmp;
Packit 1f69a5
  const guint8 *srcU, *srcU_tmp;
Packit 1f69a5
  const guint8 *srcV, *srcV_tmp;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint y_stride, uv_stride;
Packit 1f69a5
  gint v_subs, h_subs;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint p[4];
Packit 1f69a5
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
  uv_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
Packit 1f69a5
Packit 1f69a5
  srcY_tmp = srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
Packit 1f69a5
  srcU_tmp = srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
Packit 1f69a5
  srcV_tmp = srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  switch (GST_VIDEO_FRAME_FORMAT (in_frame)) {
Packit 1f69a5
    case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
    case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
      v_subs = h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
      v_subs = h_subs = 1;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 4;
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      g_assert_not_reached ();
Packit 1f69a5
      return;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = b_alpha;
Packit 1f69a5
      y = srcY[0];
Packit 1f69a5
      u = srcU[0];
Packit 1f69a5
      v = srcV[0];
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      srcY++;
Packit 1f69a5
      if ((j + 1) % h_subs == 0) {
Packit 1f69a5
        srcU++;
Packit 1f69a5
        srcV++;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
    if ((i + 1) % v_subs == 0) {
Packit 1f69a5
      srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
      srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
    } else {
Packit 1f69a5
      srcU = srcU_tmp;
Packit 1f69a5
      srcV = srcV_tmp;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_planar_yuv_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  const guint8 *srcY, *srcY_tmp;
Packit 1f69a5
  const guint8 *srcU, *srcU_tmp;
Packit 1f69a5
  const guint8 *srcV, *srcV_tmp;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint y_stride, uv_stride;
Packit 1f69a5
  gint v_subs, h_subs;
Packit 1f69a5
  gint smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  gint smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint p[4];
Packit 1f69a5
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
  uv_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
Packit 1f69a5
Packit 1f69a5
  srcY_tmp = srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
Packit 1f69a5
  srcU_tmp = srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
Packit 1f69a5
  srcV_tmp = srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  switch (GST_VIDEO_FRAME_FORMAT (in_frame)) {
Packit 1f69a5
    case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
    case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
      v_subs = h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
      v_subs = h_subs = 1;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 2;
Packit 1f69a5
      break;
Packit 1f69a5
    case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
      v_subs = 1;
Packit 1f69a5
      h_subs = 4;
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      g_assert_not_reached ();
Packit 1f69a5
      return;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    for (j = 0; j < width; j++) {
Packit 1f69a5
      a = b_alpha;
Packit 1f69a5
      y = srcY[0];
Packit 1f69a5
      u = srcU[0] - 128;
Packit 1f69a5
      v = srcV[0] - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin,
Packit 1f69a5
          smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
      srcY++;
Packit 1f69a5
      if ((j + 1) % h_subs == 0) {
Packit 1f69a5
        srcU++;
Packit 1f69a5
        srcV++;
Packit 1f69a5
      }
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    srcY_tmp = srcY = srcY_tmp + y_stride;
Packit 1f69a5
    if ((i + 1) % v_subs == 0) {
Packit 1f69a5
      srcU_tmp = srcU = srcU_tmp + uv_stride;
Packit 1f69a5
      srcV_tmp = srcV = srcV_tmp + uv_stride;
Packit 1f69a5
    } else {
Packit 1f69a5
      srcU = srcU_tmp;
Packit 1f69a5
      srcV = srcV_tmp;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_packed_422_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint y, u, v;
Packit 1f69a5
  gint p[4];                    /* Y U Y V */
Packit 1f69a5
  gint src_stride;
Packit 1f69a5
  const guint8 *src_tmp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  src_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  p[2] = p[0] + 2;
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv != alpha->out_sdtv) {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->in_sdtv ? cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      src_tmp = src;
Packit 1f69a5
Packit 1f69a5
      for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
        dest[0] = s_alpha;
Packit 1f69a5
        dest[4] = s_alpha;
Packit 1f69a5
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[2]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[2]], src[p[1]], src[p[3]]);
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[2]], src[p[1]], src[p[3]]);
Packit 1f69a5
Packit 1f69a5
        dest[5] = y;
Packit 1f69a5
        dest[6] = u;
Packit 1f69a5
        dest[7] = v;
Packit 1f69a5
Packit 1f69a5
        dest += 8;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      if (j == width - 1) {
Packit 1f69a5
        dest[0] = s_alpha;
Packit 1f69a5
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      src = src_tmp + src_stride;
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      src_tmp = src;
Packit 1f69a5
Packit 1f69a5
      for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
        dest[0] = s_alpha;
Packit 1f69a5
        dest[4] = s_alpha;
Packit 1f69a5
Packit 1f69a5
        y = src[p[0]];
Packit 1f69a5
        u = src[p[1]];
Packit 1f69a5
        v = src[p[3]];
Packit 1f69a5
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        y = src[p[2]];
Packit 1f69a5
Packit 1f69a5
        dest[5] = y;
Packit 1f69a5
        dest[6] = u;
Packit 1f69a5
        dest[7] = v;
Packit 1f69a5
Packit 1f69a5
        dest += 8;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      if (j == width - 1) {
Packit 1f69a5
        dest[0] = s_alpha;
Packit 1f69a5
Packit 1f69a5
        y = src[p[0]];
Packit 1f69a5
        u = src[p[1]];
Packit 1f69a5
        v = src[p[3]];
Packit 1f69a5
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u;
Packit 1f69a5
        dest[3] = v;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      src = src_tmp + src_stride;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_packed_422_ayuv (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint p[4];                    /* Y U Y V */
Packit 1f69a5
  gint src_stride;
Packit 1f69a5
  const guint8 *src_tmp;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  src_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  p[2] = p[0] + 2;
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  if (alpha->in_sdtv != alpha->out_sdtv) {
Packit 1f69a5
    gint matrix[12];
Packit 1f69a5
Packit 1f69a5
    memcpy (matrix,
Packit 1f69a5
        alpha->in_sdtv ? cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit :
Packit 1f69a5
        cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      src_tmp = src;
Packit 1f69a5
Packit 1f69a5
      for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u + 128;
Packit 1f69a5
        dest[3] = v + 128;
Packit 1f69a5
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[2]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[2]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[2]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[4] = a;
Packit 1f69a5
        dest[5] = y;
Packit 1f69a5
        dest[6] = u + 128;
Packit 1f69a5
        dest[7] = v + 128;
Packit 1f69a5
Packit 1f69a5
        dest += 8;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      if (j == width - 1) {
Packit 1f69a5
        y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]);
Packit 1f69a5
        u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
        v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]) - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u + 128;
Packit 1f69a5
        dest[3] = v + 128;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      src = src_tmp + src_stride;
Packit 1f69a5
    }
Packit 1f69a5
  } else {
Packit 1f69a5
    for (i = 0; i < height; i++) {
Packit 1f69a5
      src_tmp = src;
Packit 1f69a5
Packit 1f69a5
      for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
        y = src[p[0]];
Packit 1f69a5
        u = src[p[1]] - 128;
Packit 1f69a5
        v = src[p[3]] - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u + 128;
Packit 1f69a5
        dest[3] = v + 128;
Packit 1f69a5
Packit 1f69a5
        y = src[p[2]];
Packit 1f69a5
        u = src[p[1]] - 128;
Packit 1f69a5
        v = src[p[3]] - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[4] = a;
Packit 1f69a5
        dest[5] = y;
Packit 1f69a5
        dest[6] = u + 128;
Packit 1f69a5
        dest[7] = v + 128;
Packit 1f69a5
Packit 1f69a5
        dest += 8;
Packit 1f69a5
        src += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      if (j == width - 1) {
Packit 1f69a5
        y = src[p[0]];
Packit 1f69a5
        u = src[p[1]] - 128;
Packit 1f69a5
        v = src[p[3]] - 128;
Packit 1f69a5
Packit 1f69a5
        a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
            smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
            one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
Packit 1f69a5
        dest[0] = a;
Packit 1f69a5
        dest[1] = y;
Packit 1f69a5
        dest[2] = u + 128;
Packit 1f69a5
        dest[3] = v + 128;
Packit 1f69a5
Packit 1f69a5
        dest += 4;
Packit 1f69a5
      }
Packit 1f69a5
Packit 1f69a5
      src = src_tmp + src_stride;
Packit 1f69a5
    }
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_packed_422_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint p[4], o[4];
Packit 1f69a5
  gint src_stride;
Packit 1f69a5
  const guint8 *src_tmp;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  src_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = o[0] + 2;
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    src_tmp = src;
Packit 1f69a5
Packit 1f69a5
    for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = s_alpha;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, src[o[2]], src[o[1]], src[o[3]]);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, src[o[2]], src[o[1]], src[o[3]]);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, src[o[2]], src[o[1]], src[o[3]]);
Packit 1f69a5
Packit 1f69a5
      dest[4 + p[0]] = s_alpha;
Packit 1f69a5
      dest[4 + p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[4 + p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[4 + p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 8;
Packit 1f69a5
      src += 4;
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    if (j == width - 1) {
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[3]]);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = s_alpha;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    src = src_tmp + src_stride;
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_chroma_key_packed_422_argb (const GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame, GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const guint8 *src;
Packit 1f69a5
  guint8 *dest;
Packit 1f69a5
  gint width, height;
Packit 1f69a5
  gint i, j;
Packit 1f69a5
  gint a, y, u, v;
Packit 1f69a5
  gint r, g, b;
Packit 1f69a5
  gint smin, smax;
Packit 1f69a5
  gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255);
Packit 1f69a5
  gint8 cb = alpha->cb, cr = alpha->cr;
Packit 1f69a5
  gint8 kg = alpha->kg;
Packit 1f69a5
  guint8 accept_angle_tg = alpha->accept_angle_tg;
Packit 1f69a5
  guint8 accept_angle_ctg = alpha->accept_angle_ctg;
Packit 1f69a5
  guint8 one_over_kc = alpha->one_over_kc;
Packit 1f69a5
  guint8 kfgy_scale = alpha->kfgy_scale;
Packit 1f69a5
  guint noise_level2 = alpha->noise_level2;
Packit 1f69a5
  gint p[4], o[4];
Packit 1f69a5
  gint src_stride;
Packit 1f69a5
  const guint8 *src_tmp;
Packit 1f69a5
  gint matrix[12];
Packit 1f69a5
Packit 1f69a5
  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
Packit 1f69a5
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
Packit 1f69a5
Packit 1f69a5
  width = GST_VIDEO_FRAME_WIDTH (in_frame);
Packit 1f69a5
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
Packit 1f69a5
Packit 1f69a5
  src_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
Packit 1f69a5
Packit 1f69a5
  o[0] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 0);
Packit 1f69a5
  o[2] = o[0] + 2;
Packit 1f69a5
  o[1] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 1);
Packit 1f69a5
  o[3] = GST_VIDEO_FRAME_COMP_POFFSET (in_frame, 2);
Packit 1f69a5
Packit 1f69a5
  p[0] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 3);
Packit 1f69a5
  p[1] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 0);
Packit 1f69a5
  p[2] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 1);
Packit 1f69a5
  p[3] = GST_VIDEO_FRAME_COMP_POFFSET (out_frame, 2);
Packit 1f69a5
Packit 1f69a5
  memcpy (matrix,
Packit 1f69a5
      alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
Packit 1f69a5
      cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
Packit 1f69a5
Packit 1f69a5
  smin = 128 - alpha->black_sensitivity;
Packit 1f69a5
  smax = 128 + alpha->white_sensitivity;
Packit 1f69a5
Packit 1f69a5
  for (i = 0; i < height; i++) {
Packit 1f69a5
    src_tmp = src;
Packit 1f69a5
Packit 1f69a5
    for (j = 0; j < width - 1; j += 2) {
Packit 1f69a5
      y = src[o[0]];
Packit 1f69a5
      u = src[o[1]] - 128;
Packit 1f69a5
      v = src[o[3]] - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      y = src[o[2]];
Packit 1f69a5
      u = src[o[1]] - 128;
Packit 1f69a5
      v = src[o[3]] - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[4 + p[0]] = a;
Packit 1f69a5
      dest[4 + p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[4 + p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[4 + p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 8;
Packit 1f69a5
      src += 4;
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    if (j == width - 1) {
Packit 1f69a5
      y = src[o[0]];
Packit 1f69a5
      u = src[o[1]] - 128;
Packit 1f69a5
      v = src[o[3]] - 128;
Packit 1f69a5
Packit 1f69a5
      a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb,
Packit 1f69a5
          smin, smax, accept_angle_tg, accept_angle_ctg,
Packit 1f69a5
          one_over_kc, kfgy_scale, kg, noise_level2);
Packit 1f69a5
      u += 128;
Packit 1f69a5
      v += 128;
Packit 1f69a5
Packit 1f69a5
      r = APPLY_MATRIX (matrix, 0, y, u, v);
Packit 1f69a5
      g = APPLY_MATRIX (matrix, 1, y, u, v);
Packit 1f69a5
      b = APPLY_MATRIX (matrix, 2, y, u, v);
Packit 1f69a5
Packit 1f69a5
      dest[p[0]] = a;
Packit 1f69a5
      dest[p[1]] = CLAMP (r, 0, 255);
Packit 1f69a5
      dest[p[2]] = CLAMP (g, 0, 255);
Packit 1f69a5
      dest[p[3]] = CLAMP (b, 0, 255);
Packit 1f69a5
Packit 1f69a5
      dest += 4;
Packit 1f69a5
    }
Packit 1f69a5
Packit 1f69a5
    src = src_tmp + src_stride;
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
/* Protected with the alpha lock */
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_init_params_full (GstAlpha * alpha,
Packit 1f69a5
    const GstVideoFormatInfo * in_info, const GstVideoFormatInfo * out_info)
Packit 1f69a5
{
Packit 1f69a5
  gfloat kgl;
Packit 1f69a5
  gfloat tmp;
Packit 1f69a5
  gfloat tmp1, tmp2;
Packit 1f69a5
  gfloat y;
Packit 1f69a5
  guint target_r = alpha->target_r;
Packit 1f69a5
  guint target_g = alpha->target_g;
Packit 1f69a5
  guint target_b = alpha->target_b;
Packit 1f69a5
  const gint *matrix;
Packit 1f69a5
Packit 1f69a5
  switch (alpha->method) {
Packit 1f69a5
    case ALPHA_METHOD_GREEN:
Packit 1f69a5
      target_r = 0;
Packit 1f69a5
      target_g = 255;
Packit 1f69a5
      target_b = 0;
Packit 1f69a5
      break;
Packit 1f69a5
    case ALPHA_METHOD_BLUE:
Packit 1f69a5
      target_r = 0;
Packit 1f69a5
      target_g = 0;
Packit 1f69a5
      target_b = 255;
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      break;
Packit 1f69a5
  }
Packit 1f69a5
Packit 1f69a5
  /* RGB->RGB: convert to SDTV YUV, chroma keying, convert back
Packit 1f69a5
   * YUV->RGB: chroma keying, convert to RGB
Packit 1f69a5
   * RGB->YUV: convert to YUV, chroma keying
Packit 1f69a5
   * YUV->YUV: convert matrix, chroma keying
Packit 1f69a5
   */
Packit 1f69a5
  if (GST_VIDEO_FORMAT_INFO_IS_RGB (in_info)
Packit 1f69a5
      && GST_VIDEO_FORMAT_INFO_IS_RGB (out_info))
Packit 1f69a5
    matrix = cog_rgb_to_ycbcr_matrix_8bit_sdtv;
Packit 1f69a5
  else if (GST_VIDEO_FORMAT_INFO_IS_YUV (in_info)
Packit 1f69a5
      && GST_VIDEO_FORMAT_INFO_IS_RGB (out_info))
Packit 1f69a5
    matrix =
Packit 1f69a5
        (alpha->in_sdtv) ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
        cog_rgb_to_ycbcr_matrix_8bit_hdtv;
Packit 1f69a5
  else if (GST_VIDEO_FORMAT_INFO_IS_RGB (in_info)
Packit 1f69a5
      && GST_VIDEO_FORMAT_INFO_IS_YUV (out_info))
Packit 1f69a5
    matrix =
Packit 1f69a5
        (alpha->out_sdtv) ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
        cog_rgb_to_ycbcr_matrix_8bit_hdtv;
Packit 1f69a5
  else                          /* yuv -> yuv */
Packit 1f69a5
    matrix =
Packit 1f69a5
        (alpha->out_sdtv) ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
Packit 1f69a5
        cog_rgb_to_ycbcr_matrix_8bit_hdtv;
Packit 1f69a5
Packit 1f69a5
  y = (matrix[0] * ((gint) target_r) +
Packit 1f69a5
      matrix[1] * ((gint) target_g) +
Packit 1f69a5
      matrix[2] * ((gint) target_b) + matrix[3]) >> 8;
Packit 1f69a5
  /* Cb,Cr without offset here because the chroma keying
Packit 1f69a5
   * works with them being in range [-128,127]
Packit 1f69a5
   */
Packit 1f69a5
  tmp1 =
Packit 1f69a5
      (matrix[4] * ((gint) target_r) +
Packit 1f69a5
      matrix[5] * ((gint) target_g) + matrix[6] * ((gint) target_b)) >> 8;
Packit 1f69a5
  tmp2 =
Packit 1f69a5
      (matrix[8] * ((gint) target_r) +
Packit 1f69a5
      matrix[9] * ((gint) target_g) + matrix[10] * ((gint) target_b)) >> 8;
Packit 1f69a5
Packit 1f69a5
  kgl = sqrt (tmp1 * tmp1 + tmp2 * tmp2);
Packit 1f69a5
  alpha->cb = 127 * (tmp1 / kgl);
Packit 1f69a5
  alpha->cr = 127 * (tmp2 / kgl);
Packit 1f69a5
Packit 1f69a5
  tmp = 15 * tan (M_PI * alpha->angle / 180);
Packit 1f69a5
  tmp = MIN (tmp, 255);
Packit 1f69a5
  alpha->accept_angle_tg = tmp;
Packit 1f69a5
  tmp = 15 / tan (M_PI * alpha->angle / 180);
Packit 1f69a5
  tmp = MIN (tmp, 255);
Packit 1f69a5
  alpha->accept_angle_ctg = tmp;
Packit 1f69a5
  tmp = 1 / (kgl);
Packit 1f69a5
  alpha->one_over_kc = 255 * 2 * tmp - 255;
Packit 1f69a5
  tmp = 15 * y / kgl;
Packit 1f69a5
  tmp = MIN (tmp, 255);
Packit 1f69a5
  alpha->kfgy_scale = tmp;
Packit 1f69a5
  alpha->kg = MIN (kgl, 127);
Packit 1f69a5
Packit 1f69a5
  alpha->noise_level2 = alpha->noise_level * alpha->noise_level;
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_init_params (GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  const GstVideoFormatInfo *finfo_in, *finfo_out;
Packit 1f69a5
Packit 1f69a5
  finfo_in = GST_VIDEO_FILTER (alpha)->in_info.finfo;
Packit 1f69a5
  finfo_out = GST_VIDEO_FILTER (alpha)->out_info.finfo;
Packit 1f69a5
Packit 1f69a5
  if (finfo_in != NULL && finfo_out != NULL) {
Packit 1f69a5
    gst_alpha_init_params_full (alpha, finfo_in, finfo_out);
Packit 1f69a5
  } else {
Packit 1f69a5
    GST_DEBUG_OBJECT (alpha, "video formats not set yet");
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
/* Protected with the alpha lock */
Packit 1f69a5
static gboolean
Packit 1f69a5
gst_alpha_set_process_function_full (GstAlpha * alpha, GstVideoInfo * in_info,
Packit 1f69a5
    GstVideoInfo * out_info)
Packit 1f69a5
{
Packit 1f69a5
  alpha->process = NULL;
Packit 1f69a5
Packit 1f69a5
  switch (alpha->method) {
Packit 1f69a5
    case ALPHA_METHOD_SET:
Packit 1f69a5
      switch (GST_VIDEO_INFO_FORMAT (out_info)) {
Packit 1f69a5
        case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
          switch (GST_VIDEO_INFO_FORMAT (in_info)) {
Packit 1f69a5
            case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
              alpha->process = gst_alpha_set_ayuv_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
            case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
              alpha->process = gst_alpha_set_planar_yuv_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_YUY2:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YVYU:
Packit 1f69a5
            case GST_VIDEO_FORMAT_UYVY:
Packit 1f69a5
              alpha->process = gst_alpha_set_packed_422_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
              alpha->process = gst_alpha_set_argb_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_xRGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_xBGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGR:
Packit 1f69a5
              alpha->process = gst_alpha_set_rgb_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            default:
Packit 1f69a5
              break;
Packit 1f69a5
          }
Packit 1f69a5
          break;
Packit 1f69a5
        case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
        case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
        case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
        case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
          switch (GST_VIDEO_INFO_FORMAT (in_info)) {
Packit 1f69a5
            case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
              alpha->process = gst_alpha_set_ayuv_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
            case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
              alpha->process = gst_alpha_set_planar_yuv_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_YUY2:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YVYU:
Packit 1f69a5
            case GST_VIDEO_FORMAT_UYVY:
Packit 1f69a5
              alpha->process = gst_alpha_set_packed_422_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
              alpha->process = gst_alpha_set_argb_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_xRGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_xBGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGR:
Packit 1f69a5
              alpha->process = gst_alpha_set_rgb_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            default:
Packit 1f69a5
              break;
Packit 1f69a5
          }
Packit 1f69a5
          break;
Packit 1f69a5
        default:
Packit 1f69a5
          break;
Packit 1f69a5
      }
Packit 1f69a5
      break;
Packit 1f69a5
    case ALPHA_METHOD_GREEN:
Packit 1f69a5
    case ALPHA_METHOD_BLUE:
Packit 1f69a5
    case ALPHA_METHOD_CUSTOM:
Packit 1f69a5
      switch (GST_VIDEO_INFO_FORMAT (out_info)) {
Packit 1f69a5
        case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
          switch (GST_VIDEO_INFO_FORMAT (in_info)) {
Packit 1f69a5
            case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_ayuv_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
            case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_planar_yuv_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_YUY2:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YVYU:
Packit 1f69a5
            case GST_VIDEO_FORMAT_UYVY:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_packed_422_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_argb_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_xRGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_xBGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGR:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_rgb_ayuv;
Packit 1f69a5
              break;
Packit 1f69a5
            default:
Packit 1f69a5
              break;
Packit 1f69a5
          }
Packit 1f69a5
          break;
Packit 1f69a5
        case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
        case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
        case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
        case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
          switch (GST_VIDEO_INFO_FORMAT (in_info)) {
Packit 1f69a5
            case GST_VIDEO_FORMAT_AYUV:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_ayuv_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y444:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y42B:
Packit 1f69a5
            case GST_VIDEO_FORMAT_I420:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YV12:
Packit 1f69a5
            case GST_VIDEO_FORMAT_Y41B:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_planar_yuv_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_YUY2:
Packit 1f69a5
            case GST_VIDEO_FORMAT_YVYU:
Packit 1f69a5
            case GST_VIDEO_FORMAT_UYVY:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_packed_422_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_ARGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_ABGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBA:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRA:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_argb_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            case GST_VIDEO_FORMAT_xRGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_xBGR:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGBx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGRx:
Packit 1f69a5
            case GST_VIDEO_FORMAT_RGB:
Packit 1f69a5
            case GST_VIDEO_FORMAT_BGR:
Packit 1f69a5
              alpha->process = gst_alpha_chroma_key_rgb_argb;
Packit 1f69a5
              break;
Packit 1f69a5
            default:
Packit 1f69a5
              break;
Packit 1f69a5
          }
Packit 1f69a5
          break;
Packit 1f69a5
        default:
Packit 1f69a5
          break;
Packit 1f69a5
      }
Packit 1f69a5
      break;
Packit 1f69a5
    default:
Packit 1f69a5
      break;
Packit 1f69a5
  }
Packit 1f69a5
  return alpha->process != NULL;
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_set_process_function (GstAlpha * alpha)
Packit 1f69a5
{
Packit 1f69a5
  GstVideoInfo *info_in, *info_out;
Packit 1f69a5
Packit 1f69a5
  info_in = &GST_VIDEO_FILTER (alpha)->in_info;
Packit 1f69a5
  info_out = &GST_VIDEO_FILTER (alpha)->out_info;
Packit 1f69a5
Packit 1f69a5
  if (info_in->finfo != NULL && info_out->finfo != NULL) {
Packit 1f69a5
    gst_alpha_set_process_function_full (alpha, info_in, info_out);
Packit 1f69a5
  } else {
Packit 1f69a5
    GST_DEBUG_OBJECT (alpha, "video formats not set yet");
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static void
Packit 1f69a5
gst_alpha_before_transform (GstBaseTransform * btrans, GstBuffer * buf)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (btrans);
Packit 1f69a5
  GstClockTime timestamp;
Packit 1f69a5
Packit 1f69a5
  timestamp = gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME,
Packit 1f69a5
      GST_BUFFER_TIMESTAMP (buf));
Packit 1f69a5
  GST_LOG ("Got stream time of %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
Packit 1f69a5
  if (GST_CLOCK_TIME_IS_VALID (timestamp))
Packit 1f69a5
    gst_object_sync_values (GST_OBJECT (alpha), timestamp);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static GstFlowReturn
Packit 1f69a5
gst_alpha_transform_frame (GstVideoFilter * filter, GstVideoFrame * in_frame,
Packit 1f69a5
    GstVideoFrame * out_frame)
Packit 1f69a5
{
Packit 1f69a5
  GstAlpha *alpha = GST_ALPHA (filter);
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_LOCK (alpha);
Packit 1f69a5
Packit 1f69a5
  if (G_UNLIKELY (!alpha->process))
Packit 1f69a5
    goto not_negotiated;
Packit 1f69a5
Packit 1f69a5
  alpha->process (in_frame, out_frame, alpha);
Packit 1f69a5
Packit 1f69a5
  GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
Packit 1f69a5
  return GST_FLOW_OK;
Packit 1f69a5
Packit 1f69a5
  /* ERRORS */
Packit 1f69a5
not_negotiated:
Packit 1f69a5
  {
Packit 1f69a5
    GST_ERROR_OBJECT (alpha, "Not negotiated yet");
Packit 1f69a5
    GST_ALPHA_UNLOCK (alpha);
Packit 1f69a5
    return GST_FLOW_NOT_NEGOTIATED;
Packit 1f69a5
  }
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
static gboolean
Packit 1f69a5
plugin_init (GstPlugin * plugin)
Packit 1f69a5
{
Packit 1f69a5
  return gst_element_register (plugin, "alpha", GST_RANK_NONE, GST_TYPE_ALPHA);
Packit 1f69a5
}
Packit 1f69a5
Packit 1f69a5
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
Packit 1f69a5
    GST_VERSION_MINOR,
Packit 1f69a5
    alpha,
Packit 1f69a5
    "adds an alpha channel to video - constant or via chroma-keying",
Packit 1f69a5
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)