/* Generic video aggregator plugin
 * Copyright (C) 2004, 2008 Wim Taymans <wim@fluendo.com>
 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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:gstvideoaggregator
 * @short_description: Base class for video aggregators
 *
 * VideoAggregator can accept AYUV, ARGB and BGRA video streams. For each of the requested
 * sink pads it will compare the incoming geometry and framerate to define the
 * output parameters. Indeed output video frames will have the geometry of the
 * biggest incoming video stream and the framerate of the fastest incoming one.
 *
 * VideoAggregator will do colorspace conversion.
 *
 * Zorder for each input stream can be configured on the
 * #GstVideoAggregatorPad.
 *
 */

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

#include <string.h>

#include "gstvideoaggregator.h"
#include "gstvideoaggregatorpad.h"

GST_DEBUG_CATEGORY_STATIC (gst_videoaggregator_debug);
#define GST_CAT_DEFAULT gst_videoaggregator_debug

/* Needed prototypes */
static void gst_videoaggregator_reset_qos (GstVideoAggregator * vagg);

/****************************************
 * GstVideoAggregatorPad implementation *
 ****************************************/

#define DEFAULT_PAD_ZORDER 0
#define DEFAULT_PAD_IGNORE_EOS FALSE
enum
{
  PROP_PAD_0,
  PROP_PAD_ZORDER,
  PROP_PAD_IGNORE_EOS,
};


struct _GstVideoAggregatorPadPrivate
{
  /* Converter, if NULL no conversion is done */
  GstVideoConverter *convert;

  /* caps used for conversion if needed */
  GstVideoInfo conversion_info;
  GstBuffer *converted_buffer;

  GstClockTime start_time;
  GstClockTime end_time;
};


G_DEFINE_TYPE (GstVideoAggregatorPad, gst_videoaggregator_pad,
    GST_TYPE_AGGREGATOR_PAD);

static void
gst_videoaggregator_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (object);

  switch (prop_id) {
    case PROP_PAD_ZORDER:
      g_value_set_uint (value, pad->zorder);
      break;
    case PROP_PAD_IGNORE_EOS:
      g_value_set_boolean (value, pad->ignore_eos);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static int
pad_zorder_compare (const GstVideoAggregatorPad * pad1,
    const GstVideoAggregatorPad * pad2)
{
  return pad1->zorder - pad2->zorder;
}

static void
gst_videoaggregator_pad_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (object);
  GstVideoAggregator *vagg =
      GST_VIDEO_AGGREGATOR (gst_pad_get_parent (GST_PAD (pad)));

  switch (prop_id) {
    case PROP_PAD_ZORDER:
      GST_OBJECT_LOCK (vagg);
      pad->zorder = g_value_get_uint (value);
      GST_ELEMENT (vagg)->sinkpads = g_list_sort (GST_ELEMENT (vagg)->sinkpads,
          (GCompareFunc) pad_zorder_compare);
      GST_OBJECT_UNLOCK (vagg);
      break;
    case PROP_PAD_IGNORE_EOS:
      pad->ignore_eos = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  gst_object_unref (vagg);
}

static gboolean
_flush_pad (GstAggregatorPad * aggpad, GstAggregator * aggregator)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (aggregator);
  GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (aggpad);

  gst_videoaggregator_reset_qos (vagg);
  gst_buffer_replace (&pad->buffer, NULL);
  pad->priv->start_time = -1;
  pad->priv->end_time = -1;

  return TRUE;
}

static gboolean
gst_video_aggregator_pad_set_info (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg G_GNUC_UNUSED,
    GstVideoInfo * current_info, GstVideoInfo * wanted_info)
{
  gchar *colorimetry, *best_colorimetry;
  const gchar *chroma, *best_chroma;

  if (!current_info->finfo)
    return TRUE;

  if (GST_VIDEO_INFO_FORMAT (current_info) == GST_VIDEO_FORMAT_UNKNOWN)
    return TRUE;

  if (pad->priv->convert)
    gst_video_converter_free (pad->priv->convert);

  pad->priv->convert = NULL;

  colorimetry = gst_video_colorimetry_to_string (&(current_info->colorimetry));
  chroma = gst_video_chroma_to_string (current_info->chroma_site);

  best_colorimetry =
      gst_video_colorimetry_to_string (&(wanted_info->colorimetry));
  best_chroma = gst_video_chroma_to_string (wanted_info->chroma_site);

  if (GST_VIDEO_INFO_FORMAT (wanted_info) !=
      GST_VIDEO_INFO_FORMAT (current_info)
      || g_strcmp0 (colorimetry, best_colorimetry)
      || g_strcmp0 (chroma, best_chroma)) {
    GstVideoInfo tmp_info;

    /* Initialize with the wanted video format and our original width and
     * height as we don't want to rescale. Then copy over the wanted
     * colorimetry, and chroma-site and our current pixel-aspect-ratio
     * and other relevant fields.
     */
    gst_video_info_set_format (&tmp_info, GST_VIDEO_INFO_FORMAT (wanted_info),
        current_info->width, current_info->height);
    tmp_info.chroma_site = wanted_info->chroma_site;
    tmp_info.colorimetry = wanted_info->colorimetry;
    tmp_info.par_n = current_info->par_n;
    tmp_info.par_d = current_info->par_d;
    tmp_info.fps_n = current_info->fps_n;
    tmp_info.fps_d = current_info->fps_d;
    tmp_info.flags = current_info->flags;
    tmp_info.interlace_mode = current_info->interlace_mode;

    GST_DEBUG_OBJECT (pad, "This pad will be converted from %d to %d",
        GST_VIDEO_INFO_FORMAT (current_info),
        GST_VIDEO_INFO_FORMAT (&tmp_info));
    pad->priv->convert =
        gst_video_converter_new (current_info, &tmp_info, NULL);
    pad->priv->conversion_info = tmp_info;
    if (!pad->priv->convert) {
      g_free (colorimetry);
      g_free (best_colorimetry);
      GST_WARNING_OBJECT (pad, "No path found for conversion");
      return FALSE;
    }
  } else {
    GST_DEBUG_OBJECT (pad, "This pad will not need conversion");
  }
  g_free (colorimetry);
  g_free (best_colorimetry);

  return TRUE;
}

static void
gst_videoaggregator_pad_finalize (GObject * o)
{
  GstVideoAggregatorPad *vaggpad = GST_VIDEO_AGGREGATOR_PAD (o);

  if (vaggpad->priv->convert)
    gst_video_converter_free (vaggpad->priv->convert);
  vaggpad->priv->convert = NULL;

  G_OBJECT_CLASS (gst_videoaggregator_pad_parent_class)->finalize (o);
}

static gboolean
gst_video_aggregator_pad_prepare_frame (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg)
{
  guint outsize;
  GstVideoFrame *converted_frame;
  GstBuffer *converted_buf = NULL;
  GstVideoFrame *frame;
  static GstAllocationParams params = { 0, 15, 0, 0, };

  if (!pad->buffer)
    return TRUE;

  frame = g_slice_new0 (GstVideoFrame);

  if (!gst_video_frame_map (frame, &pad->buffer_vinfo, pad->buffer,
          GST_MAP_READ)) {
    GST_WARNING_OBJECT (vagg, "Could not map input buffer");
    return FALSE;
  }

  if (pad->priv->convert) {
    gint converted_size;

    converted_frame = g_slice_new0 (GstVideoFrame);

    /* We wait until here to set the conversion infos, in case vagg->info changed */
    converted_size = pad->priv->conversion_info.size;
    outsize = GST_VIDEO_INFO_SIZE (&vagg->info);
    converted_size = converted_size > outsize ? converted_size : outsize;
    converted_buf = gst_buffer_new_allocate (NULL, converted_size, &params);

    if (!gst_video_frame_map (converted_frame, &(pad->priv->conversion_info),
            converted_buf, GST_MAP_READWRITE)) {
      GST_WARNING_OBJECT (vagg, "Could not map converted frame");

      g_slice_free (GstVideoFrame, converted_frame);
      gst_video_frame_unmap (frame);
      g_slice_free (GstVideoFrame, frame);
      return FALSE;
    }

    gst_video_converter_frame (pad->priv->convert, frame, converted_frame);
    pad->priv->converted_buffer = converted_buf;
    gst_video_frame_unmap (frame);
    g_slice_free (GstVideoFrame, frame);
  } else {
    converted_frame = frame;
  }

  pad->aggregated_frame = converted_frame;

  return TRUE;
}

static void
gst_video_aggregator_pad_clean_frame (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg)
{
  if (pad->aggregated_frame) {
    gst_video_frame_unmap (pad->aggregated_frame);
    g_slice_free (GstVideoFrame, pad->aggregated_frame);
    pad->aggregated_frame = NULL;
  }

  if (pad->priv->converted_buffer) {
    gst_buffer_unref (pad->priv->converted_buffer);
    pad->priv->converted_buffer = NULL;
  }
}

