/* GStreamer Video Overlay Composition
 * Copyright (C) 2011 Intel Corporation
 * Copyright (C) 2011 Collabora Ltd.
 * Copyright (C) 2011 Tim-Philipp Müller <tim centricular net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstvideooverlaycomposition
 * @short_description: Video Buffer Overlay Compositions (Subtitles, Logos)
 *
 * <refsect2>
 * <para>
 * Functions to create and handle overlay compositions on video buffers.
 * </para>
 * <para>
 * An overlay composition describes one or more overlay rectangles to be
 * blended on top of a video buffer.
 * </para>
 * <para>
 * This API serves two main purposes:
 * <itemizedlist>
 * <listitem>
 * it can be used to attach overlay information (subtitles or logos)
 * to non-raw video buffers such as GL/VAAPI/VDPAU surfaces. The actual
 * blending of the overlay can then be done by e.g. the video sink that
 * processes these non-raw buffers.
 * </listitem>
 * <listitem>
 * it can also be used to blend overlay rectangles on top of raw video
 * buffers, thus consolidating blending functionality for raw video in
 * one place.
 * </listitem>
 * Together, this allows existing overlay elements to easily handle raw
 * and non-raw video as input in without major changes (once the overlays
 * have been put into a #GstOverlayComposition object anyway) - for raw
 * video the overlay can just use the blending function to blend the data
 * on top of the video, and for surface buffers it can just attach them to
 * the buffer and let the sink render the overlays.
 * </itemizedlist>
 * </para>
 * </refsect2>
 */

/* TODO:
 *  - provide accessors for seq_num and other fields (as needed)
 *  - allow overlay to set/get original pango markup string on/from rectangle
 */

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

#include "video-overlay-composition.h"
#include "video-blend.h"
#include "gstvideometa.h"
#include <string.h>

struct _GstVideoOverlayComposition
{
  GstMiniObject parent;

  guint num_rectangles;
  GstVideoOverlayRectangle **rectangles;

  /* lowest rectangle sequence number still used by the upstream
   * overlay element. This way a renderer maintaining some kind of
   * rectangles <-> surface cache can know when to free cached
   * surfaces/rectangles. */
  guint min_seq_num_used;

  /* sequence number for the composition (same series as rectangles) */
  guint seq_num;
};

struct _GstVideoOverlayRectangle
{
  GstMiniObject parent;

  /* Position on video frame and dimension of output rectangle in
   * output frame terms (already adjusted for the PAR of the output
   * frame). x/y can be negative (overlay will be clipped then) */
  gint x, y;
  guint render_width, render_height;

  /* Info on overlay pixels (format, width, height) */
  GstVideoInfo info;

  /* The flags associated to this rectangle */
  GstVideoOverlayFormatFlags flags;

  /* Refcounted blob of memory, no caps or timestamps */
  GstBuffer *pixels;

  /* FIXME: how to express source like text or pango markup?
   *        (just add source type enum + source buffer with data)
   *
   * FOR 0.10: always send pixel blobs, but attach source data in
   * addition (reason: if downstream changes, we can't renegotiate
   * that properly, if we just do a query of supported formats from
   * the start). Sink will just ignore pixels and use pango markup
   * from source data if it supports that.
   *
   * FOR 0.11: overlay should query formats (pango markup, pixels)
   * supported by downstream and then only send that. We can
   * renegotiate via the reconfigure event.
   */

  /* sequence number: useful for backends/renderers/sinks that want
   * to maintain a cache of rectangles <-> surfaces. The value of
   * the min_seq_num_used in the composition tells the renderer which
   * rectangles have expired. */
  guint seq_num;

  /* global alpha: global alpha value of the rectangle. Each each per-pixel
   * alpha value of image-data will be multiplied with the global alpha value
   * during blending.
   * Can be used for efficient fading in/out of overlay rectangles.
   * GstElements that render OverlayCompositions and don't support global alpha
   * should simply ignore it.*/
  gfloat global_alpha;

  /* track alpha-values already applied: */
  gfloat applied_global_alpha;
  /* store initial per-pixel alpha values: */
  guint8 *initial_alpha;

  /* FIXME: we may also need a (private) way to cache converted/scaled
   * pixel blobs */
  GMutex lock;

  GList *scaled_rectangles;
};

#define GST_RECTANGLE_LOCK(rect)   g_mutex_lock(&rect->lock)
#define GST_RECTANGLE_UNLOCK(rect) g_mutex_unlock(&rect->lock)

/* --------------------------- utility functions --------------------------- */

#ifndef GST_DISABLE_GST_DEBUG

#define GST_CAT_DEFAULT ensure_debug_category()

static GstDebugCategory *
ensure_debug_category (void)
{
  static gsize cat_gonce = 0;

  if (g_once_init_enter (&cat_gonce)) {
    gsize cat_done;

    cat_done = (gsize) _gst_debug_category_new ("video-composition", 0,
        "video overlay composition");

    g_once_init_leave (&cat_gonce, cat_done);
  }

  return (GstDebugCategory *) cat_gonce;
}

#else

#define ensure_debug_category() /* NOOP */

#endif /* GST_DISABLE_GST_DEBUG */

static guint
gst_video_overlay_get_seqnum (void)
{
  static gint seqnum;           /* 0 */

  return (guint) g_atomic_int_add (&seqnum, 1);
}

static void
gst_video_overlay_composition_meta_free (GstMeta * meta, GstBuffer * buf)
{
  GstVideoOverlayCompositionMeta *ometa;

  ometa = (GstVideoOverlayCompositionMeta *) meta;

  if (ometa->overlay)
    gst_video_overlay_composition_unref (ometa->overlay);
}

static gboolean
gst_video_overlay_composition_meta_transform (GstBuffer * dest, GstMeta * meta,
    GstBuffer * buffer, GQuark type, gpointer data)
{
  GstVideoOverlayCompositionMeta *dmeta, *smeta;

  smeta = (GstVideoOverlayCompositionMeta *) meta;

  if (GST_META_TRANSFORM_IS_COPY (type)) {
    GstMetaTransformCopy *copy = data;

    if (!copy->region) {
      GST_DEBUG ("copy video overlay composition metadata");

      /* only copy if the complete data is copied as well */
      dmeta =
          (GstVideoOverlayCompositionMeta *) gst_buffer_add_meta (dest,
          GST_VIDEO_OVERLAY_COMPOSITION_META_INFO, NULL);
      if (!dmeta)
        return FALSE;

      dmeta->overlay = gst_video_overlay_composition_ref (smeta->overlay);
    }
  } else {
    /* return FALSE, if transform type is not supported */
    return FALSE;
  }
  return TRUE;
}

