/*
 * Combine video streams to 3D stereo
 *
 * GStreamer
 * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2014 Jan Schmidt <jan@noraisin.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.
 */

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

#include "gstglstereomix.h"

#define GST_CAT_DEFAULT gst_gl_stereo_mix_debug
GST_DEBUG_CATEGORY (gst_gl_stereo_mix_debug);

#define gst_gl_stereo_mix_parent_class parent_class
G_DEFINE_TYPE (GstGLStereoMix, gst_gl_stereo_mix, GST_TYPE_GL_MIXER);

static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps);
static gboolean _negotiated_caps (GstVideoAggregator * videoaggregator,
    GstCaps * caps);
gboolean gst_gl_stereo_mix_make_output (GstGLStereoMix * mix);
static gboolean gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer,
    GPtrArray * in_frames);

#define DEFAULT_DOWNMIX GST_GL_STEREO_DOWNMIX_ANAGLYPH_GREEN_MAGENTA_DUBOIS

/* GLStereoMix signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_DOWNMIX_MODE
};

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
        (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
            "RGBA") "; "
        GST_VIDEO_CAPS_MAKE_WITH_FEATURES
        (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
            "RGBA")
        "; " GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS))
    );

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
        (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
            "RGBA") "; "
        GST_VIDEO_CAPS_MAKE_WITH_FEATURES
        (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
            "RGBA")
        "; " GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS))
    );

static GstFlowReturn gst_gl_stereo_mix_get_output_buffer (GstVideoAggregator *
    videoaggregator, GstBuffer ** outbuf);
static gboolean gst_gl_stereo_mix_stop (GstAggregator * agg);
static gboolean gst_gl_stereo_mix_start (GstAggregator * agg);
static gboolean gst_gl_stereo_mix_src_query (GstAggregator * agg,
    GstQuery * query);

static void
gst_gl_stereo_mix_find_best_format (GstVideoAggregator * vagg,
    GstCaps * downstream_caps, GstVideoInfo * best_info,
    gboolean * at_least_one_alpha);

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

static void gst_gl_stereo_mix_finalize (GObject * object);

static GstFlowReturn
gst_gl_stereo_mix_aggregate_frames (GstVideoAggregator * vagg,
    GstBuffer * outbuffer);

static void
gst_gl_stereo_mix_class_init (GstGLStereoMixClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstVideoAggregatorClass *videoaggregator_class =
      (GstVideoAggregatorClass *) klass;
  GstAggregatorClass *agg_class = (GstAggregatorClass *) klass;
  GstGLBaseMixerClass *base_mix_class = (GstGLBaseMixerClass *) klass;

  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "glstereomixer", 0,
      "opengl stereoscopic mixer");

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gl_stereo_mix_finalize);

  gobject_class->get_property = gst_gl_stereo_mix_get_property;
  gobject_class->set_property = gst_gl_stereo_mix_set_property;

  gst_element_class_set_metadata (element_class, "OpenGL stereo video combiner",
      "Filter/Effect/Video", "OpenGL stereo video combiner",
      "Jan Schmidt <jan@centricular.com>");

  g_object_class_install_property (gobject_class, PROP_DOWNMIX_MODE,
      g_param_spec_enum ("downmix-mode", "Mode for mono downmixed output",
          "Output anaglyph type to generate when downmixing to mono",
          GST_TYPE_GL_STEREO_DOWNMIX_MODE_TYPE, DEFAULT_DOWNMIX,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));

  agg_class->stop = gst_gl_stereo_mix_stop;
  agg_class->start = gst_gl_stereo_mix_start;
  agg_class->src_query = gst_gl_stereo_mix_src_query;

  videoaggregator_class->aggregate_frames = gst_gl_stereo_mix_aggregate_frames;
  videoaggregator_class->update_caps = _update_caps;
  videoaggregator_class->negotiated_caps = _negotiated_caps;
  videoaggregator_class->get_output_buffer =
      gst_gl_stereo_mix_get_output_buffer;
  videoaggregator_class->find_best_format = gst_gl_stereo_mix_find_best_format;
  videoaggregator_class->preserve_update_caps_result = TRUE;

  base_mix_class->supported_gl_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
}

static void
gst_gl_stereo_mix_init (GstGLStereoMix * mix)
{
}

static void
gst_gl_stereo_mix_finalize (GObject * object)
{
  //GstGLStereoMix *mix = GST_GL_STEREO_MIX (object);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
gst_gl_stereo_mix_query_caps (GstPad * pad, GstAggregator * agg,
    GstQuery * query)
{
  GstCaps *filter, *caps;

  gst_query_parse_caps (query, &filter);

  caps = gst_pad_get_current_caps (agg->srcpad);
  if (caps == NULL) {
    caps = gst_pad_get_pad_template_caps (agg->srcpad);
  }

  if (filter)
    caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);

  gst_query_set_caps_result (query, caps);
  gst_caps_unref (caps);

  return TRUE;
}

static gboolean
gst_gl_stereo_mix_src_query (GstAggregator * agg, GstQuery * query)
{
  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
      return gst_gl_stereo_mix_query_caps (agg->srcpad, agg, query);
      break;
    default:
      break;
  }

  return GST_AGGREGATOR_CLASS (parent_class)->src_query (agg, query);
}


static GstFlowReturn
gst_gl_stereo_mix_get_output_buffer (GstVideoAggregator * videoaggregator,
    GstBuffer ** outbuf)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (videoaggregator);
  GstFlowReturn ret = GST_FLOW_OK;

#if 0

  if (!mix->priv->pool_active) {
    if (!gst_buffer_pool_set_active (mix->priv->pool, TRUE)) {
      GST_ELEMENT_ERROR (mix, RESOURCE, SETTINGS,
          ("failed to activate bufferpool"), ("failed to activate bufferpool"));
      return GST_FLOW_ERROR;
    }
    mix->priv->pool_active = TRUE;
  }

  return gst_buffer_pool_acquire_buffer (mix->priv->pool, outbuf, NULL);
#endif

  if (!gst_gl_stereo_mix_make_output (mix)) {
    gst_buffer_replace (&mix->primary_out, NULL);
    gst_buffer_replace (&mix->auxilliary_out, NULL);
    GST_ELEMENT_ERROR (mix, RESOURCE, SETTINGS,
        ("Failed to generate output"), ("failed to generate output"));
    ret = GST_FLOW_ERROR;
  }

  if (mix->auxilliary_out) {
    *outbuf = mix->auxilliary_out;
    mix->auxilliary_out = NULL;
  } else {
    *outbuf = mix->primary_out;
    mix->primary_out = NULL;
  }
  return ret;
}

gboolean
gst_gl_stereo_mix_make_output (GstGLStereoMix * mix)
{
  guint i;
  GList *walk;
  gboolean res = FALSE;
  guint array_index = 0;
  GstElement *element = GST_ELEMENT (mix);
  gboolean missing_buffer = FALSE;

  GST_LOG_OBJECT (mix, "Processing buffers");

  GST_OBJECT_LOCK (mix);
  walk = element->sinkpads;

  i = mix->frames->len;
  g_ptr_array_set_size (mix->frames, element->numsinkpads);
  for (; i < element->numsinkpads; i++)
    mix->frames->pdata[i] = g_slice_new0 (GstGLStereoMixFrameData);
  while (walk) {
    GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
    GstVideoAggregatorPad *vaggpad = walk->data;
    GstGLStereoMixFrameData *frame;

    GST_LOG_OBJECT (mix, "Checking pad %" GST_PTR_FORMAT, vaggpad);

    frame = g_ptr_array_index (mix->frames, array_index);
    frame->base.pad = pad;
    frame->buf = NULL;

    walk = g_list_next (walk);

    if (vaggpad->buffer != NULL) {
      frame->buf = vaggpad->buffer;

      GST_DEBUG_OBJECT (pad, "Got buffer %" GST_PTR_FORMAT, frame->buf);
    } else {
      GST_LOG_OBJECT (mix, "No buffer on pad %" GST_PTR_FORMAT, vaggpad);
      missing_buffer = TRUE;
    }
    ++array_index;
  }
  if (missing_buffer) {
    /* We're still waiting for a buffer to turn up on at least one input */
    GST_WARNING_OBJECT (mix, "Not generating output - need more input buffers");
    res = TRUE;
    goto out;
  }

  /* Copy GL memory from each input frame to the output */
  if (!gst_gl_stereo_mix_process_frames (mix, mix->frames)) {
    GST_LOG_OBJECT (mix, "Failed to process frames to output");
    goto out;
  }

  if (mix->primary_out == NULL)
    goto out;

  res = TRUE;