static void
gst_videoaggregator_pad_class_init (GstVideoAggregatorPadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstAggregatorPadClass *aggpadclass = (GstAggregatorPadClass *) klass;

  gobject_class->set_property = gst_videoaggregator_pad_set_property;
  gobject_class->get_property = gst_videoaggregator_pad_get_property;
  gobject_class->finalize = gst_videoaggregator_pad_finalize;

  g_object_class_install_property (gobject_class, PROP_PAD_ZORDER,
      g_param_spec_uint ("zorder", "Z-Order", "Z Order of the picture",
          0, G_MAXUINT, DEFAULT_PAD_ZORDER,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PAD_IGNORE_EOS,
      g_param_spec_boolean ("ignore-eos", "Ignore EOS", "Aggregate the last "
          "frame on pads that are EOS till they are released",
          DEFAULT_PAD_IGNORE_EOS,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  g_type_class_add_private (klass, sizeof (GstVideoAggregatorPadPrivate));

  aggpadclass->flush = GST_DEBUG_FUNCPTR (_flush_pad);
  klass->set_info = GST_DEBUG_FUNCPTR (gst_video_aggregator_pad_set_info);
  klass->prepare_frame =
      GST_DEBUG_FUNCPTR (gst_video_aggregator_pad_prepare_frame);
  klass->clean_frame = GST_DEBUG_FUNCPTR (gst_video_aggregator_pad_clean_frame);
}

static void
gst_videoaggregator_pad_init (GstVideoAggregatorPad * vaggpad)
{
  vaggpad->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (vaggpad, GST_TYPE_VIDEO_AGGREGATOR_PAD,
      GstVideoAggregatorPadPrivate);

  vaggpad->zorder = DEFAULT_PAD_ZORDER;
  vaggpad->ignore_eos = DEFAULT_PAD_IGNORE_EOS;
  vaggpad->aggregated_frame = NULL;
  vaggpad->priv->converted_buffer = NULL;

  vaggpad->priv->convert = NULL;
}

/*********************************
 * GstChildProxy implementation  *
 *********************************/
static GObject *
gst_videoaggregator_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GObject *obj;
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (child_proxy);

  GST_OBJECT_LOCK (vagg);
  if ((obj = g_list_nth_data (GST_ELEMENT (vagg)->sinkpads, index)))
    g_object_ref (obj);
  GST_OBJECT_UNLOCK (vagg);

  return obj;
}

static guint
gst_videoaggregator_child_proxy_get_children_count (GstChildProxy * child_proxy)
{
  guint count = 0;

  GST_OBJECT_LOCK (child_proxy);
  count = GST_ELEMENT (child_proxy)->numsinkpads;
  GST_OBJECT_UNLOCK (child_proxy);

  GST_INFO_OBJECT (child_proxy, "Children Count: %d", count);

  return count;
}

static void
gst_videoaggregator_child_proxy_init (gpointer g_iface, gpointer iface_data)
{
  GstChildProxyInterface *iface = g_iface;

  GST_INFO ("intializing child proxy interface");
  iface->get_child_by_index =
      gst_videoaggregator_child_proxy_get_child_by_index;
  iface->get_children_count =
      gst_videoaggregator_child_proxy_get_children_count;
}

/**************************************
 * GstVideoAggregator implementation  *
 **************************************/

#define GST_VIDEO_AGGREGATOR_GET_LOCK(vagg) (&GST_VIDEO_AGGREGATOR(vagg)->priv->lock)

#define GST_VIDEO_AGGREGATOR_LOCK(vagg)   G_STMT_START {       \
  GST_LOG_OBJECT (vagg, "Taking EVENT lock from thread %p",    \
        g_thread_self());                                      \
  g_mutex_lock(GST_VIDEO_AGGREGATOR_GET_LOCK(vagg));           \
  GST_LOG_OBJECT (vagg, "Took EVENT lock from thread %p",      \
        g_thread_self());                                      \
  } G_STMT_END

#define GST_VIDEO_AGGREGATOR_UNLOCK(vagg)   G_STMT_START {     \
  GST_LOG_OBJECT (vagg, "Releasing EVENT lock from thread %p", \
        g_thread_self());                                      \
  g_mutex_unlock(GST_VIDEO_AGGREGATOR_GET_LOCK(vagg));         \
  GST_LOG_OBJECT (vagg, "Took EVENT lock from thread %p",      \
        g_thread_self());                                      \
  } G_STMT_END


struct _GstVideoAggregatorPrivate
{
  /* Lock to prevent the state to change while aggregating */
  GMutex lock;

  /* Current downstream segment */
  GstClockTime ts_offset;
  guint64 nframes;

  /* QoS stuff */
  gdouble proportion;
  GstClockTime earliest_time;
  guint64 qos_processed, qos_dropped;

  /* current caps */
  GstCaps *current_caps;

  gboolean live;
};

/* Can't use the G_DEFINE_TYPE macros because we need the
 * videoaggregator class in the _init to be able to set
 * the sink pad non-alpha caps. Using the G_DEFINE_TYPE there
 * seems to be no way of getting the real class being initialized */
static void gst_videoaggregator_init (GstVideoAggregator * self,
    GstVideoAggregatorClass * klass);
static void gst_videoaggregator_class_init (GstVideoAggregatorClass * klass);
static gpointer gst_videoaggregator_parent_class = NULL;

GType
gst_videoaggregator_get_type (void)
{
  static volatile gsize g_define_type_id_volatile = 0;

  if (g_once_init_enter (&g_define_type_id_volatile)) {
    GType g_define_type_id = g_type_register_static_simple (GST_TYPE_AGGREGATOR,
        g_intern_static_string ("GstVideoAggregator"),
        sizeof (GstVideoAggregatorClass),
        (GClassInitFunc) gst_videoaggregator_class_init,
        sizeof (GstVideoAggregator),
        (GInstanceInitFunc) gst_videoaggregator_init,
        (GTypeFlags) G_TYPE_FLAG_ABSTRACT);
    {
      G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
          gst_videoaggregator_child_proxy_init);
    }
    g_once_init_leave (&g_define_type_id_volatile, g_define_type_id);
  }
  return g_define_type_id_volatile;
}

static void
gst_videoaggreagator_find_best_format (GstVideoAggregator * vagg,
    GstCaps * downstream_caps, GstVideoInfo * best_info,
    gboolean * at_least_one_alpha)
{
  GList *tmp;
  GstCaps *possible_caps;
  GstVideoAggregatorPad *pad;
  gboolean need_alpha = FALSE;
  gint best_format_number = 0;
  GHashTable *formats_table = g_hash_table_new (g_direct_hash, g_direct_equal);

  GST_OBJECT_LOCK (vagg);
  for (tmp = GST_ELEMENT (vagg)->sinkpads; tmp; tmp = tmp->next) {
    GstStructure *s;
    gint format_number;

    pad = tmp->data;

    if (!pad->info.finfo)
      continue;

    if (pad->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_ALPHA)
      *at_least_one_alpha = TRUE;

    /* If we want alpha, disregard all the other formats */
    if (need_alpha && !(pad->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_ALPHA))
      continue;

    /* This can happen if we release a pad and another pad hasn't been negotiated_caps yet */
    if (GST_VIDEO_INFO_FORMAT (&pad->info) == GST_VIDEO_FORMAT_UNKNOWN)
      continue;

    possible_caps = gst_video_info_to_caps (&pad->info);

    s = gst_caps_get_structure (possible_caps, 0);
    gst_structure_remove_fields (s, "width", "height", "framerate",
        "pixel-aspect-ratio", "interlace-mode", NULL);

    /* Can downstream accept this format ? */
    if (!gst_caps_can_intersect (downstream_caps, possible_caps)) {
      gst_caps_unref (possible_caps);
      continue;
    }

    gst_caps_unref (possible_caps);

    format_number =
        GPOINTER_TO_INT (g_hash_table_lookup (formats_table,
            GINT_TO_POINTER (GST_VIDEO_INFO_FORMAT (&pad->info))));
    format_number += 1;

    g_hash_table_replace (formats_table,
        GINT_TO_POINTER (GST_VIDEO_INFO_FORMAT (&pad->info)),
        GINT_TO_POINTER (format_number));

    /* If that pad is the first with alpha, set it as the new best format */
    if (!need_alpha && (pad->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_ALPHA)) {
      need_alpha = TRUE;
      *best_info = pad->info;
      best_format_number = format_number;
    } else if (format_number > best_format_number) {
      *best_info = pad->info;
      best_format_number = format_number;
    }
  }
  GST_OBJECT_UNLOCK (vagg);

  g_hash_table_unref (formats_table);
}