GType
gst_video_overlay_composition_meta_api_get_type (void)
{
  static volatile GType type = 0;
  static const gchar *tags[] = { NULL };

  if (g_once_init_enter (&type)) {
    GType _type =
        gst_meta_api_type_register ("GstVideoOverlayCompositionMetaAPI", tags);
    g_once_init_leave (&type, _type);
  }
  return type;
}

/* video overlay composition metadata */
const GstMetaInfo *
gst_video_overlay_composition_meta_get_info (void)
{
  static const GstMetaInfo *video_overlay_composition_meta_info = NULL;

  if (g_once_init_enter (&video_overlay_composition_meta_info)) {
    const GstMetaInfo *meta =
        gst_meta_register (GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE,
        "GstVideoOverlayCompositionMeta",
        sizeof (GstVideoOverlayCompositionMeta), (GstMetaInitFunction) NULL,
        (GstMetaFreeFunction) gst_video_overlay_composition_meta_free,
        (GstMetaTransformFunction)
        gst_video_overlay_composition_meta_transform);
    g_once_init_leave (&video_overlay_composition_meta_info, meta);
  }
  return video_overlay_composition_meta_info;
}

/**
 * gst_buffer_add_video_overlay_composition_meta:
 * @buf: a #GstBuffer
 * @comp: (allow-none): a #GstVideoOverlayComposition
 *
 * Sets an overlay composition on a buffer. The buffer will obtain its own
 * reference to the composition, meaning this function does not take ownership
 * of @comp.
 *
 * Returns: (transfer none): a #GstVideoOverlayCompositionMeta
 */
GstVideoOverlayCompositionMeta *
gst_buffer_add_video_overlay_composition_meta (GstBuffer * buf,
    GstVideoOverlayComposition * comp)
{
  GstVideoOverlayCompositionMeta *ometa;

  g_return_val_if_fail (gst_buffer_is_writable (buf), NULL);

  ometa = (GstVideoOverlayCompositionMeta *)
      gst_buffer_add_meta (buf, GST_VIDEO_OVERLAY_COMPOSITION_META_INFO, NULL);

  ometa->overlay = gst_video_overlay_composition_ref (comp);

  return ometa;
}

/* ------------------------------ composition ------------------------------ */

#define RECTANGLE_ARRAY_STEP 4  /* premature optimization */

GST_DEFINE_MINI_OBJECT_TYPE (GstVideoOverlayComposition,
    gst_video_overlay_composition);

static void
gst_video_overlay_composition_free (GstMiniObject * mini_obj)
{
  GstVideoOverlayComposition *comp = (GstVideoOverlayComposition *) mini_obj;
  guint num;

  num = comp->num_rectangles;

  while (num > 0) {
    gst_video_overlay_rectangle_unref (comp->rectangles[num - 1]);
    --num;
  }

  g_free (comp->rectangles);
  comp->rectangles = NULL;
  comp->num_rectangles = 0;

  g_slice_free (GstVideoOverlayComposition, comp);
}

/**
 * gst_video_overlay_composition_new:
 * @rectangle: (transfer none): a #GstVideoOverlayRectangle to add to the
 *     composition
 *
 * Creates a new video overlay composition object to hold one or more
 * overlay rectangles.
 *
 * Returns: (transfer full): a new #GstVideoOverlayComposition. Unref with
 *     gst_video_overlay_composition_unref() when no longer needed.
 */
GstVideoOverlayComposition *
gst_video_overlay_composition_new (GstVideoOverlayRectangle * rectangle)
{
  GstVideoOverlayComposition *comp;


  /* FIXME: should we allow empty compositions? Could also be expressed as
   * buffer without a composition on it. Maybe there are cases where doing
   * an empty new + _add() in a loop is easier? */
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);

  comp = g_slice_new0 (GstVideoOverlayComposition);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (comp), 0,
      GST_TYPE_VIDEO_OVERLAY_COMPOSITION,
      (GstMiniObjectCopyFunction) gst_video_overlay_composition_copy,
      NULL, (GstMiniObjectFreeFunction) gst_video_overlay_composition_free);

  comp->rectangles = g_new0 (GstVideoOverlayRectangle *, RECTANGLE_ARRAY_STEP);
  comp->rectangles[0] = gst_video_overlay_rectangle_ref (rectangle);
  comp->num_rectangles = 1;

  comp->seq_num = gst_video_overlay_get_seqnum ();

  /* since the rectangle was created earlier, its seqnum is smaller than ours */
  comp->min_seq_num_used = rectangle->seq_num;

  GST_LOG ("new composition %p: seq_num %u with rectangle %p", comp,
      comp->seq_num, rectangle);

  return comp;
}

/**
 * gst_video_overlay_composition_add_rectangle:
 * @comp: a #GstVideoOverlayComposition
 * @rectangle: (transfer none): a #GstVideoOverlayRectangle to add to the
 *     composition
 *
 * Adds an overlay rectangle to an existing overlay composition object. This
 * must be done right after creating the overlay composition.
 */
void
gst_video_overlay_composition_add_rectangle (GstVideoOverlayComposition * comp,
    GstVideoOverlayRectangle * rectangle)
{
  g_return_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp));
  g_return_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle));
  g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (comp) == 1);

  if (comp->num_rectangles % RECTANGLE_ARRAY_STEP == 0) {
    comp->rectangles =
        g_renew (GstVideoOverlayRectangle *, comp->rectangles,
        comp->num_rectangles + RECTANGLE_ARRAY_STEP);
  }

  comp->rectangles[comp->num_rectangles] =
      gst_video_overlay_rectangle_ref (rectangle);
  comp->num_rectangles += 1;

  comp->min_seq_num_used = MIN (comp->min_seq_num_used, rectangle->seq_num);

  GST_LOG ("composition %p: added rectangle %p", comp, rectangle);
}

/**
 * gst_video_overlay_composition_n_rectangles:
 * @comp: a #GstVideoOverlayComposition
 *
 * Returns the number of #GstVideoOverlayRectangle<!-- -->s contained in @comp.
 *
 * Returns: the number of rectangles
 */
guint
gst_video_overlay_composition_n_rectangles (GstVideoOverlayComposition * comp)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), 0);

  return comp->num_rectangles;
}

/**
 * gst_video_overlay_composition_get_rectangle:
 * @comp: a #GstVideoOverlayComposition
 * @n: number of the rectangle to get
 *
 * Returns the @n-th #GstVideoOverlayRectangle contained in @comp.
 *
 * Returns: (transfer none): the @n-th rectangle, or NULL if @n is out of
 *     bounds. Will not return a new reference, the caller will need to
 *     obtain her own reference using gst_video_overlay_rectangle_ref()
 *     if needed.
 */