out:
  GST_OBJECT_UNLOCK (mix);

  return res;
}

static GstFlowReturn
gst_gl_stereo_mix_aggregate_frames (GstVideoAggregator * vagg,
    GstBuffer * outbuf)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
  /* If we're operating in frame-by-frame mode, push
   * the primary view now, and let the parent class
   * push the remaining auxilliary view */
  if (GST_VIDEO_INFO_MULTIVIEW_MODE (&vagg->info) ==
      GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME) {
    /* Transfer the timestamps video-agg put on the aux buffer */
    gst_buffer_copy_into (mix->primary_out, outbuf,
        GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
    gst_aggregator_finish_buffer (GST_AGGREGATOR (vagg), mix->primary_out);
    mix->primary_out = NULL;

    /* And actually, we don't want timestamps on the aux buffer */
    GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
    GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
  }
  return GST_FLOW_OK;
}

static void
gst_gl_stereo_mix_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (object);

  switch (prop_id) {
    case PROP_DOWNMIX_MODE:
      g_value_set_enum (value, mix->downmix_mode);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_stereo_mix_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (object);

  switch (prop_id) {
    case PROP_DOWNMIX_MODE:
      mix->downmix_mode = g_value_get_enum (value);
      if (mix->viewconvert)
        g_object_set_property (G_OBJECT (mix->viewconvert), "downmix-mode",
            value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
_free_glmixer_frame_data (GstGLStereoMixFrameData * frame)
{
  if (frame == NULL)
    return;
  if (frame->buf)
    gst_buffer_unref (frame->buf);
  g_slice_free1 (sizeof (GstGLStereoMixFrameData), frame);
}

static gboolean
gst_gl_stereo_mix_start (GstAggregator * agg)
{
  guint i;
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg);
  GstElement *element = GST_ELEMENT (agg);

  if (!GST_AGGREGATOR_CLASS (parent_class)->start (agg))
    return FALSE;

  GST_OBJECT_LOCK (mix);
  mix->array_buffers = g_ptr_array_new_full (element->numsinkpads,
      (GDestroyNotify) _free_glmixer_frame_data);
  mix->frames = g_ptr_array_new_full (element->numsinkpads, NULL);

  g_ptr_array_set_size (mix->array_buffers, element->numsinkpads);
  g_ptr_array_set_size (mix->frames, element->numsinkpads);

  for (i = 0; i < element->numsinkpads; i++)
    mix->frames->pdata[i] = g_slice_new0 (GstGLStereoMixFrameData);

  mix->viewconvert = gst_gl_view_convert_new ();
  g_object_set (G_OBJECT (mix->viewconvert), "downmix-mode",
      mix->downmix_mode, NULL);

  GST_OBJECT_UNLOCK (mix);

  return TRUE;
}

static gboolean
gst_gl_stereo_mix_stop (GstAggregator * agg)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg);

  if (!GST_AGGREGATOR_CLASS (parent_class)->stop (agg))
    return FALSE;

  GST_OBJECT_LOCK (agg);
  g_ptr_array_free (mix->frames, TRUE);
  mix->frames = NULL;
  g_ptr_array_free (mix->array_buffers, TRUE);
  mix->array_buffers = NULL;
  GST_OBJECT_UNLOCK (agg);

  if (mix->viewconvert) {
    gst_object_unref (mix->viewconvert);
    mix->viewconvert = NULL;
  }

  return TRUE;
}