/* WITH GST_VIDEO_AGGREGATOR_LOCK TAKEN */
static gboolean
gst_videoaggregator_src_setcaps (GstVideoAggregator * vagg, GstCaps * caps)
{
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  gboolean ret = FALSE;
  GstVideoInfo info;

  GstPad *pad = GST_AGGREGATOR (vagg)->srcpad;

  GST_INFO_OBJECT (pad, "set src caps: %" GST_PTR_FORMAT, caps);

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

  ret = TRUE;

  if (GST_VIDEO_INFO_FPS_N (&vagg->info) != GST_VIDEO_INFO_FPS_N (&info) ||
      GST_VIDEO_INFO_FPS_D (&vagg->info) != GST_VIDEO_INFO_FPS_D (&info)) {
    if (agg->segment.position != -1) {
      vagg->priv->nframes = 0;
      /* The timestamp offset will be updated based on the
       * segment position the next time we aggregate */
      GST_DEBUG_OBJECT (vagg,
          "Resetting frame counter because of framerate change");
    }
    gst_videoaggregator_reset_qos (vagg);
  }

  vagg->info = info;

  if (vagg->priv->current_caps == NULL ||
      gst_caps_is_equal (caps, vagg->priv->current_caps) == FALSE) {
    GstClockTime latency;

    gst_caps_replace (&vagg->priv->current_caps, caps);
    GST_VIDEO_AGGREGATOR_UNLOCK (vagg);

    gst_aggregator_set_src_caps (agg, caps);
    latency = gst_util_uint64_scale (GST_SECOND,
        GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info));
    gst_aggregator_set_latency (agg, latency, latency);

    GST_VIDEO_AGGREGATOR_LOCK (vagg);
  }

done:
  return ret;
}

static GstCaps *
gst_videoaggregator_default_fixate_caps (GstVideoAggregator * vagg,
    GstCaps * caps)
{
  gint best_width = -1, best_height = -1;
  gint best_fps_n = -1, best_fps_d = -1;
  gdouble best_fps = -1.;
  GstStructure *s;
  GList *l;

  GST_OBJECT_LOCK (vagg);
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *mpad = l->data;
    gint fps_n, fps_d;
    gint width, height;
    gdouble cur_fps;

    fps_n = GST_VIDEO_INFO_FPS_N (&mpad->info);
    fps_d = GST_VIDEO_INFO_FPS_D (&mpad->info);
    width = GST_VIDEO_INFO_WIDTH (&mpad->info);
    height = GST_VIDEO_INFO_HEIGHT (&mpad->info);

    if (width == 0 || height == 0)
      continue;

    if (best_width < width)
      best_width = width;
    if (best_height < height)
      best_height = height;

    if (fps_d == 0)
      cur_fps = 0.0;
    else
      gst_util_fraction_to_double (fps_n, fps_d, &cur_fps);

    if (best_fps < cur_fps) {
      best_fps = cur_fps;
      best_fps_n = fps_n;
      best_fps_d = fps_d;
    }
  }
  GST_OBJECT_UNLOCK (vagg);

  if (best_fps_n <= 0 || best_fps_d <= 0 || best_fps == 0.0) {
    best_fps_n = 25;
    best_fps_d = 1;
    best_fps = 25.0;
  }

  s = gst_caps_get_structure (caps, 0);
  gst_structure_fixate_field_nearest_int (s, "width", best_width);
  gst_structure_fixate_field_nearest_int (s, "height", best_height);
  gst_structure_fixate_field_nearest_fraction (s, "framerate", best_fps_n,
      best_fps_d);
  if (gst_structure_has_field (s, "pixel-aspect-ratio"))
    gst_structure_fixate_field_nearest_fraction (s, "pixel-aspect-ratio", 1, 1);
  caps = gst_caps_fixate (caps);

  return caps;
}

static GstCaps *
gst_videoaggregator_default_update_caps (GstVideoAggregator * vagg,
    GstCaps * caps, GstCaps * filter)
{
  GstVideoAggregatorClass *vagg_klass = GST_VIDEO_AGGREGATOR_GET_CLASS (vagg);
  GstCaps *ret, *best_format_caps;
  gboolean at_least_one_alpha = FALSE;
  GstVideoFormat best_format;
  GstVideoInfo best_info;

  best_format = GST_VIDEO_FORMAT_UNKNOWN;
  gst_video_info_init (&best_info);

  if (vagg_klass->find_best_format) {
    vagg_klass->find_best_format (vagg, caps, &best_info, &at_least_one_alpha);

    best_format = GST_VIDEO_INFO_FORMAT (&best_info);
  }

  if (best_format == GST_VIDEO_FORMAT_UNKNOWN) {
    GstCaps *tmp = gst_caps_fixate (gst_caps_ref (caps));
    gst_video_info_from_caps (&best_info, tmp);
    best_format = GST_VIDEO_INFO_FORMAT (&best_info);
    gst_caps_unref (tmp);
  }

  GST_DEBUG_OBJECT (vagg,
      "The output format will now be : %d with chroma : %s",
      best_format, gst_video_chroma_to_string (best_info.chroma_site));

  best_format_caps = gst_caps_copy (caps);
  gst_caps_set_simple (best_format_caps, "format", G_TYPE_STRING,
      gst_video_format_to_string (best_format), "chroma-site", G_TYPE_STRING,
      gst_video_chroma_to_string (best_info.chroma_site), NULL);
  ret = gst_caps_merge (best_format_caps, gst_caps_ref (caps));

  if (filter) {
    ret = gst_caps_intersect (ret, filter);
  } else {
    gst_caps_ref (ret);
  }

  return ret;
}

/* WITH GST_VIDEO_AGGREGATOR_LOCK TAKEN */
static gboolean
gst_videoaggregator_update_src_caps (GstVideoAggregator * vagg)
{
  GstVideoAggregatorClass *vagg_klass = GST_VIDEO_AGGREGATOR_GET_CLASS (vagg);
  GstVideoAggregatorPadClass *vaggpad_klass = g_type_class_peek
      (GST_AGGREGATOR_GET_CLASS (vagg)->sinkpads_type);
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  gboolean ret = TRUE, at_least_one_pad_configured = FALSE;
  gboolean at_least_one_alpha = FALSE;
  GstCaps *downstream_caps;
  GList *l;

  downstream_caps = gst_pad_get_allowed_caps (agg->srcpad);

  if (!downstream_caps || gst_caps_is_empty (downstream_caps)) {
    GST_INFO_OBJECT (vagg, "No downstream caps found %"
        GST_PTR_FORMAT, downstream_caps);
    if (downstream_caps)
      gst_caps_unref (downstream_caps);
    return FALSE;
  }

  GST_OBJECT_LOCK (vagg);
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *mpad = l->data;

    if (GST_VIDEO_INFO_WIDTH (&mpad->info) == 0
        || GST_VIDEO_INFO_HEIGHT (&mpad->info) == 0)
      continue;

    if (mpad->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_ALPHA)
      at_least_one_alpha = TRUE;

    at_least_one_pad_configured = TRUE;
  }
  GST_OBJECT_UNLOCK (vagg);

  if (at_least_one_pad_configured) {
    GstCaps *caps, *peercaps;

    peercaps = gst_pad_peer_query_caps (agg->srcpad, NULL);

    g_assert (vagg_klass->update_caps);
    GST_DEBUG_OBJECT (vagg, "updating caps from %" GST_PTR_FORMAT,
        downstream_caps);
    GST_DEBUG_OBJECT (vagg, "       with filter %" GST_PTR_FORMAT, peercaps);
    if (!(caps = vagg_klass->update_caps (vagg, downstream_caps, peercaps))) {
      GST_WARNING_OBJECT (vagg, "Subclass failed to update provided caps");
      gst_caps_unref (downstream_caps);
      if (peercaps)
        gst_caps_unref (peercaps);
      ret = FALSE;
      goto done;
    }
    GST_DEBUG_OBJECT (vagg, "               to %" GST_PTR_FORMAT, caps);

    gst_caps_unref (downstream_caps);
    if (peercaps)
      gst_caps_unref (peercaps);

    if (!gst_caps_is_fixed (caps)) {
      g_assert (vagg_klass->fixate_caps);

      caps = gst_caps_make_writable (caps);
      GST_DEBUG_OBJECT (vagg, "fixate caps from %" GST_PTR_FORMAT, caps);
      if (!(caps = vagg_klass->fixate_caps (vagg, caps))) {
        GST_WARNING_OBJECT (vagg, "Subclass failed to fixate provided caps");
        ret = FALSE;
        goto done;
      }
      GST_DEBUG_OBJECT (vagg, "             to %" GST_PTR_FORMAT, caps);
    }

    {
      const GstVideoFormatInfo *finfo;
      const gchar *v_format_str;
      GstVideoFormat v_format;
      GstStructure *s;

      s = gst_caps_get_structure (caps, 0);
      v_format_str = gst_structure_get_string (s, "format");
      g_return_val_if_fail (v_format_str != NULL, FALSE);
      v_format = gst_video_format_from_string (v_format_str);
      g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
      finfo = gst_video_format_get_info (v_format);
      g_return_val_if_fail (finfo != NULL, FALSE);

      if (at_least_one_alpha && !(finfo->flags & GST_VIDEO_FORMAT_FLAG_ALPHA)) {
        GST_ELEMENT_ERROR (vagg, CORE, NEGOTIATION,
            ("At least one of the input pads contains alpha, but configured caps don't support alpha."),
            ("Either convert your inputs to not contain alpha or add a videoconvert after the aggregator"));
        ret = FALSE;
        goto done;
      }
    }

    gst_video_info_from_caps (&vagg->info, caps);

    if (vaggpad_klass->set_info) {
      /* Then browse the sinks once more, setting or unsetting conversion if needed */
      for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
        GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (l->data);

        if (!vaggpad_klass->set_info (pad, vagg, &pad->info, &vagg->info)) {
          GST_OBJECT_UNLOCK (vagg);

          return FALSE;
        }
      }
    }

    if (gst_videoaggregator_src_setcaps (vagg, caps)) {
      if (vagg_klass->negotiated_caps)
        ret =
            GST_VIDEO_AGGREGATOR_GET_CLASS (vagg)->negotiated_caps (vagg, caps);
    }
    gst_caps_unref (caps);
  } else {
    /* We couldn't decide the output video info because the sinkpads don't have
     * all the caps yet, so we mark the pad as needing a reconfigure. This
     * allows aggregate() to skip ahead a bit and try again later. */
    GST_DEBUG_OBJECT (vagg, "Couldn't decide output video info");
    gst_pad_mark_reconfigure (agg->srcpad);
    ret = FALSE;
  }