GstVideoOverlayRectangle *
gst_video_overlay_composition_get_rectangle (GstVideoOverlayComposition * comp,
    guint n)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL);

  if (n >= comp->num_rectangles)
    return NULL;

  return comp->rectangles[n];
}

static gboolean
gst_video_overlay_rectangle_needs_scaling (GstVideoOverlayRectangle * r)
{
  return (GST_VIDEO_INFO_WIDTH (&r->info) != r->render_width ||
      GST_VIDEO_INFO_HEIGHT (&r->info) != r->render_height);
}

/**
 * gst_video_overlay_composition_blend:
 * @comp: a #GstVideoOverlayComposition
 * @video_buf: a #GstVideoFrame containing raw video data in a supported format
 *
 * Blends the overlay rectangles in @comp on top of the raw video data
 * contained in @video_buf. The data in @video_buf must be writable and
 * mapped appropriately.
 */
/* FIXME: formats with more than 8 bit per component which get unpacked into
 * ARGB64 or AYUV64 (such as v210, v216, UYVP, GRAY16_LE and GRAY16_BE)
 * are not supported yet by the code in video-blend.c.
 */
gboolean
gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp,
    GstVideoFrame * video_buf)
{
  GstVideoInfo scaled_info;
  GstVideoInfo *vinfo;
  GstVideoFrame rectangle_frame;
  GstVideoFormat fmt;
  GstBuffer *pixels = NULL;
  gboolean ret = TRUE;
  guint n, num;
  int w, h;

  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), FALSE);
  g_return_val_if_fail (video_buf != NULL, FALSE);

  w = GST_VIDEO_FRAME_WIDTH (video_buf);
  h = GST_VIDEO_FRAME_HEIGHT (video_buf);
  fmt = GST_VIDEO_FRAME_FORMAT (video_buf);

  num = comp->num_rectangles;
  GST_LOG ("Blending composition %p with %u rectangles onto video buffer %p "
      "(%ux%u, format %u)", comp, num, video_buf, w, h, fmt);

  for (n = 0; n < num; ++n) {
    GstVideoOverlayRectangle *rect;
    gboolean needs_scaling;

    rect = comp->rectangles[n];

    GST_LOG (" rectangle %u %p: %ux%u, format %u", n, rect,
        GST_VIDEO_INFO_WIDTH (&rect->info), GST_VIDEO_INFO_HEIGHT (&rect->info),
        GST_VIDEO_INFO_FORMAT (&rect->info));

    needs_scaling = gst_video_overlay_rectangle_needs_scaling (rect);
    if (needs_scaling) {
      gst_video_blend_scale_linear_RGBA (&rect->info, rect->pixels,
          rect->render_height, rect->render_width, &scaled_info, &pixels);
      vinfo = &scaled_info;
    } else {
      pixels = gst_buffer_ref (rect->pixels);
      vinfo = &rect->info;
    }

    gst_video_frame_map (&rectangle_frame, vinfo, pixels, GST_MAP_READ);

    ret = gst_video_blend (video_buf, &rectangle_frame, rect->x, rect->y,
        rect->global_alpha);
    gst_video_frame_unmap (&rectangle_frame);
    if (!ret) {
      GST_WARNING ("Could not blend overlay rectangle onto video buffer");
    }

    /* FIXME: should cache scaled pixels in the rectangle struct */
    gst_buffer_unref (pixels);
  }

  return ret;
}

/**
 * gst_video_overlay_composition_copy:
 * @comp: (transfer none): a #GstVideoOverlayComposition to copy
 *
 * Makes a copy of @comp and all contained rectangles, so that it is possible
 * to modify the composition and contained rectangles (e.g. add additional
 * rectangles or change the render co-ordinates or render dimension). The
 * actual overlay pixel data buffers contained in the rectangles are not
 * copied.
 *
 * Returns: (transfer full): a new #GstVideoOverlayComposition equivalent
 *     to @comp.
 */
GstVideoOverlayComposition *
gst_video_overlay_composition_copy (GstVideoOverlayComposition * comp)
{
  GstVideoOverlayComposition *copy;
  GstVideoOverlayRectangle *rect;
  guint n;

  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL);

  if (G_LIKELY (comp->num_rectangles == 0))
    return gst_video_overlay_composition_new (NULL);

  rect = gst_video_overlay_rectangle_copy (comp->rectangles[0]);
  copy = gst_video_overlay_composition_new (rect);
  gst_video_overlay_rectangle_unref (rect);

  for (n = 1; n < comp->num_rectangles; ++n) {
    rect = gst_video_overlay_rectangle_copy (comp->rectangles[n]);
    gst_video_overlay_composition_add_rectangle (copy, rect);
    gst_video_overlay_rectangle_unref (rect);
  }

  return copy;
}

/**
 * gst_video_overlay_composition_make_writable:
 * @comp: (transfer full): a #GstVideoOverlayComposition to copy
 *
 * Takes ownership of @comp and returns a version of @comp that is writable
 * (i.e. can be modified). Will either return @comp right away, or create a
 * new writable copy of @comp and unref @comp itself. All the contained
 * rectangles will also be copied, but the actual overlay pixel data buffers
 * contained in the rectangles are not copied.
 *
 * Returns: (transfer full): a writable #GstVideoOverlayComposition
 *     equivalent to @comp.
 */
GstVideoOverlayComposition *
gst_video_overlay_composition_make_writable (GstVideoOverlayComposition * comp)
{
  GstVideoOverlayComposition *writable_comp;

  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), NULL);

  if (GST_MINI_OBJECT_REFCOUNT_VALUE (comp) == 1) {
    guint n;

    for (n = 0; n < comp->num_rectangles; ++n) {
      if (GST_MINI_OBJECT_REFCOUNT_VALUE (comp->rectangles[n]) != 1)
        goto copy;
    }
    return comp;
  }

copy:

  writable_comp = gst_video_overlay_composition_copy (comp);
  gst_video_overlay_composition_unref (comp);

  return writable_comp;
}

/**
 * gst_video_overlay_composition_get_seqnum:
 * @comp: a #GstVideoOverlayComposition
 *
 * Returns the sequence number of this composition. Sequence numbers are
 * monotonically increasing and unique for overlay compositions and rectangles
 * (meaning there will never be a rectangle with the same sequence number as
 * a composition).
 *
 * Returns: the sequence number of @comp
 */
guint
gst_video_overlay_composition_get_seqnum (GstVideoOverlayComposition * comp)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_COMPOSITION (comp), 0);

  return comp->seq_num;
}

/* ------------------------------ rectangles ------------------------------ -*/

GST_DEFINE_MINI_OBJECT_TYPE (GstVideoOverlayRectangle,
    gst_video_overlay_rectangle);