/* Convert to caps that can be accepted by this element... */
static GstCaps *
get_converted_caps (GstGLStereoMix * mix, GstCaps * caps)
{
#if 0
  GstGLContext *context = GST_GL_BASE_MIXER (mix)->context;
  GstCaps *result, *tmp;

  GST_LOG_OBJECT (mix, "Converting caps %" GST_PTR_FORMAT, caps);
  result = gst_gl_upload_transform_caps (context, GST_PAD_SINK, caps, NULL);
  tmp = result;
  GST_TRACE_OBJECT (mix, "transfer returned caps %" GST_PTR_FORMAT, tmp);

  result =
      gst_gl_color_convert_transform_caps (context, GST_PAD_SINK, tmp, NULL);
  gst_caps_unref (tmp);
  GST_TRACE_OBJECT (mix, "convert returned caps %" GST_PTR_FORMAT, tmp);

  tmp = result;
  result = gst_gl_view_convert_transform_caps (mix->viewconvert,
      GST_PAD_SINK, tmp, NULL);
  gst_caps_unref (tmp);
#else
  GstCaps *result;

  GST_LOG_OBJECT (mix, "Converting caps %" GST_PTR_FORMAT, caps);
  result = gst_gl_view_convert_transform_caps (mix->viewconvert,
      GST_PAD_SINK, caps, NULL);
#endif

  GST_LOG_OBJECT (mix, "returning caps %" GST_PTR_FORMAT, result);

  return result;
}