done:
  return ret;
}

static gboolean
gst_videoaggregator_pad_sink_setcaps (GstPad * pad, GstObject * parent,
    GstCaps * caps)
{
  GstVideoAggregator *vagg;
  GstVideoAggregatorPad *vaggpad;
  GstVideoInfo info;
  gboolean ret = FALSE;

  GST_INFO_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, caps);

  vagg = GST_VIDEO_AGGREGATOR (parent);
  vaggpad = GST_VIDEO_AGGREGATOR_PAD (pad);

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_DEBUG_OBJECT (pad, "Failed to parse caps");
    goto beach;
  }

  GST_VIDEO_AGGREGATOR_LOCK (vagg);
  if (GST_VIDEO_INFO_FORMAT (&vagg->info) != GST_VIDEO_FORMAT_UNKNOWN) {
    if (GST_VIDEO_INFO_INTERLACE_MODE (&vagg->info) !=
        GST_VIDEO_INFO_INTERLACE_MODE (&info)) {
      GST_ERROR_OBJECT (pad,
          "got input caps %" GST_PTR_FORMAT ", but " "current caps are %"
          GST_PTR_FORMAT, caps, vagg->priv->current_caps);
      GST_VIDEO_AGGREGATOR_UNLOCK (vagg);
      return FALSE;
    }
  }

  vaggpad->info = info;
  gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (vagg));
  ret = TRUE;

  GST_VIDEO_AGGREGATOR_UNLOCK (vagg);

beach:
  return ret;
}

static gboolean
gst_videoaggregator_caps_has_alpha (GstCaps * caps)
{
  guint size = gst_caps_get_size (caps);
  guint i;

  for (i = 0; i < size; i++) {
    GstStructure *s = gst_caps_get_structure (caps, i);
    const GValue *formats = gst_structure_get_value (s, "format");

    if (formats) {
      const GstVideoFormatInfo *info;

      if (GST_VALUE_HOLDS_LIST (formats)) {
        guint list_size = gst_value_list_get_size (formats);
        guint index;

        for (index = 0; index < list_size; index++) {
          const GValue *list_item = gst_value_list_get_value (formats, index);
          info =
              gst_video_format_get_info (gst_video_format_from_string
              (g_value_get_string (list_item)));
          if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info))
            return TRUE;
        }

      } else if (G_VALUE_HOLDS_STRING (formats)) {
        info =
            gst_video_format_get_info (gst_video_format_from_string
            (g_value_get_string (formats)));
        if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info))
          return TRUE;

      } else {
        g_assert_not_reached ();
        GST_WARNING ("Unexpected type for video 'format' field: %s",
            G_VALUE_TYPE_NAME (formats));
      }

    } else {
      return TRUE;
    }
  }
  return FALSE;
}

static GstCaps *
gst_videoaggregator_pad_sink_getcaps (GstPad * pad, GstVideoAggregator * vagg,
    GstCaps * filter)
{
  GstCaps *srccaps;
  GstCaps *template_caps, *sink_template_caps;
  GstCaps *returned_caps;
  GstStructure *s;
  gint i, n;
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  GstPad *srcpad = GST_PAD (agg->srcpad);
  gboolean has_alpha;

  template_caps = gst_pad_get_pad_template_caps (srcpad);

  GST_DEBUG_OBJECT (pad, "Get caps with filter: %" GST_PTR_FORMAT, filter);

  srccaps = gst_pad_peer_query_caps (srcpad, template_caps);
  srccaps = gst_caps_make_writable (srccaps);
  has_alpha = gst_videoaggregator_caps_has_alpha (srccaps);

  n = gst_caps_get_size (srccaps);
  for (i = 0; i < n; i++) {
    s = gst_caps_get_structure (srccaps, i);
    gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
        "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);

    gst_structure_remove_fields (s, "colorimetry", "chroma-site", "format",
        "pixel-aspect-ratio", NULL);
  }

  if (filter) {
    returned_caps = gst_caps_intersect (srccaps, filter);
    gst_caps_unref (srccaps);
  } else {
    returned_caps = srccaps;
  }

  if (has_alpha) {
    sink_template_caps = gst_pad_get_pad_template_caps (pad);
  } else {
    GstVideoAggregatorClass *klass = GST_VIDEO_AGGREGATOR_GET_CLASS (vagg);
    sink_template_caps = gst_caps_ref (klass->sink_non_alpha_caps);
  }

  {
    GstCaps *intersect = gst_caps_intersect (returned_caps, sink_template_caps);
    gst_caps_unref (returned_caps);
    returned_caps = intersect;
  }

  gst_caps_unref (template_caps);
  gst_caps_unref (sink_template_caps);

  GST_DEBUG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, returned_caps);

  return returned_caps;
}

static void
gst_videoaggregator_update_qos (GstVideoAggregator * vagg, gdouble proportion,
    GstClockTimeDiff diff, GstClockTime timestamp)
{
  gboolean live;

  GST_DEBUG_OBJECT (vagg,
      "Updating QoS: proportion %lf, diff %" GST_STIME_FORMAT ", timestamp %"
      GST_TIME_FORMAT, proportion, GST_STIME_ARGS (diff),
      GST_TIME_ARGS (timestamp));

  live =
      GST_CLOCK_TIME_IS_VALID (gst_aggregator_get_latency (GST_AGGREGATOR
          (vagg)));

  GST_OBJECT_LOCK (vagg);

  vagg->priv->proportion = proportion;
  if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
    if (!live && G_UNLIKELY (diff > 0))
      vagg->priv->earliest_time =
          timestamp + 2 * diff + gst_util_uint64_scale_int_round (GST_SECOND,
          GST_VIDEO_INFO_FPS_D (&vagg->info),
          GST_VIDEO_INFO_FPS_N (&vagg->info));
    else
      vagg->priv->earliest_time = timestamp + diff;
  } else {
    vagg->priv->earliest_time = GST_CLOCK_TIME_NONE;
  }
  GST_OBJECT_UNLOCK (vagg);
}

static void
gst_videoaggregator_reset_qos (GstVideoAggregator * vagg)
{
  gst_videoaggregator_update_qos (vagg, 0.5, 0, GST_CLOCK_TIME_NONE);
  vagg->priv->qos_processed = vagg->priv->qos_dropped = 0;
}

static void
gst_videoaggregator_read_qos (GstVideoAggregator * vagg, gdouble * proportion,
    GstClockTime * time)
{
  GST_OBJECT_LOCK (vagg);
  *proportion = vagg->priv->proportion;
  *time = vagg->priv->earliest_time;
  GST_OBJECT_UNLOCK (vagg);
}

static void
gst_videoaggregator_reset (GstVideoAggregator * vagg)
{
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  GList *l;

  gst_video_info_init (&vagg->info);
  vagg->priv->ts_offset = 0;
  vagg->priv->nframes = 0;
  vagg->priv->live = FALSE;

  agg->segment.position = -1;

  gst_videoaggregator_reset_qos (vagg);

  GST_OBJECT_LOCK (vagg);
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *p = l->data;

    gst_buffer_replace (&p->buffer, NULL);
    p->priv->start_time = -1;
    p->priv->end_time = -1;

    gst_video_info_init (&p->info);
  }
  GST_OBJECT_UNLOCK (vagg);
}