static void
gst_video_overlay_rectangle_free (GstMiniObject * mini_obj)
{
  GstVideoOverlayRectangle *rect = (GstVideoOverlayRectangle *) mini_obj;

  gst_buffer_replace (&rect->pixels, NULL);

  while (rect->scaled_rectangles != NULL) {
    GstVideoOverlayRectangle *scaled_rect = rect->scaled_rectangles->data;

    gst_video_overlay_rectangle_unref (scaled_rect);

    rect->scaled_rectangles =
        g_list_delete_link (rect->scaled_rectangles, rect->scaled_rectangles);
  }

  g_free (rect->initial_alpha);
  g_mutex_clear (&rect->lock);

  g_slice_free (GstVideoOverlayRectangle, rect);
}

static inline gboolean
gst_video_overlay_rectangle_check_flags (GstVideoOverlayFormatFlags flags)
{
  /* Check flags only contains flags we know about */
  return (flags & ~(GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA |
          GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)) == 0;
}

static gboolean
gst_video_overlay_rectangle_is_same_alpha_type (GstVideoOverlayFormatFlags
    flags1, GstVideoOverlayFormatFlags flags2)
{
  return ((flags1 ^ flags2) & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)
      == 0;
}


/**
 * gst_video_overlay_rectangle_new_raw:
 * @pixels: (transfer none): a #GstBuffer pointing to the pixel memory
 * @render_x: the X co-ordinate on the video where the top-left corner of this
 *     overlay rectangle should be rendered to
 * @render_y: the Y co-ordinate on the video where the top-left corner of this
 *     overlay rectangle should be rendered to
 * @render_width: the render width of this rectangle on the video
 * @render_height: the render height of this rectangle on the video
 * @flags: flags
 *
 * Creates a new video overlay rectangle with ARGB or AYUV pixel data.
 * The layout in case of ARGB of the components in memory is B-G-R-A
 * on little-endian platforms
 * (corresponding to #GST_VIDEO_FORMAT_BGRA) and A-R-G-B on big-endian
 * platforms (corresponding to #GST_VIDEO_FORMAT_ARGB). In other words,
 * pixels are treated as 32-bit words and the lowest 8 bits then contain
 * the blue component value and the highest 8 bits contain the alpha
 * component value. Unless specified in the flags, the RGB values are
 * non-premultiplied. This is the format that is used by most hardware,
 * and also many rendering libraries such as Cairo, for example.
 * The pixel data buffer must have #GstVideoMeta set.
 *
 * Returns: (transfer full): a new #GstVideoOverlayRectangle. Unref with
 *     gst_video_overlay_rectangle_unref() when no longer needed.
 */
GstVideoOverlayRectangle *
gst_video_overlay_rectangle_new_raw (GstBuffer * pixels,
    gint render_x, gint render_y, guint render_width, guint render_height,
    GstVideoOverlayFormatFlags flags)
{
  GstVideoOverlayRectangle *rect;
  GstVideoMeta *vmeta;
  GstVideoFormat format;
  guint width, height;

  g_return_val_if_fail (GST_IS_BUFFER (pixels), NULL);
  g_return_val_if_fail (render_height > 0 && render_width > 0, NULL);
  g_return_val_if_fail (gst_video_overlay_rectangle_check_flags (flags), NULL);

  /* buffer must have video meta with some expected settings */
  vmeta = gst_buffer_get_video_meta (pixels);
  g_return_val_if_fail (vmeta, NULL);
  g_return_val_if_fail (vmeta->format ==
      GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB ||
      vmeta->format == GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV, NULL);
  g_return_val_if_fail (vmeta->flags == GST_VIDEO_FRAME_FLAG_NONE, NULL);

  format = vmeta->format;
  width = vmeta->width;
  height = vmeta->height;

  /* technically ((height-1)*stride)+width might be okay too */
  g_return_val_if_fail (gst_buffer_get_size (pixels) >= height * width * 4,
      NULL);
  g_return_val_if_fail (height > 0 && width > 0, NULL);

  rect = g_slice_new0 (GstVideoOverlayRectangle);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (rect), 0,
      GST_TYPE_VIDEO_OVERLAY_RECTANGLE,
      (GstMiniObjectCopyFunction) gst_video_overlay_rectangle_copy,
      NULL, (GstMiniObjectFreeFunction) gst_video_overlay_rectangle_free);

  g_mutex_init (&rect->lock);

  rect->pixels = gst_buffer_ref (pixels);
  rect->scaled_rectangles = NULL;

  gst_video_info_init (&rect->info);
  gst_video_info_set_format (&rect->info, format, width, height);
  if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)
    rect->info.flags |= GST_VIDEO_FLAG_PREMULTIPLIED_ALPHA;

  rect->x = render_x;
  rect->y = render_y;
  rect->render_width = render_width;
  rect->render_height = render_height;

  rect->global_alpha = 1.0;
  rect->applied_global_alpha = 1.0;
  rect->initial_alpha = NULL;

  rect->flags = flags;

  rect->seq_num = gst_video_overlay_get_seqnum ();

  GST_LOG ("new rectangle %p: %ux%u => %ux%u @ %u,%u, seq_num %u, format %u, "
      "flags %x, pixels %p, global_alpha=%f", rect, width, height, render_width,
      render_height, render_x, render_y, rect->seq_num, format,
      rect->flags, pixels, rect->global_alpha);

  return rect;
}

/**
 * gst_video_overlay_rectangle_get_render_rectangle:
 * @rectangle: a #GstVideoOverlayRectangle
 * @render_x: (out) (allow-none): address where to store the X render offset
 * @render_y: (out) (allow-none): address where to store the Y render offset
 * @render_width: (out) (allow-none): address where to store the render width
 * @render_height: (out) (allow-none): address where to store the render height
 *
 * Retrieves the render position and render dimension of the overlay
 * rectangle on the video.
 *
 * Returns: TRUE if valid render dimensions were retrieved.
 */
gboolean
gst_video_overlay_rectangle_get_render_rectangle (GstVideoOverlayRectangle *
    rectangle, gint * render_x, gint * render_y, guint * render_width,
    guint * render_height)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), FALSE);

  if (render_x)
    *render_x = rectangle->x;
  if (render_y)
    *render_y = rectangle->y;
  if (render_width)
    *render_width = rectangle->render_width;
  if (render_height)
    *render_height = rectangle->render_height;

  return TRUE;
}

