/*
 * 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);

G_DEFINE_TYPE (GstGLStereoMixPad, gst_gl_stereo_mix_pad, GST_TYPE_GL_MIXER_PAD);

static void
gst_gl_stereo_mix_pad_class_init (GstGLStereoMixPadClass * klass)
{
}

static void
gst_gl_stereo_mix_pad_init (GstGLStereoMixPad * pad)
{
}

#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,
    GstCaps * filter);
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);

#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 ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
        "format = (string) RGBA, "
        "width = " GST_VIDEO_SIZE_RANGE ", "
        "height = " GST_VIDEO_SIZE_RANGE ", "
        "framerate = " GST_VIDEO_FPS_RANGE ","
        "texture-target = (string) 2D"
        "; "
        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 ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
        "format = (string) RGBA, "
        "width = " GST_VIDEO_SIZE_RANGE ", "
        "height = " GST_VIDEO_SIZE_RANGE ", "
        "framerate = " GST_VIDEO_FPS_RANGE ","
        "texture-target = (string) 2D"
        "; "
        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_static_pad_template (element_class, &src_factory);
  gst_element_class_add_static_pad_template (element_class, &sink_factory);

  agg_class->sinkpads_type = GST_TYPE_GL_STEREO_MIX_PAD;
  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;

  base_mix_class->supported_gl_api =
      GST_GL_API_GLES2 | 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)
{
  GList *walk;
  gboolean res = FALSE;
  GstElement *element = GST_ELEMENT (mix);
  gboolean missing_buffer = FALSE;

  GST_LOG_OBJECT (mix, "Processing buffers");

  GST_OBJECT_LOCK (mix);
  walk = element->sinkpads;
  while (walk) {
    GstVideoAggregatorPad *vaggpad = walk->data;
    GstGLStereoMixPad *pad = walk->data;

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

    if (vaggpad->buffer != NULL) {
      pad->current_buffer = vaggpad->buffer;

      GST_DEBUG_OBJECT (pad, "Got buffer %" GST_PTR_FORMAT,
          pad->current_buffer);
    } else {
      GST_LOG_OBJECT (mix, "No buffer on pad %" GST_PTR_FORMAT, vaggpad);
      pad->current_buffer = NULL;
      missing_buffer = TRUE;
    }
    walk = g_list_next (walk);
  }
  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)) {
    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 gboolean
gst_gl_stereo_mix_start (GstAggregator * agg)
{
  GstGLStereoMix *mix = GST_GL_STEREO_MIX (agg);

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

  GST_OBJECT_LOCK (mix);
  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;

  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, GstCaps * filter)
{
  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);
  GstCaps *in_caps;

  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);

  in_caps = gst_video_info_to_caps (&mix->mix_info);
  gst_caps_set_features (in_caps, 0,
      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
  gst_caps_set_simple (in_caps, "texture-target", G_TYPE_STRING,
      GST_GL_TEXTURE_TARGET_2D_STR, NULL);

  gst_gl_view_convert_set_caps (mix->viewconvert, in_caps, caps);

  return TRUE;
}

/* called with the object lock held */
static gboolean
gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer)
{
  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mixer);
  GstBuffer *converted_buffer, *inbuf;
  GstVideoInfo *out_info = &vagg->info;
#ifndef G_DISABLE_ASSERT
  gint n;
#endif
  gint v, views;
  gint valid_views = 0;
  GList *walk;

  inbuf = gst_buffer_new ();
  walk = GST_ELEMENT (mixer)->sinkpads;
  while (walk) {
    GstGLStereoMixPad *pad = walk->data;
    GstMemory *in_mem;

    GST_LOG_OBJECT (mixer, "Handling frame %d", valid_views);

    if (!pad || !pad->current_buffer) {
      GST_DEBUG ("skipping texture, null frame");
      walk = g_list_next (walk);
      continue;
    }

    in_mem = gst_buffer_get_memory (pad->current_buffer, 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, pad->current_buffer);

    valid_views++;
    walk = g_list_next (walk);
  }

  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;
}