#define GST_FLOW_NEEDS_DATA GST_FLOW_CUSTOM_ERROR
static gint
gst_videoaggregator_fill_queues (GstVideoAggregator * vagg,
    GstClockTime output_start_running_time,
    GstClockTime output_end_running_time)
{
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  GList *l;
  gboolean eos = TRUE;
  gboolean need_more_data = FALSE;

  /* get a set of buffers into pad->buffer that are within output_start_running_time
   * and output_end_running_time taking into account finished and unresponsive pads */

  GST_OBJECT_LOCK (vagg);
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *pad = l->data;
    GstSegment segment;
    GstAggregatorPad *bpad;
    GstBuffer *buf;
    GstVideoInfo *vinfo;
    gboolean is_eos;

    bpad = GST_AGGREGATOR_PAD (pad);
    GST_OBJECT_LOCK (bpad);
    segment = bpad->segment;
    GST_OBJECT_UNLOCK (bpad);
    is_eos = gst_aggregator_pad_is_eos (bpad);

    if (!is_eos)
      eos = FALSE;
    buf = gst_aggregator_pad_get_buffer (bpad);
    if (buf) {
      GstClockTime start_time, end_time;

      start_time = GST_BUFFER_TIMESTAMP (buf);
      if (start_time == -1) {
        gst_buffer_unref (buf);
        GST_DEBUG_OBJECT (pad, "Need timestamped buffers!");
        GST_OBJECT_UNLOCK (vagg);
        return GST_FLOW_ERROR;
      }

      vinfo = &pad->info;

      /* FIXME: Make all this work with negative rates */
      end_time = GST_BUFFER_DURATION (buf);

      if (end_time == -1) {
        start_time = MAX (start_time, segment.start);
        start_time =
            gst_segment_to_running_time (&segment, GST_FORMAT_TIME, start_time);

        if (start_time >= output_end_running_time) {
          if (pad->buffer) {
            GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time >= "
                "output_end_running_time. Keeping previous buffer");
          } else {
            GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time >= "
                "output_end_running_time. No previous buffer, need more data");
            need_more_data = TRUE;
          }
          gst_buffer_unref (buf);
          continue;
        } else if (start_time < output_start_running_time) {
          GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time < "
              "output_start_running_time.  Discarding old buffer");
          gst_buffer_replace (&pad->buffer, buf);
          pad->buffer_vinfo = *vinfo;
          gst_buffer_unref (buf);
          gst_aggregator_pad_drop_buffer (bpad);
          need_more_data = TRUE;
          continue;
        }
        gst_buffer_unref (buf);
        buf = gst_aggregator_pad_steal_buffer (bpad);
        gst_buffer_replace (&pad->buffer, buf);
        pad->buffer_vinfo = *vinfo;
        /* FIXME: Set start_time and end_time to something here? */
        gst_buffer_unref (buf);
        GST_DEBUG_OBJECT (pad, "buffer duration is -1");
        continue;
      }

      g_assert (start_time != -1 && end_time != -1);
      end_time += start_time;   /* convert from duration to position */

      /* Check if it's inside the segment */
      if (start_time >= segment.stop || end_time < segment.start) {
        GST_DEBUG_OBJECT (pad,
            "Buffer outside the segment : segment: [%" GST_TIME_FORMAT " -- %"
            GST_TIME_FORMAT "]" " Buffer [%" GST_TIME_FORMAT " -- %"
            GST_TIME_FORMAT "]", GST_TIME_ARGS (segment.stop),
            GST_TIME_ARGS (segment.start), GST_TIME_ARGS (start_time),
            GST_TIME_ARGS (end_time));

        gst_buffer_unref (buf);
        gst_aggregator_pad_drop_buffer (bpad);

        need_more_data = TRUE;
        continue;
      }

      /* Clip to segment and convert to running time */
      start_time = MAX (start_time, segment.start);
      if (segment.stop != -1)
        end_time = MIN (end_time, segment.stop);
      start_time =
          gst_segment_to_running_time (&segment, GST_FORMAT_TIME, start_time);
      end_time =
          gst_segment_to_running_time (&segment, GST_FORMAT_TIME, end_time);
      g_assert (start_time != -1 && end_time != -1);

      /* Convert to the output segment rate */
      if (ABS (agg->segment.rate) != 1.0) {
        start_time *= ABS (agg->segment.rate);
        end_time *= ABS (agg->segment.rate);
      }

      GST_TRACE_OBJECT (pad, "dealing with buffer %p start %" GST_TIME_FORMAT
          " end %" GST_TIME_FORMAT " out start %" GST_TIME_FORMAT
          " out end %" GST_TIME_FORMAT, buf, GST_TIME_ARGS (start_time),
          GST_TIME_ARGS (end_time), GST_TIME_ARGS (output_start_running_time),
          GST_TIME_ARGS (output_end_running_time));

      if (pad->priv->end_time != -1 && pad->priv->end_time > end_time) {
        GST_DEBUG_OBJECT (pad, "Buffer from the past, dropping");
        gst_buffer_unref (buf);
        gst_aggregator_pad_drop_buffer (bpad);
        continue;
      }

      if (end_time >= output_start_running_time
          && start_time < output_end_running_time) {
        GST_DEBUG_OBJECT (pad,
            "Taking new buffer with start time %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start_time));
        gst_buffer_replace (&pad->buffer, buf);
        pad->buffer_vinfo = *vinfo;
        pad->priv->start_time = start_time;
        pad->priv->end_time = end_time;

        gst_buffer_unref (buf);
        gst_aggregator_pad_drop_buffer (bpad);
        eos = FALSE;
      } else if (start_time >= output_end_running_time) {
        GST_DEBUG_OBJECT (pad, "Keeping buffer until %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start_time));
        gst_buffer_unref (buf);
        eos = FALSE;
      } else {
        gst_buffer_replace (&pad->buffer, buf);
        pad->buffer_vinfo = *vinfo;
        pad->priv->start_time = start_time;
        pad->priv->end_time = end_time;
        GST_DEBUG_OBJECT (pad,
            "replacing old buffer with a newer buffer, start %" GST_TIME_FORMAT
            " out end %" GST_TIME_FORMAT, GST_TIME_ARGS (start_time),
            GST_TIME_ARGS (output_end_running_time));
        gst_buffer_unref (buf);
        gst_aggregator_pad_drop_buffer (bpad);

        need_more_data = TRUE;
        continue;
      }
    } else {
      if (is_eos && pad->ignore_eos) {
        eos = FALSE;
        GST_DEBUG_OBJECT (pad, "ignoring EOS and re-using previous buffer");
        continue;
      }

      if (pad->priv->end_time != -1) {
        if (pad->priv->end_time <= output_start_running_time) {
          pad->priv->start_time = pad->priv->end_time = -1;
          if (is_eos) {
            GST_DEBUG ("I just need more data");
            need_more_data = TRUE;
          }
        } else if (is_eos) {
          eos = FALSE;
        }
      } else if (is_eos) {
        gst_buffer_replace (&pad->buffer, NULL);
      }
    }
  }
  GST_OBJECT_UNLOCK (vagg);

  if (need_more_data)
    return GST_FLOW_NEEDS_DATA;
  if (eos)
    return GST_FLOW_EOS;

  return GST_FLOW_OK;
}

static gboolean
sync_pad_values (GstVideoAggregator * vagg, GstVideoAggregatorPad * pad)
{
  GstAggregatorPad *bpad = GST_AGGREGATOR_PAD (pad);
  GstClockTime timestamp;
  gint64 stream_time;

  if (pad->buffer == NULL)
    return TRUE;

  timestamp = GST_BUFFER_TIMESTAMP (pad->buffer);
  GST_OBJECT_LOCK (bpad);
  stream_time = gst_segment_to_stream_time (&bpad->segment, GST_FORMAT_TIME,
      timestamp);
  GST_OBJECT_UNLOCK (bpad);

  /* sync object properties on stream time */
  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (pad), stream_time);

  return TRUE;
}

static gboolean
prepare_frames (GstVideoAggregator * vagg, GstVideoAggregatorPad * pad)
{
  GstVideoAggregatorPadClass *vaggpad_class =
      GST_VIDEO_AGGREGATOR_PAD_GET_CLASS (pad);

  if (pad->buffer == NULL || !vaggpad_class->prepare_frame)
    return TRUE;

  return vaggpad_class->prepare_frame (pad, vagg);
}

static gboolean
clean_pad (GstVideoAggregator * vagg, GstVideoAggregatorPad * pad)
{
  GstVideoAggregatorPadClass *vaggpad_class =
      GST_VIDEO_AGGREGATOR_PAD_GET_CLASS (pad);

  vaggpad_class->clean_frame (pad, vagg);

  return TRUE;
}