/**
 * gst_video_overlay_rectangle_set_render_rectangle:
 * @rectangle: a #GstVideoOverlayRectangle
 * @render_x: render X position of rectangle on video
 * @render_y: render Y position of rectangle on video
 * @render_width: render width of rectangle
 * @render_height: render height of rectangle
 *
 * Sets the render position and dimensions of the rectangle on the video.
 * This function is mainly for elements that modify the size of the video
 * in some way (e.g. through scaling or cropping) and need to adjust the
 * details of any overlays to match the operation that changed the size.
 *
 * @rectangle must be writable, meaning its refcount must be 1. You can
 * make the rectangles inside a #GstVideoOverlayComposition writable using
 * gst_video_overlay_composition_make_writable() or
 * gst_video_overlay_composition_copy().
 */
void
gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle *
    rectangle, gint render_x, gint render_y, guint render_width,
    guint render_height)
{
  g_return_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle));
  g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (rectangle) == 1);

  rectangle->x = render_x;
  rectangle->y = render_y;
  rectangle->render_width = render_width;
  rectangle->render_height = render_height;
}

/* FIXME: orc-ify */
static void
gst_video_overlay_rectangle_premultiply_0 (GstVideoFrame * frame)
{
  int i, j;
  for (j = 0; j < GST_VIDEO_FRAME_HEIGHT (frame); ++j) {
    guint8 *line;

    line = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
    line += GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) * j;
    for (i = 0; i < GST_VIDEO_FRAME_WIDTH (frame); ++i) {
      int a = line[0];
      line[1] = line[1] * a / 255;
      line[2] = line[2] * a / 255;
      line[3] = line[3] * a / 255;
      line += 4;
    }
  }
}

static void
gst_video_overlay_rectangle_premultiply_3 (GstVideoFrame * frame)
{
  int i, j;
  for (j = 0; j < GST_VIDEO_FRAME_HEIGHT (frame); ++j) {
    guint8 *line;

    line = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
    line += GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) * j;
    for (i = 0; i < GST_VIDEO_FRAME_WIDTH (frame); ++i) {
      int a = line[3];
      line[0] = line[0] * a / 255;
      line[1] = line[1] * a / 255;
      line[2] = line[2] * a / 255;
      line += 4;
    }
  }
}

static void
gst_video_overlay_rectangle_premultiply (GstVideoFrame * frame)
{
  gint alpha_offset;

  alpha_offset = GST_VIDEO_FRAME_COMP_POFFSET (frame, 3);
  switch (alpha_offset) {
    case 0:
      gst_video_overlay_rectangle_premultiply_0 (frame);
      break;
    case 3:
      gst_video_overlay_rectangle_premultiply_3 (frame);
      break;
    default:
      g_assert_not_reached ();
      break;
  }
}

/* FIXME: orc-ify */
static void
gst_video_overlay_rectangle_unpremultiply_0 (GstVideoFrame * frame)
{
  int i, j;
  for (j = 0; j < GST_VIDEO_FRAME_HEIGHT (frame); ++j) {
    guint8 *line;

    line = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
    line += GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) * j;
    for (i = 0; i < GST_VIDEO_FRAME_WIDTH (frame); ++i) {
      int a = line[0];
      if (a) {
        line[1] = MIN ((line[1] * 255 + a / 2) / a, 255);
        line[2] = MIN ((line[2] * 255 + a / 2) / a, 255);
        line[3] = MIN ((line[3] * 255 + a / 2) / a, 255);
      }
      line += 4;
    }
  }
}

static void
gst_video_overlay_rectangle_unpremultiply_3 (GstVideoFrame * frame)
{
  int i, j;
  for (j = 0; j < GST_VIDEO_FRAME_HEIGHT (frame); ++j) {
    guint8 *line;

    line = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
    line += GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) * j;
    for (i = 0; i < GST_VIDEO_FRAME_WIDTH (frame); ++i) {
      int a = line[3];
      if (a) {
        line[0] = MIN ((line[0] * 255 + a / 2) / a, 255);
        line[1] = MIN ((line[1] * 255 + a / 2) / a, 255);
        line[2] = MIN ((line[2] * 255 + a / 2) / a, 255);
      }
      line += 4;
    }
  }
}

static void
gst_video_overlay_rectangle_unpremultiply (GstVideoFrame * frame)
{
  gint alpha_offset;

  alpha_offset = GST_VIDEO_FRAME_COMP_POFFSET (frame, 3);
  switch (alpha_offset) {
    case 0:
      gst_video_overlay_rectangle_unpremultiply_0 (frame);
      break;
    case 3:
      gst_video_overlay_rectangle_unpremultiply_3 (frame);
      break;
    default:
      g_assert_not_reached ();
      break;
  }
}


static void
gst_video_overlay_rectangle_extract_alpha (GstVideoOverlayRectangle * rect)
{
  guint8 *src, *dst;
  GstVideoFrame frame;
  gint i, j, w, h, stride, alpha_offset;

  alpha_offset = GST_VIDEO_INFO_COMP_POFFSET (&rect->info, 3);
  g_return_if_fail (alpha_offset == 0 || alpha_offset == 3);

  gst_video_frame_map (&frame, &rect->info, rect->pixels, GST_MAP_READ);
  src = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
  w = GST_VIDEO_INFO_WIDTH (&rect->info);
  h = GST_VIDEO_INFO_HEIGHT (&rect->info);
  stride = GST_VIDEO_INFO_PLANE_STRIDE (&rect->info, 0);

  g_free (rect->initial_alpha);
  rect->initial_alpha = g_malloc (w * h);
  dst = rect->initial_alpha;

  for (i = 0; i < h; i++) {
    for (j = 0; j < w; j++) {
      *dst = src[alpha_offset];
      dst++;
      src += 4;
    }
    src += stride - 4 * w;
  }
  gst_video_frame_unmap (&frame);
}


static void
gst_video_overlay_rectangle_apply_global_alpha (GstVideoOverlayRectangle * rect,
    float global_alpha)
{
  guint8 *src, *dst;
  GstVideoFrame frame;
  gint i, j, w, h, stride;
  gint argb_a, argb_r, argb_g, argb_b;
  gint alpha_offset;

  g_assert (!(rect->applied_global_alpha != 1.0
          && rect->initial_alpha == NULL));

  alpha_offset = GST_VIDEO_INFO_COMP_POFFSET (&rect->info, 3);
  g_return_if_fail (alpha_offset == 0 || alpha_offset == 3);

  if (global_alpha == rect->applied_global_alpha)
    return;

  if (rect->initial_alpha == NULL)
    gst_video_overlay_rectangle_extract_alpha (rect);

  src = rect->initial_alpha;
  rect->pixels = gst_buffer_make_writable (rect->pixels);

  gst_video_frame_map (&frame, &rect->info, rect->pixels, GST_MAP_READ);
  dst = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
  w = GST_VIDEO_INFO_WIDTH (&rect->info);
  h = GST_VIDEO_INFO_HEIGHT (&rect->info);
  stride = GST_VIDEO_INFO_PLANE_STRIDE (&rect->info, 0);

  argb_a = GST_VIDEO_INFO_COMP_POFFSET (&rect->info, 3);
  argb_r = (argb_a + 1) % 4;
  argb_g = (argb_a + 2) % 4;
  argb_b = (argb_a + 3) % 4;

  for (i = 0; i < h; i++) {
    for (j = 0; j < w; j++) {
      guint8 na = (guint8) (*src * global_alpha);

      if (! !(rect->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)) {
        dst[argb_r] =
            (guint8) ((double) (dst[argb_r] * 255) / (double) dst[argb_a]) *
            na / 255;
        dst[argb_g] =
            (guint8) ((double) (dst[argb_g] * 255) / (double) dst[argb_a]) *
            na / 255;
        dst[argb_b] =
            (guint8) ((double) (dst[argb_b] * 255) / (double) dst[argb_a]) *
            na / 255;
      }
      dst[argb_a] = na;
      src++;
      dst += 4;
    }
    dst += stride - 4 * w;
  }
  gst_video_frame_unmap (&frame);

  rect->applied_global_alpha = global_alpha;
}