/* Return the possible output caps we decided in find_best_format() */
static GstCaps *
_update_caps (GstVideoAggregator * vagg, GstCaps * caps)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);

  return gst_caps_ref (mix->out_caps);
}

/* Called after videoaggregator fixates our caps */
static gboolean
_negotiated_caps (GstVideoAggregator * vagg, GstCaps * caps)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);

  GST_LOG_OBJECT (mix, "Configured output caps %" GST_PTR_FORMAT, caps);

  if (GST_VIDEO_AGGREGATOR_CLASS (parent_class)->negotiated_caps)
    if (!GST_VIDEO_AGGREGATOR_CLASS (parent_class)->negotiated_caps (vagg,
            caps))
      return FALSE;

  /* Update the glview_convert output */
  if (!gst_video_info_from_caps (&mix->out_info, caps))
    return FALSE;

  /* We can configure the view_converter now */
  gst_gl_view_convert_set_context (mix->viewconvert,
      GST_GL_BASE_MIXER (mix)->context);
  gst_gl_view_convert_set_format (mix->viewconvert, &mix->mix_info,
      &mix->out_info);

  return TRUE;

}

static gboolean
gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer, GPtrArray * frames)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mixer);
  GstBuffer *converted_buffer, *inbuf;
  GstVideoInfo *out_info = &vagg->info;
  gint count = 0;
#ifndef G_DISABLE_ASSERT
  gint n;
#endif
  gint v, views;
  gint valid_views = 0;

  inbuf = gst_buffer_new ();
  while (count < frames->len) {
    GstGLStereoMixFrameData *frame;
    GstMemory *in_mem;

    frame = g_ptr_array_index (frames, count);
    GST_LOG_OBJECT (mixer, "Handling frame %d", count);

    if (!frame) {
      GST_DEBUG ("skipping texture, null frame");
      count++;
      continue;
    }

    in_mem = gst_buffer_get_memory (frame->buf, 0);

    GST_LOG_OBJECT (mixer,
        "Appending memory %" GST_PTR_FORMAT " to intermediate buffer", in_mem);
    /* Appending the memory to a 2nd buffer locks it
     * exclusive a 2nd time, which will mark it for
     * copy-on-write. The ref will keep the memory
     * alive but we add a parent_buffer_meta to also
     * prevent the input buffer from returning to any buffer
     * pool it might belong to
     */
    gst_buffer_append_memory (inbuf, in_mem);
    /* Use parent buffer meta to keep input buffer alive */
    gst_buffer_add_parent_buffer_meta (inbuf, frame->buf);

    count++;
    valid_views++;
  }

  if (mixer->mix_info.views != valid_views) {
    GST_WARNING_OBJECT (mixer, "Not enough input views to process");
    return FALSE;
  }

  if (GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) ==
      GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
    views = out_info->views;
  else
    views = 1;

  if (gst_gl_view_convert_submit_input_buffer (mixer->viewconvert,
          FALSE, inbuf) != GST_FLOW_OK)
    return FALSE;

  /* Clear any existing buffers, just in case */
  gst_buffer_replace (&mixer->primary_out, NULL);
  gst_buffer_replace (&mixer->auxilliary_out, NULL);

  if (gst_gl_view_convert_get_output (mixer->viewconvert,
          &mixer->primary_out) != GST_FLOW_OK)
    return FALSE;

  if (GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) ==
      GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME) {
    if (gst_gl_view_convert_get_output (mixer->viewconvert,
            &mixer->auxilliary_out) != GST_FLOW_OK)
      return FALSE;
  }

  if (mixer->primary_out == NULL)
    return FALSE;

  converted_buffer = mixer->primary_out;

#ifndef G_DISABLE_ASSERT
  n = gst_buffer_n_memory (converted_buffer);
  g_assert (n == GST_VIDEO_INFO_N_PLANES (out_info) * views);