static GstFlowReturn
gst_videoaggregator_do_aggregate (GstVideoAggregator * vagg,
    GstClockTime output_start_time, GstClockTime output_end_time,
    GstBuffer ** outbuf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (vagg);
  GstVideoAggregatorClass *vagg_klass = (GstVideoAggregatorClass *) klass;
  GstVideoAggregatorPadClass *vaggpad_class = g_type_class_peek
      (GST_AGGREGATOR_CLASS (klass)->sinkpads_type);

  g_assert (vagg_klass->aggregate_frames != NULL);
  g_assert (vagg_klass->get_output_buffer != NULL);

  if ((ret = vagg_klass->get_output_buffer (vagg, outbuf)) != GST_FLOW_OK) {
    GST_WARNING_OBJECT (vagg, "Could not get an output buffer, reason: %s",
        gst_flow_get_name (ret));
    return ret;
  }
  if (*outbuf == NULL) {
    /* sub-class doesn't want to generate output right now */
    return GST_FLOW_OK;
  }

  GST_BUFFER_TIMESTAMP (*outbuf) = output_start_time;
  GST_BUFFER_DURATION (*outbuf) = output_end_time - output_start_time;

  /* Sync pad properties to the stream time */
  gst_aggregator_iterate_sinkpads (GST_AGGREGATOR (vagg),
      (GstAggregatorPadForeachFunc) sync_pad_values, NULL);

  /* Convert all the frames the subclass has before aggregating */
  gst_aggregator_iterate_sinkpads (GST_AGGREGATOR (vagg),
      (GstAggregatorPadForeachFunc) prepare_frames, NULL);

  ret = vagg_klass->aggregate_frames (vagg, *outbuf);

  if (vaggpad_class->clean_frame) {
    gst_aggregator_iterate_sinkpads (GST_AGGREGATOR (vagg),
        (GstAggregatorPadForeachFunc) clean_pad, NULL);
  }

  return ret;
}

/* Perform qos calculations before processing the next frame. Returns TRUE if
 * the frame should be processed, FALSE if the frame can be dropped entirely */
static gint64
gst_videoaggregator_do_qos (GstVideoAggregator * vagg, GstClockTime timestamp)
{
  GstAggregator *agg = GST_AGGREGATOR (vagg);
  GstClockTime qostime, earliest_time;
  gdouble proportion;
  gint64 jitter;

  /* no timestamp, can't do QoS => process frame */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
    GST_LOG_OBJECT (vagg, "invalid timestamp, can't do QoS, process frame");
    return -1;
  }

  /* get latest QoS observation values */
  gst_videoaggregator_read_qos (vagg, &proportion, &earliest_time);

  /* skip qos if we have no observation (yet) => process frame */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
    GST_LOG_OBJECT (vagg, "no observation yet, process frame");
    return -1;
  }

  /* qos is done on running time */
  qostime =
      gst_segment_to_running_time (&agg->segment, GST_FORMAT_TIME, timestamp);

  /* see how our next timestamp relates to the latest qos timestamp */
  GST_LOG_OBJECT (vagg, "qostime %" GST_TIME_FORMAT ", earliest %"
      GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));

  jitter = GST_CLOCK_DIFF (qostime, earliest_time);
  if (qostime != GST_CLOCK_TIME_NONE && jitter > 0) {
    GST_DEBUG_OBJECT (vagg, "we are late, drop frame");
    return jitter;
  }

  GST_LOG_OBJECT (vagg, "process frame");
  return jitter;
}

static GstClockTime
gst_videoaggregator_get_next_time (GstAggregator * agg)
{
  GstClockTime next_time;

  GST_OBJECT_LOCK (agg);
  if (agg->segment.position == -1 || agg->segment.position < agg->segment.start)
    next_time = agg->segment.start;
  else
    next_time = agg->segment.position;

  if (agg->segment.stop != -1 && next_time > agg->segment.stop)
    next_time = agg->segment.stop;

  next_time =
      gst_segment_to_running_time (&agg->segment, GST_FORMAT_TIME, next_time);
  GST_OBJECT_UNLOCK (agg);

  return next_time;
}

static GstFlowReturn
gst_videoaggregator_check_reconfigure (GstVideoAggregator * vagg,
    gboolean timeout)
{
  GstAggregator *agg = (GstAggregator *) vagg;

  if (GST_VIDEO_INFO_FORMAT (&vagg->info) == GST_VIDEO_FORMAT_UNKNOWN
      || gst_pad_check_reconfigure (GST_AGGREGATOR_SRC_PAD (vagg))) {
    gboolean ret;

    ret = gst_videoaggregator_update_src_caps (vagg);
    if (!ret) {
      if (timeout && gst_pad_needs_reconfigure (GST_AGGREGATOR_SRC_PAD (vagg))) {
        guint64 frame_duration;
        gint fps_d, fps_n;

        GST_DEBUG_OBJECT (vagg,
            "Got timeout before receiving any caps, don't output anything");

        if (agg->segment.position == -1) {
          if (agg->segment.rate > 0.0)
            agg->segment.position = agg->segment.start;
          else
            agg->segment.position = agg->segment.stop;
        }

        /* Advance position */
        fps_d = GST_VIDEO_INFO_FPS_D (&vagg->info) ?
            GST_VIDEO_INFO_FPS_D (&vagg->info) : 1;
        fps_n = GST_VIDEO_INFO_FPS_N (&vagg->info) ?
            GST_VIDEO_INFO_FPS_N (&vagg->info) : 25;
        /* Default to 25/1 if no "best fps" is known */
        frame_duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n);
        if (agg->segment.rate > 0.0)
          agg->segment.position += frame_duration;
        else if (agg->segment.position > frame_duration)
          agg->segment.position -= frame_duration;
        else
          agg->segment.position = 0;
        vagg->priv->nframes++;
        return GST_FLOW_NEEDS_DATA;
      } else {
        return GST_FLOW_NOT_NEGOTIATED;
      }
    }
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_videoaggregator_aggregate (GstAggregator * agg, gboolean timeout)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);
  GstClockTime output_start_time, output_end_time;
  GstClockTime output_start_running_time, output_end_running_time;
  GstBuffer *outbuf = NULL;
  GstFlowReturn flow_ret;
  gint64 jitter;

  GST_VIDEO_AGGREGATOR_LOCK (vagg);

  flow_ret = gst_videoaggregator_check_reconfigure (vagg, timeout);
  if (flow_ret != GST_FLOW_OK) {
    if (flow_ret == GST_FLOW_NEEDS_DATA)
      flow_ret = GST_FLOW_OK;
    goto unlock_and_return;
  }

  output_start_time = agg->segment.position;
  if (agg->segment.position == -1 || agg->segment.position < agg->segment.start)
    output_start_time = agg->segment.start;

  if (vagg->priv->nframes == 0) {
    vagg->priv->ts_offset = output_start_time;
    GST_DEBUG_OBJECT (vagg, "New ts offset %" GST_TIME_FORMAT,
        GST_TIME_ARGS (output_start_time));
  }

  if (GST_VIDEO_INFO_FPS_N (&vagg->info) == 0) {
    output_end_time = -1;
  } else {
    output_end_time =
        vagg->priv->ts_offset +
        gst_util_uint64_scale_round (vagg->priv->nframes + 1,
        GST_SECOND * GST_VIDEO_INFO_FPS_D (&vagg->info),
        GST_VIDEO_INFO_FPS_N (&vagg->info));
  }

  if (agg->segment.stop != -1)
    output_end_time = MIN (output_end_time, agg->segment.stop);

  output_start_running_time =
      gst_segment_to_running_time (&agg->segment, GST_FORMAT_TIME,
      output_start_time);
  output_end_running_time =
      gst_segment_to_running_time (&agg->segment, GST_FORMAT_TIME,
      output_end_time);

  if (output_end_time == output_start_time) {
    flow_ret = GST_FLOW_EOS;
  } else {
    flow_ret =
        gst_videoaggregator_fill_queues (vagg, output_start_running_time,
        output_end_running_time);
  }

  if (flow_ret == GST_FLOW_NEEDS_DATA && !timeout) {
    GST_DEBUG_OBJECT (vagg, "Need more data for decisions");
    flow_ret = GST_FLOW_OK;
    goto unlock_and_return;
  } else if (flow_ret == GST_FLOW_EOS) {
    GST_DEBUG_OBJECT (vagg, "All sinkpads are EOS -- forwarding");
    goto unlock_and_return;
  } else if (flow_ret == GST_FLOW_ERROR) {
    GST_WARNING_OBJECT (vagg, "Error collecting buffers");
    goto unlock_and_return;
  }

  GST_DEBUG_OBJECT (vagg,
      "Producing buffer for %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
      ", running time start %" GST_TIME_FORMAT ", running time end %"
      GST_TIME_FORMAT, GST_TIME_ARGS (output_start_time),
      GST_TIME_ARGS (output_end_time),
      GST_TIME_ARGS (output_start_running_time),
      GST_TIME_ARGS (output_end_running_time));

  jitter = gst_videoaggregator_do_qos (vagg, output_start_time);
  if (jitter <= 0) {
    flow_ret = gst_videoaggregator_do_aggregate (vagg, output_start_time,
        output_end_time, &outbuf);
    if (flow_ret != GST_FLOW_OK)
      goto done;
    vagg->priv->qos_processed++;
  } else {
    GstMessage *msg;

    vagg->priv->qos_dropped++;

    msg =
        gst_message_new_qos (GST_OBJECT_CAST (vagg), vagg->priv->live,
        output_start_running_time, gst_segment_to_stream_time (&agg->segment,
            GST_FORMAT_TIME, output_start_time), output_start_time,
        output_end_time - output_start_time);
    gst_message_set_qos_values (msg, jitter, vagg->priv->proportion, 1000000);
    gst_message_set_qos_stats (msg, GST_FORMAT_BUFFERS,
        vagg->priv->qos_processed, vagg->priv->qos_dropped);
    gst_element_post_message (GST_ELEMENT_CAST (vagg), msg);

    flow_ret = GST_FLOW_OK;
  }

  GST_VIDEO_AGGREGATOR_UNLOCK (vagg);
  if (outbuf) {
    GST_DEBUG_OBJECT (vagg,
        "Pushing buffer with ts %" GST_TIME_FORMAT " and duration %"
        GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));

    flow_ret = gst_aggregator_finish_buffer (agg, outbuf);
  }

  GST_VIDEO_AGGREGATOR_LOCK (vagg);
  vagg->priv->nframes++;
  agg->segment.position = output_end_time;
  GST_VIDEO_AGGREGATOR_UNLOCK (vagg);

  return flow_ret;