static void
gst_video_overlay_rectangle_convert (GstVideoInfo * src, GstBuffer * src_buffer,
    GstVideoFormat dest_format, GstVideoInfo * dest, GstBuffer ** dest_buffer)
{
  gint width, height, stride;
  GstVideoFrame src_frame, dest_frame;
  GstVideoFormat format;
  gint k, l;
  guint8 *sdata, *ddata;

  format = GST_VIDEO_INFO_FORMAT (src);

  width = GST_VIDEO_INFO_WIDTH (src);
  height = GST_VIDEO_INFO_HEIGHT (src);

  gst_video_info_init (dest);
  gst_video_info_set_format (dest, dest_format, width, height);

  *dest_buffer = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (dest));

  gst_video_frame_map (&src_frame, src, src_buffer, GST_MAP_READ);
  gst_video_frame_map (&dest_frame, dest, *dest_buffer, GST_MAP_WRITE);

  sdata = GST_VIDEO_FRAME_PLANE_DATA (&src_frame, 0);
  ddata = GST_VIDEO_FRAME_PLANE_DATA (&dest_frame, 0);
  stride = GST_VIDEO_FRAME_PLANE_STRIDE (&src_frame, 0);

  if (format == GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV &&
      dest_format == GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB) {
    gint ayuv;
    gint a, y, u, v, r, g, b;

    for (k = 0; k < height; k++) {
      for (l = 0; l < width; l++) {
        ayuv = GST_READ_UINT32_BE (sdata);
        a = ayuv >> 24;
        y = (ayuv >> 16) & 0xff;
        u = (ayuv >> 8) & 0xff;
        v = (ayuv & 0xff);

        r = (298 * y + 459 * v - 63514) >> 8;
        g = (298 * y - 55 * u - 136 * v + 19681) >> 8;
        b = (298 * y + 541 * u - 73988) >> 8;

        r = CLAMP (r, 0, 255);
        g = CLAMP (g, 0, 255);
        b = CLAMP (b, 0, 255);

        /* native endian ARGB */
        *(guint32 *) ddata = ((a << 24) | (r << 16) | (g << 8) | b);

        sdata += 4;
        ddata += 4;
      }
      sdata += stride - 4 * width;
    }
  } else if (format == GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB &&
      dest_format == GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV) {
    gint argb;
    gint a, y, u, v, r, g, b;

    for (k = 0; k < height; k++) {
      for (l = 0; l < width; l++) {
        /* native endian ARGB */
        argb = *(guint32 *) sdata;
        a = argb >> 24;
        r = (argb >> 16) & 0xff;
        g = (argb >> 8) & 0xff;
        b = (argb & 0xff);

        y = (47 * r + 157 * g + 16 * b + 4096) >> 8;
        u = (-26 * r - 87 * g + 112 * b + 32768) >> 8;
        v = (112 * r - 102 * g - 10 * b + 32768) >> 8;

        y = CLAMP (y, 0, 255);
        u = CLAMP (u, 0, 255);
        v = CLAMP (v, 0, 255);

        GST_WRITE_UINT32_BE (ddata, ((a << 24) | (y << 16) | (u << 8) | v));

        sdata += 4;
        ddata += 4;
      }
      sdata += stride - 4 * width;
    }
  } else {
    GST_ERROR ("unsupported conversion");
    g_assert_not_reached ();
  }

  gst_video_frame_unmap (&src_frame);
  gst_video_frame_unmap (&dest_frame);
}