#endif

  for (v = 0; v < views; v++) {
    gst_buffer_add_video_meta_full (converted_buffer, v,
        GST_VIDEO_INFO_FORMAT (out_info),
        GST_VIDEO_INFO_WIDTH (out_info),
        GST_VIDEO_INFO_HEIGHT (out_info),
        GST_VIDEO_INFO_N_PLANES (out_info), out_info->offset, out_info->stride);
    if (mixer->auxilliary_out) {
      gst_buffer_add_video_meta_full (mixer->auxilliary_out, v,
          GST_VIDEO_INFO_FORMAT (out_info),
          GST_VIDEO_INFO_WIDTH (out_info),
          GST_VIDEO_INFO_HEIGHT (out_info),
          GST_VIDEO_INFO_N_PLANES (out_info), out_info->offset,
          out_info->stride);
    }
  }

  return TRUE;
}

/* Iterate the input sink pads, and choose the blend format
 * we will generate before output conversion, which is RGBA
 * at some suitable size */
static void
gst_gl_stereo_mix_find_best_format (GstVideoAggregator * vagg,
    GstCaps * downstream_caps, GstVideoInfo * best_info,
    gboolean * at_least_one_alpha)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
  GList *l;
  gint best_width = -1, best_height = -1;
  gdouble best_fps = -1, cur_fps;
  gint best_fps_n = 0, best_fps_d = 1;
  GstVideoInfo *mix_info;
  GstCaps *blend_caps, *tmp_caps;

  /* We'll deal with alpha internally, so just tell aggregator to
   * be quiet */
  *at_least_one_alpha = FALSE;

  GST_OBJECT_LOCK (vagg);

  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoAggregatorPad *pad = l->data;
    GstVideoInfo tmp = pad->info;
    gint this_width, this_height;
    gint fps_n, fps_d;

    if (!pad->info.finfo)
      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;

    /* Convert to per-view width/height for unpacked forms */
    gst_video_multiview_video_info_change_mode (&tmp,
        GST_VIDEO_MULTIVIEW_MODE_SEPARATED, GST_VIDEO_MULTIVIEW_FLAGS_NONE);

    this_width = GST_VIDEO_INFO_WIDTH (&tmp);
    this_height = GST_VIDEO_INFO_HEIGHT (&tmp);
    fps_n = GST_VIDEO_INFO_FPS_N (&tmp);
    fps_d = GST_VIDEO_INFO_FPS_D (&tmp);

    GST_INFO_OBJECT (vagg, "Input pad %" GST_PTR_FORMAT
        " w %u h %u", pad, this_width, this_height);

    if (this_width == 0 || this_height == 0)
      continue;

    if (best_width < this_width)
      best_width = this_width;
    if (best_height < this_height)
      best_height = this_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;
    }

    /* FIXME: Preserve PAR for at least one input when different sized inputs */
  }
  GST_OBJECT_UNLOCK (vagg);

  mix_info = &mix->mix_info;
  gst_video_info_set_format (mix_info, GST_VIDEO_FORMAT_RGBA, best_width,
      best_height);

  GST_VIDEO_INFO_FPS_N (mix_info) = best_fps_n;
  GST_VIDEO_INFO_FPS_D (mix_info) = best_fps_d;

  GST_VIDEO_INFO_MULTIVIEW_MODE (mix_info) = GST_VIDEO_MULTIVIEW_MODE_SEPARATED;
  GST_VIDEO_INFO_VIEWS (mix_info) = 2;

  /* FIXME: If input is marked as flipped or flopped, preserve those flags */
  GST_VIDEO_INFO_MULTIVIEW_FLAGS (mix_info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;

  /* Choose our output format based on downstream preferences */
  blend_caps = gst_video_info_to_caps (mix_info);

  gst_caps_set_features (blend_caps, 0,
      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));

  tmp_caps = get_converted_caps (GST_GL_STEREO_MIX (vagg), blend_caps);
  gst_caps_unref (blend_caps);

  if (mix->out_caps)
    gst_caps_unref (mix->out_caps);

  mix->out_caps = gst_caps_intersect (downstream_caps, tmp_caps);
  gst_caps_unref (tmp_caps);

  GST_DEBUG_OBJECT (vagg, "Possible output caps %" GST_PTR_FORMAT,
      mix->out_caps);
  /* Tell videoaggregator our preferred size. Actual info gets
   * overridden during caps nego */
  *best_info = *mix_info;
}