done:
  if (outbuf)
    gst_buffer_unref (outbuf);
unlock_and_return:
  GST_VIDEO_AGGREGATOR_UNLOCK (vagg);
  return flow_ret;
}

/* FIXME, the duration query should reflect how long you will produce
 * data, that is the amount of stream time until you will emit EOS.
 *
 * For synchronized aggregating this is always the max of all the durations
 * of upstream since we emit EOS when all of them finished.
 *
 * We don't do synchronized aggregating so this really depends on where the
 * streams where punched in and what their relative offsets are against
 * each other which we can get from the first timestamps we see.
 *
 * When we add a new stream (or remove a stream) the duration might
 * also become invalid again and we need to post a new DURATION
 * message to notify this fact to the parent.
 * For now we take the max of all the upstream elements so the simple
 * cases work at least somewhat.
 */
static gboolean
gst_videoaggregator_query_duration (GstVideoAggregator * vagg, GstQuery * query)
{
  GValue item = { 0 };
  gint64 max;
  gboolean res;
  GstFormat format;
  GstIterator *it;
  gboolean done;

  /* parse format */
  gst_query_parse_duration (query, &format, NULL);

  max = -1;
  res = TRUE;
  done = FALSE;

  /* Take maximum of all durations */
  it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (vagg));
  while (!done) {
    switch (gst_iterator_next (it, &item)) {
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_OK:
      {
        GstPad *pad;
        gint64 duration;

        pad = g_value_get_object (&item);

        /* ask sink peer for duration */
        res &= gst_pad_peer_query_duration (pad, format, &duration);
        /* take max from all valid return values */
        if (res) {
          /* valid unknown length, stop searching */
          if (duration == -1) {
            max = duration;
            done = TRUE;
          }
          /* else see if bigger than current max */
          else if (duration > max)
            max = duration;
        }
        g_value_reset (&item);
        break;
      }
      case GST_ITERATOR_RESYNC:
        max = -1;
        res = TRUE;
        gst_iterator_resync (it);
        break;
      default:
        res = FALSE;
        done = TRUE;
        break;
    }
  }
  g_value_unset (&item);
  gst_iterator_free (it);

  if (res) {
    /* and store the max */
    GST_DEBUG_OBJECT (vagg, "Total duration in format %s: %"
        GST_TIME_FORMAT, gst_format_get_name (format), GST_TIME_ARGS (max));
    gst_query_set_duration (query, format, max);
  }

  return res;
}

static gboolean
gst_videoaggregator_src_query (GstAggregator * agg, GstQuery * query)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;

      gst_query_parse_position (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          gst_query_set_position (query, format,
              gst_segment_to_stream_time (&agg->segment, GST_FORMAT_TIME,
                  agg->segment.position));
          res = TRUE;
          break;
        default:
          break;
      }
      break;
    }
    case GST_QUERY_DURATION:
      res = gst_videoaggregator_query_duration (vagg, query);
      break;
    case GST_QUERY_LATENCY:
      res =
          GST_AGGREGATOR_CLASS (gst_videoaggregator_parent_class)->src_query
          (agg, query);

      if (res) {
        gst_query_parse_latency (query, &vagg->priv->live, NULL, NULL);
      }
      break;
    default:
      res =
          GST_AGGREGATOR_CLASS (gst_videoaggregator_parent_class)->src_query
          (agg, query);
      break;
  }
  return res;
}

static gboolean
gst_videoaggregator_src_event (GstAggregator * agg, GstEvent * event)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_QOS:
    {
      GstQOSType type;
      GstClockTimeDiff diff;
      GstClockTime timestamp;
      gdouble proportion;

      gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
      gst_videoaggregator_update_qos (vagg, proportion, diff, timestamp);
      break;
    }
    case GST_EVENT_SEEK:
    {
      GST_DEBUG_OBJECT (vagg, "Handling SEEK event");
    }
    default:
      break;
  }

  return
      GST_AGGREGATOR_CLASS (gst_videoaggregator_parent_class)->src_event (agg,
      event);
}

static GstFlowReturn
gst_videoaggregator_flush (GstAggregator * agg)
{
  GList *l;
  gdouble abs_rate;
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);

  GST_INFO_OBJECT (agg, "Flushing");
  GST_OBJECT_LOCK (vagg);
  abs_rate = ABS (agg->segment.rate);
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *p = l->data;

    /* Convert to the output segment rate */
    if (ABS (agg->segment.rate) != abs_rate) {
      if (ABS (agg->segment.rate) != 1.0 && p->buffer) {
        p->priv->start_time /= ABS (agg->segment.rate);
        p->priv->end_time /= ABS (agg->segment.rate);
      }
      if (abs_rate != 1.0 && p->buffer) {
        p->priv->start_time *= abs_rate;
        p->priv->end_time *= abs_rate;
      }
    }
  }
  GST_OBJECT_UNLOCK (vagg);

  agg->segment.position = -1;
  vagg->priv->ts_offset = 0;
  vagg->priv->nframes = 0;

  gst_videoaggregator_reset_qos (vagg);
  return GST_FLOW_OK;
}

static gboolean
gst_videoaggregator_sink_event (GstAggregator * agg, GstAggregatorPad * bpad,
    GstEvent * event)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);
  GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (bpad);
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (pad, "Got %s event on pad %s:%s",
      GST_EVENT_TYPE_NAME (event), GST_DEBUG_PAD_NAME (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret =
          gst_videoaggregator_pad_sink_setcaps (GST_PAD (pad),
          GST_OBJECT (vagg), caps);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_SEGMENT:{
      GstSegment seg;
      gst_event_copy_segment (event, &seg);

      g_assert (seg.format == GST_FORMAT_TIME);
      gst_videoaggregator_reset_qos (vagg);
      break;
    }
    default:
      break;
  }

  if (event != NULL)
    return GST_AGGREGATOR_CLASS (gst_videoaggregator_parent_class)->sink_event
        (agg, bpad, event);

  return ret;
}

static gboolean
gst_videoaggregator_start (GstAggregator * agg)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);

  gst_caps_replace (&vagg->priv->current_caps, NULL);

  return TRUE;
}

static gboolean
gst_videoaggregator_stop (GstAggregator * agg)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);

  gst_videoaggregator_reset (vagg);

  return TRUE;
}

/* GstElement vmethods */
static GstPad *
gst_videoaggregator_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstVideoAggregator *vagg;
  GstVideoAggregatorPad *vaggpad;

  vagg = GST_VIDEO_AGGREGATOR (element);

  vaggpad = (GstVideoAggregatorPad *)
      GST_ELEMENT_CLASS (gst_videoaggregator_parent_class)->request_new_pad
      (element, templ, req_name, caps);

  if (vaggpad == NULL)
    return NULL;

  GST_OBJECT_LOCK (vagg);
  vaggpad->zorder = GST_ELEMENT (vagg)->numsinkpads;
  vaggpad->priv->start_time = -1;
  vaggpad->priv->end_time = -1;
  element->sinkpads = g_list_sort (element->sinkpads,
      (GCompareFunc) pad_zorder_compare);
  GST_OBJECT_UNLOCK (vagg);

  gst_child_proxy_child_added (GST_CHILD_PROXY (vagg), G_OBJECT (vaggpad),
      GST_OBJECT_NAME (vaggpad));

  return GST_PAD (vaggpad);
}

static void
gst_videoaggregator_release_pad (GstElement * element, GstPad * pad)
{
  GstVideoAggregator *vagg = NULL;
  GstVideoAggregatorPad *vaggpad;
  gboolean last_pad;

  vagg = GST_VIDEO_AGGREGATOR (element);
  vaggpad = GST_VIDEO_AGGREGATOR_PAD (pad);

  GST_VIDEO_AGGREGATOR_LOCK (vagg);

  GST_OBJECT_LOCK (vagg);
  last_pad = (GST_ELEMENT (vagg)->numsinkpads - 1 == 0);
  GST_OBJECT_UNLOCK (vagg);

  if (last_pad)
    gst_videoaggregator_reset (vagg);

  gst_buffer_replace (&vaggpad->buffer, NULL);

  gst_child_proxy_child_removed (GST_CHILD_PROXY (vagg), G_OBJECT (vaggpad),
      GST_OBJECT_NAME (vaggpad));

  GST_ELEMENT_CLASS (gst_videoaggregator_parent_class)->release_pad (GST_ELEMENT
      (vagg), pad);

  gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (vagg));

  GST_VIDEO_AGGREGATOR_UNLOCK (vagg);
  return;
}