static GstBuffer *
gst_video_overlay_rectangle_get_pixels_raw_internal (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags, gboolean unscaled,
    GstVideoFormat wanted_format)
{
  GstVideoOverlayFormatFlags new_flags;
  GstVideoOverlayRectangle *scaled_rect = NULL, *conv_rect = NULL;
  GstVideoInfo info;
  GstVideoFrame frame;
  GstBuffer *buf;
  GList *l;
  guint width, height;
  guint wanted_width;
  guint wanted_height;
  gboolean apply_global_alpha;
  gboolean revert_global_alpha;
  GstVideoFormat format;

  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);
  g_return_val_if_fail (gst_video_overlay_rectangle_check_flags (flags), NULL);

  width = GST_VIDEO_INFO_WIDTH (&rectangle->info);
  height = GST_VIDEO_INFO_HEIGHT (&rectangle->info);
  wanted_width = unscaled ? width : rectangle->render_width;
  wanted_height = unscaled ? height : rectangle->render_height;
  format = GST_VIDEO_INFO_FORMAT (&rectangle->info);

  apply_global_alpha =
      (! !(rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)
      && !(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA));
  revert_global_alpha =
      (! !(rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)
      && ! !(flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA));

  /* This assumes we don't need to adjust the format */
  if (wanted_width == width &&
      wanted_height == height &&
      wanted_format == format &&
      gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags,
          flags)) {
    /* don't need to apply/revert global-alpha either: */
    if ((!apply_global_alpha
            || rectangle->applied_global_alpha == rectangle->global_alpha)
        && (!revert_global_alpha || rectangle->applied_global_alpha == 1.0)) {
      return rectangle->pixels;
    } else {
      /* only apply/revert global-alpha */
      scaled_rect = rectangle;
      goto done;
    }
  }

  /* see if we've got one cached already */
  GST_RECTANGLE_LOCK (rectangle);
  for (l = rectangle->scaled_rectangles; l != NULL; l = l->next) {
    GstVideoOverlayRectangle *r = l->data;

    if (GST_VIDEO_INFO_WIDTH (&r->info) == wanted_width &&
        GST_VIDEO_INFO_HEIGHT (&r->info) == wanted_height &&
        GST_VIDEO_INFO_FORMAT (&r->info) == wanted_format &&
        gst_video_overlay_rectangle_is_same_alpha_type (r->flags, flags)) {
      /* we'll keep these rectangles around until finalize, so it's ok not
       * to take our own ref here */
      scaled_rect = r;
      break;
    }
  }
  GST_RECTANGLE_UNLOCK (rectangle);

  if (scaled_rect != NULL)
    goto done;

  /* maybe have one in the right format though */
  if (format != wanted_format) {
    GST_RECTANGLE_LOCK (rectangle);
    for (l = rectangle->scaled_rectangles; l != NULL; l = l->next) {
      GstVideoOverlayRectangle *r = l->data;

      if (GST_VIDEO_INFO_FORMAT (&r->info) == wanted_format &&
          gst_video_overlay_rectangle_is_same_alpha_type (r->flags, flags)) {
        /* we'll keep these rectangles around until finalize, so it's ok not
         * to take our own ref here */
        conv_rect = r;
        break;
      }
    }
    GST_RECTANGLE_UNLOCK (rectangle);
  } else {
    conv_rect = rectangle;
  }

  if (conv_rect == NULL) {
    GstVideoInfo conv_info;

    gst_video_overlay_rectangle_convert (&rectangle->info, rectangle->pixels,
        wanted_format, &conv_info, &buf);
    gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
        GST_VIDEO_INFO_FORMAT (&conv_info), width, height);
    conv_rect = gst_video_overlay_rectangle_new_raw (buf,
        0, 0, width, height, rectangle->flags);
    if (rectangle->global_alpha != 1.0)
      gst_video_overlay_rectangle_set_global_alpha (scaled_rect,
          rectangle->global_alpha);
    gst_buffer_unref (buf);
    /* keep this converted one around as well in any case */
    GST_RECTANGLE_LOCK (rectangle);
    rectangle->scaled_rectangles =
        g_list_prepend (rectangle->scaled_rectangles, conv_rect);
    GST_RECTANGLE_UNLOCK (rectangle);
  }

  /* now we continue from conv_rect */
  width = GST_VIDEO_INFO_WIDTH (&conv_rect->info);
  height = GST_VIDEO_INFO_HEIGHT (&conv_rect->info);
  format = GST_VIDEO_INFO_FORMAT (&conv_rect->info);

  /* not cached yet, do the preprocessing and put the result into our cache */
  if (wanted_width != width || wanted_height != height) {
    GstVideoInfo scaled_info;

    /* we could check the cache for a scaled rect with global_alpha == 1 here */
    gst_video_blend_scale_linear_RGBA (&conv_rect->info, conv_rect->pixels,
        wanted_height, wanted_width, &scaled_info, &buf);
    info = scaled_info;
    gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
        GST_VIDEO_INFO_FORMAT (&conv_rect->info), wanted_width, wanted_height);
  } else if (!gst_video_overlay_rectangle_is_same_alpha_type (conv_rect->flags,
          flags)) {
    /* if we don't have to scale, we have to modify the alpha values, so we
     * need to make a copy of the pixel memory (and we take ownership below) */
    buf = gst_buffer_copy (conv_rect->pixels);
    info = conv_rect->info;
  } else {
    /* do not need to scale or modify alpha values, almost done then */
    scaled_rect = conv_rect;
    goto done;
  }

  new_flags = conv_rect->flags;
  gst_video_frame_map (&frame, &info, buf, GST_MAP_READWRITE);
  if (!gst_video_overlay_rectangle_is_same_alpha_type (conv_rect->flags, flags)) {
    if (rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) {
      gst_video_overlay_rectangle_unpremultiply (&frame);
      new_flags &= ~GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
    } else {
      gst_video_overlay_rectangle_premultiply (&frame);
      new_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
    }
  }
  gst_video_frame_unmap (&frame);

  scaled_rect = gst_video_overlay_rectangle_new_raw (buf,
      0, 0, wanted_width, wanted_height, new_flags);
  if (conv_rect->global_alpha != 1.0)
    gst_video_overlay_rectangle_set_global_alpha (scaled_rect,
        conv_rect->global_alpha);
  gst_buffer_unref (buf);

  GST_RECTANGLE_LOCK (rectangle);
  rectangle->scaled_rectangles =
      g_list_prepend (rectangle->scaled_rectangles, scaled_rect);
  GST_RECTANGLE_UNLOCK (rectangle);

done:

  GST_RECTANGLE_LOCK (rectangle);
  if (apply_global_alpha
      && scaled_rect->applied_global_alpha != rectangle->global_alpha) {
    gst_video_overlay_rectangle_apply_global_alpha (scaled_rect,
        rectangle->global_alpha);
    gst_video_overlay_rectangle_set_global_alpha (scaled_rect,
        rectangle->global_alpha);
  } else if (revert_global_alpha && scaled_rect->applied_global_alpha != 1.0) {
    gst_video_overlay_rectangle_apply_global_alpha (scaled_rect, 1.0);
  }
  GST_RECTANGLE_UNLOCK (rectangle);

  return scaled_rect->pixels;
}


/**
 * gst_video_overlay_rectangle_get_pixels_raw:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Returns: (transfer none): a #GstBuffer holding the pixel data with
 *    format as originally provided and specified in video meta with
 *    width and height of the render dimensions as per
 *    gst_video_overlay_rectangle_get_render_rectangle(). This function does
 *    not return a reference, the caller should obtain a reference of her own
 *    with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_raw (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, FALSE, GST_VIDEO_INFO_FORMAT (&rectangle->info));
}

/**
 * gst_video_overlay_rectangle_get_pixels_argb:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with
 *    width and height of the render dimensions as per
 *    gst_video_overlay_rectangle_get_render_rectangle(). This function does
 *    not return a reference, the caller should obtain a reference of her own
 *    with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, FALSE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB);
}

/**
 * gst_video_overlay_rectangle_get_pixels_ayuv:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Returns: (transfer none): a #GstBuffer holding the AYUV pixel data with
 *    width and height of the render dimensions as per
 *    gst_video_overlay_rectangle_get_render_rectangle(). This function does
 *    not return a reference, the caller should obtain a reference of her own
 *    with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_ayuv (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, FALSE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV);
}

/**
 * gst_video_overlay_rectangle_get_pixels_unscaled_raw:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags.
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Retrieves the pixel data as it is. This is useful if the caller can
 * do the scaling itself when handling the overlaying. The rectangle will
 * need to be scaled to the render dimensions, which can be retrieved using
 * gst_video_overlay_rectangle_get_render_rectangle().
 *
 * Returns: (transfer none): a #GstBuffer holding the pixel data with
 *    #GstVideoMeta set. This function does not return a reference, the caller
 *    should obtain a reference of her own with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_unscaled_raw (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);

  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, TRUE, GST_VIDEO_INFO_FORMAT (&rectangle->info));
}

/**
 * gst_video_overlay_rectangle_get_pixels_unscaled_argb:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags.
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Retrieves the pixel data as it is. This is useful if the caller can
 * do the scaling itself when handling the overlaying. The rectangle will
 * need to be scaled to the render dimensions, which can be retrieved using
 * gst_video_overlay_rectangle_get_render_rectangle().
 *
 * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with
 *    #GstVideoMeta set. This function does not return a reference, the caller
 *    should obtain a reference of her own with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_unscaled_argb (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);

  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, TRUE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB);
}

/**
 * gst_video_overlay_rectangle_get_pixels_unscaled_ayuv:
 * @rectangle: a #GstVideoOverlayRectangle
 * @flags: flags.
 *    If a global_alpha value != 1 is set for the rectangle, the caller
 *    should set the #GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA flag
 *    if he wants to apply global-alpha himself. If the flag is not set
 *    global_alpha is applied internally before returning the pixel-data.
 *
 * Retrieves the pixel data as it is. This is useful if the caller can
 * do the scaling itself when handling the overlaying. The rectangle will
 * need to be scaled to the render dimensions, which can be retrieved using
 * gst_video_overlay_rectangle_get_render_rectangle().
 *
 * Returns: (transfer none): a #GstBuffer holding the AYUV pixel data with
 *    #GstVideoMeta set. This function does not return a reference, the caller
 *    should obtain a reference of her own with gst_buffer_ref() if needed.
 */
GstBuffer *
gst_video_overlay_rectangle_get_pixels_unscaled_ayuv (GstVideoOverlayRectangle *
    rectangle, GstVideoOverlayFormatFlags flags)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);

  return gst_video_overlay_rectangle_get_pixels_raw_internal (rectangle,
      flags, TRUE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV);
}

/**
 * gst_video_overlay_rectangle_get_flags:
 * @rectangle: a #GstVideoOverlayRectangle
 *
 * Retrieves the flags associated with a #GstVideoOverlayRectangle.
 * This is useful if the caller can handle both premultiplied alpha and
 * non premultiplied alpha, for example. By knowing whether the rectangle
 * uses premultiplied or not, it can request the pixel data in the format
 * it is stored in, to avoid unnecessary conversion.
 *
 * Returns: the #GstVideoOverlayFormatFlags associated with the rectangle.
 */
GstVideoOverlayFormatFlags
gst_video_overlay_rectangle_get_flags (GstVideoOverlayRectangle * rectangle)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle),
      GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE);

  return rectangle->flags;
}

/**
 * gst_video_overlay_rectangle_get_global_alpha:
 * @rectangle: a #GstVideoOverlayRectangle
 *
 * Retrieves the global-alpha value associated with a #GstVideoOverlayRectangle.
 *
 * Returns: the global-alpha value associated with the rectangle.
 */
gfloat
gst_video_overlay_rectangle_get_global_alpha (GstVideoOverlayRectangle *
    rectangle)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), -1);

  return rectangle->global_alpha;
}

/**
 * gst_video_overlay_rectangle_set_global_alpha:
 * @rectangle: a #GstVideoOverlayRectangle
 * @global_alpha: Global alpha value (0 to 1.0)
 *
 * Sets the global alpha value associated with a #GstVideoOverlayRectangle. Per-
 * pixel alpha values are multiplied with this value. Valid
 * values: 0 <= global_alpha <= 1; 1 to deactivate.
 *
 * @rectangle must be writable, meaning its refcount must be 1. You can
 * make the rectangles inside a #GstVideoOverlayComposition writable using
 * gst_video_overlay_composition_make_writable() or
 * gst_video_overlay_composition_copy().
 */
void
gst_video_overlay_rectangle_set_global_alpha (GstVideoOverlayRectangle *
    rectangle, gfloat global_alpha)
{
  g_return_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle));
  g_return_if_fail (global_alpha >= 0 && global_alpha <= 1);

  if (rectangle->global_alpha != global_alpha) {
    rectangle->global_alpha = global_alpha;
    if (global_alpha != 1)
      rectangle->flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA;
    else
      rectangle->flags &= ~GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA;
    /* update seq_num automatically to signal the consumer, that data has changed
     * note, that this might mislead renderers, that can handle global-alpha
     * themselves, because what they want to know is whether the actual pixel data
     * has changed. */
    rectangle->seq_num = gst_video_overlay_get_seqnum ();
  }
}

/**
 * gst_video_overlay_rectangle_copy:
 * @rectangle: (transfer none): a #GstVideoOverlayRectangle to copy
 *
 * Makes a copy of @rectangle, so that it is possible to modify it
 * (e.g. to change the render co-ordinates or render dimension). The
 * actual overlay pixel data buffers contained in the rectangle are not
 * copied.
 *
 * Returns: (transfer full): a new #GstVideoOverlayRectangle equivalent
 *     to @rectangle.
 */
GstVideoOverlayRectangle *
gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle)
{
  GstVideoOverlayRectangle *copy;

  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL);

  copy = gst_video_overlay_rectangle_new_raw (rectangle->pixels,
      rectangle->x, rectangle->y,
      rectangle->render_width, rectangle->render_height, rectangle->flags);
  if (rectangle->global_alpha != 1)
    gst_video_overlay_rectangle_set_global_alpha (copy,
        rectangle->global_alpha);

  return copy;
}

/**
 * gst_video_overlay_rectangle_get_seqnum:
 * @rectangle: a #GstVideoOverlayRectangle
 *
 * Returns the sequence number of this rectangle. Sequence numbers are
 * monotonically increasing and unique for overlay compositions and rectangles
 * (meaning there will never be a rectangle with the same sequence number as
 * a composition).
 *
 * Using the sequence number of a rectangle as an indicator for changed
 * pixel-data of a rectangle is dangereous. Some API calls, like e.g.
 * gst_video_overlay_rectangle_set_global_alpha(), automatically update
 * the per rectangle sequence number, which is misleading for renderers/
 * consumers, that handle global-alpha themselves. For them  the
 * pixel-data returned by gst_video_overlay_rectangle_get_pixels_*()
 * wont be different for different global-alpha values. In this case a
 * renderer could also use the GstBuffer pointers as a hint for changed
 * pixel-data.
 *
 * Returns: the sequence number of @rectangle
 */
guint
gst_video_overlay_rectangle_get_seqnum (GstVideoOverlayRectangle * rectangle)
{
  g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), 0);

  return rectangle->seq_num;
}