static GstFlowReturn
gst_videoaggregator_get_output_buffer (GstVideoAggregator * videoaggregator,
    GstBuffer ** outbuf)
{
  guint outsize;
  static GstAllocationParams params = { 0, 15, 0, 0, };

  outsize = GST_VIDEO_INFO_SIZE (&videoaggregator->info);
  *outbuf = gst_buffer_new_allocate (NULL, outsize, &params);

  if (*outbuf == NULL) {
    GST_ERROR_OBJECT (videoaggregator,
        "Could not instantiate buffer of size: %d", outsize);
  }

  return GST_FLOW_OK;
}

static gboolean
gst_videoaggregator_pad_sink_acceptcaps (GstPad * pad,
    GstVideoAggregator * vagg, GstCaps * caps)
{
  gboolean ret;
  GstCaps *modified_caps;
  GstCaps *accepted_caps;
  GstCaps *template_caps;
  gboolean had_current_caps = TRUE;
  gint i, n;
  GstStructure *s;
  GstAggregator *agg = GST_AGGREGATOR (vagg);

  GST_DEBUG_OBJECT (pad, "%" GST_PTR_FORMAT, caps);

  accepted_caps = gst_pad_get_current_caps (GST_PAD (agg->srcpad));

  template_caps = gst_pad_get_pad_template_caps (GST_PAD (agg->srcpad));

  if (accepted_caps == NULL) {
    accepted_caps = template_caps;
    had_current_caps = FALSE;
  }

  accepted_caps = gst_caps_make_writable (accepted_caps);

  GST_LOG_OBJECT (pad, "src caps %" GST_PTR_FORMAT, accepted_caps);

  n = gst_caps_get_size (accepted_caps);
  for (i = 0; i < n; i++) {
    s = gst_caps_get_structure (accepted_caps, i);
    gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
        "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);

    gst_structure_remove_fields (s, "colorimetry", "chroma-site", "format",
        "pixel-aspect-ratio", NULL);
  }

  modified_caps = gst_caps_intersect (accepted_caps, template_caps);

  ret = gst_caps_can_intersect (caps, accepted_caps);
  GST_DEBUG_OBJECT (pad, "%saccepted caps %" GST_PTR_FORMAT,
      (ret ? "" : "not "), caps);
  gst_caps_unref (accepted_caps);
  gst_caps_unref (modified_caps);
  if (had_current_caps)
    gst_caps_unref (template_caps);
  return ret;
}

static gboolean
gst_videoaggregator_sink_query (GstAggregator * agg, GstAggregatorPad * bpad,
    GstQuery * query)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);
  GstVideoAggregatorPad *pad = GST_VIDEO_AGGREGATOR_PAD (bpad);
  gboolean ret = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_videoaggregator_pad_sink_getcaps (GST_PAD (pad), vagg, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      ret = TRUE;
      break;
    }
    case GST_QUERY_ACCEPT_CAPS:
    {
      GstCaps *caps;

      gst_query_parse_accept_caps (query, &caps);
      ret = gst_videoaggregator_pad_sink_acceptcaps (GST_PAD (pad), vagg, caps);
      gst_query_set_accept_caps_result (query, ret);
      ret = TRUE;
      break;
    }
    default:
      ret =
          GST_AGGREGATOR_CLASS (gst_videoaggregator_parent_class)->sink_query
          (agg, bpad, query);
      break;
  }
  return ret;
}

/* GObject vmethods */
static void
gst_videoaggregator_finalize (GObject * o)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (o);

  g_mutex_clear (&vagg->priv->lock);

  G_OBJECT_CLASS (gst_videoaggregator_parent_class)->finalize (o);
}

static void
gst_videoaggregator_dispose (GObject * o)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (o);

  gst_caps_replace (&vagg->priv->current_caps, NULL);

  G_OBJECT_CLASS (gst_videoaggregator_parent_class)->dispose (o);
}

static void
gst_videoaggregator_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_videoaggregator_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GObject boilerplate */
static void
gst_videoaggregator_class_init (GstVideoAggregatorClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstAggregatorClass *agg_class = (GstAggregatorClass *) klass;

  GST_DEBUG_CATEGORY_INIT (gst_videoaggregator_debug, "videoaggregator", 0,
      "base video aggregator");

  gst_videoaggregator_parent_class = g_type_class_peek_parent (klass);

  g_type_class_add_private (klass, sizeof (GstVideoAggregatorPrivate));

  gobject_class->finalize = gst_videoaggregator_finalize;
  gobject_class->dispose = gst_videoaggregator_dispose;

  gobject_class->get_property = gst_videoaggregator_get_property;
  gobject_class->set_property = gst_videoaggregator_set_property;

  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_videoaggregator_request_new_pad);
  gstelement_class->release_pad =
      GST_DEBUG_FUNCPTR (gst_videoaggregator_release_pad);

  agg_class->sinkpads_type = GST_TYPE_VIDEO_AGGREGATOR_PAD;
  agg_class->start = gst_videoaggregator_start;
  agg_class->stop = gst_videoaggregator_stop;
  agg_class->sink_query = gst_videoaggregator_sink_query;
  agg_class->sink_event = gst_videoaggregator_sink_event;
  agg_class->flush = gst_videoaggregator_flush;
  agg_class->aggregate = gst_videoaggregator_aggregate;
  agg_class->src_event = gst_videoaggregator_src_event;
  agg_class->src_query = gst_videoaggregator_src_query;
  agg_class->get_next_time = gst_videoaggregator_get_next_time;

  klass->find_best_format = gst_videoaggreagator_find_best_format;
  klass->get_output_buffer = gst_videoaggregator_get_output_buffer;
  klass->update_caps = gst_videoaggregator_default_update_caps;
  klass->fixate_caps = gst_videoaggregator_default_fixate_caps;

  /* Register the pad class */
  g_type_class_ref (GST_TYPE_VIDEO_AGGREGATOR_PAD);
}

static inline GstCaps *
_get_non_alpha_caps_from_template (GstVideoAggregatorClass * klass)
{
  GstCaps *result;
  GstCaps *templatecaps;
  guint i, size;

  templatecaps =
      gst_pad_template_get_caps (gst_element_class_get_pad_template
      (GST_ELEMENT_CLASS (klass), "sink_%u"));

  size = gst_caps_get_size (templatecaps);
  result = gst_caps_new_empty ();
  for (i = 0; i < size; i++) {
    GstStructure *s = gst_caps_get_structure (templatecaps, i);
    const GValue *formats = gst_structure_get_value (s, "format");
    GValue new_formats = { 0, };
    gboolean has_format = FALSE;

    /* FIXME what to do if formats are missing? */
    if (formats) {
      const GstVideoFormatInfo *info;

      if (GST_VALUE_HOLDS_LIST (formats)) {
        guint list_size = gst_value_list_get_size (formats);
        guint index;

        g_value_init (&new_formats, GST_TYPE_LIST);

        for (index = 0; index < list_size; index++) {
          const GValue *list_item = gst_value_list_get_value (formats, index);

          info =
              gst_video_format_get_info (gst_video_format_from_string
              (g_value_get_string (list_item)));
          if (!GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) {
            has_format = TRUE;
            gst_value_list_append_value (&new_formats, list_item);
          }
        }

      } else if (G_VALUE_HOLDS_STRING (formats)) {
        info =
            gst_video_format_get_info (gst_video_format_from_string
            (g_value_get_string (formats)));
        if (!GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info)) {
          has_format = TRUE;
          gst_value_init_and_copy (&new_formats, formats);
        }

      } else {
        g_assert_not_reached ();
        GST_WARNING ("Unexpected type for video 'format' field: %s",
            G_VALUE_TYPE_NAME (formats));
      }

      if (has_format) {
        s = gst_structure_copy (s);
        gst_structure_take_value (s, "format", &new_formats);
        gst_caps_append_structure (result, s);
      }

    }
  }

  gst_caps_unref (templatecaps);

  return result;
}

static GMutex sink_caps_mutex;

static void
gst_videoaggregator_init (GstVideoAggregator * vagg,
    GstVideoAggregatorClass * klass)
{

  vagg->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (vagg, GST_TYPE_VIDEO_AGGREGATOR,
      GstVideoAggregatorPrivate);

  vagg->priv->current_caps = NULL;

  g_mutex_init (&vagg->priv->lock);

  /* initialize variables */
  g_mutex_lock (&sink_caps_mutex);
  if (klass->sink_non_alpha_caps == NULL) {
    klass->sink_non_alpha_caps = _get_non_alpha_caps_from_template (klass);
  }
  g_mutex_unlock (&sink_caps_mutex);

  gst_videoaggregator_reset (vagg);
}
