/* GStreamer
 * Copyright (C) 2010 Stefan Kost <ensonic@users.sf.net>
 *
 * capsnego.c: benchmark for caps negotiation
 *
 * 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.
 */

/* This benchmark recursively builds a pipeline and measures the time to go
 * from READY to PAUSED state.
 *
 * The graph size and type can be controlled with a few command line options:
 *
 *  -d depth: is the depth of the tree
 *  -c children: is the number of branches on each level
 *  -f <flavour>: can be "audio" or "video" and is controlling the kind of
 *                elements that are used.
 */

#include <gst/gst.h>
#include <stdlib.h>
#include <string.h>

enum
{
  FLAVOUR_AUDIO = 0,
  FLAVOUR_VIDEO,
  NUM_FLAVOURS
};

enum
{
  ELEM_SRC = 0,
  ELEM_MIX,
  ELEM_PROC,
  ELEM_CONV,
  NUM_ELEM
};

static const gchar *factories[NUM_FLAVOURS][NUM_ELEM] = {
  {"audiotestsrc", "adder", "volume", "audioconvert"},
  {"videotestsrc", "videomixer", "videoscale", "videoconvert"}
};

static const gchar *sink_pads[NUM_FLAVOURS][NUM_ELEM] = {
  {NULL, "sink_%u", NULL, NULL},
  {NULL, "sink_%u", NULL, NULL}
};


static gboolean
create_node (GstBin * bin, GstElement * sink, const gchar * sinkpadname,
    GstElement ** new_sink, gint children, gint flavour)
{
  GstElement *mix, *proc, *conv;

  if (children >= 1) {
    mix = gst_element_factory_make (factories[flavour][ELEM_MIX], NULL);
    if (!mix) {
      GST_WARNING ("need element '%s'", factories[flavour][ELEM_MIX]);
      return FALSE;
    }
  } else {
    mix = gst_element_factory_make ("identity", NULL);
  }
  proc = gst_element_factory_make (factories[flavour][ELEM_PROC], NULL);
  if (!proc) {
    GST_WARNING ("need element '%s'", factories[flavour][ELEM_PROC]);
    return FALSE;
  }
  conv = gst_element_factory_make (factories[flavour][ELEM_CONV], NULL);
  if (!conv) {
    GST_WARNING ("need element '%s'", factories[flavour][ELEM_CONV]);
    return FALSE;
  }
  gst_bin_add_many (bin, mix, proc, conv, NULL);
  if (!gst_element_link_pads_full (mix, "src", proc, "sink",
          GST_PAD_LINK_CHECK_NOTHING)
      || !gst_element_link_pads_full (proc, "src", conv, "sink",
          GST_PAD_LINK_CHECK_NOTHING)
      || !gst_element_link_pads_full (conv, "src", sink, sinkpadname,
          GST_PAD_LINK_CHECK_NOTHING)) {
    GST_WARNING ("can't link elements");
    return FALSE;
  }
  *new_sink = mix;
  return TRUE;
}

static gboolean
create_nodes (GstBin * bin, GstElement * sink, gint depth, gint children,
    gint flavour)
{
  GstElement *new_sink, *src;
  gint i;

  for (i = 0; i < children; i++) {
    if (depth > 0) {
      if (!create_node (bin, sink, sink_pads[flavour][ELEM_MIX], &new_sink,
              children, flavour)) {
        return FALSE;
      }
      if (!create_nodes (bin, new_sink, depth - 1, children, flavour)) {
        return FALSE;
      }
    } else {
      src = gst_element_factory_make (factories[flavour][ELEM_SRC], NULL);
      if (!src) {
        GST_WARNING ("need element '%s'", factories[flavour][ELEM_SRC]);
        return FALSE;
      }
      gst_bin_add (bin, src);
      if (!gst_element_link_pads_full (src, "src", sink,
              sink_pads[flavour][ELEM_MIX], GST_PAD_LINK_CHECK_NOTHING)) {
        GST_WARNING ("can't link elements");
        return FALSE;
      }
    }
  }
  return TRUE;
}

static void
event_loop (GstElement * bin)
{
  GstBus *bus;
  GstMessage *msg = NULL;
  gboolean running = TRUE;

  bus = gst_element_get_bus (bin);

  while (running) {
    msg = gst_bus_poll (bus,
        GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR | GST_MESSAGE_WARNING, -1);

    switch (GST_MESSAGE_TYPE (msg)) {
      case GST_MESSAGE_ASYNC_DONE:
        running = FALSE;
        break;
      case GST_MESSAGE_WARNING:{
        GError *err = NULL;
        gchar *dbg = NULL;

        gst_message_parse_warning (msg, &err, &dbg);
        GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message,
            (dbg ? dbg : "no details"));
        g_error_free (err);
        g_free (dbg);
        break;
      }
      case GST_MESSAGE_ERROR:{
        GError *err = NULL;
        gchar *dbg = NULL;

        gst_message_parse_error (msg, &err, &dbg);
        GST_ERROR_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message,
            (dbg ? dbg : "no details"));
        g_error_free (err);
        g_free (dbg);
        running = FALSE;
        break;
      }
      default:
        break;
    }
    gst_message_unref (msg);
  }
  gst_object_unref (bus);
}

gint
main (gint argc, gchar * argv[])
{
  /* default parameters */
  const gchar *flavour_str = "audio";
  gint flavour = FLAVOUR_AUDIO;
  gint children = 3;
  gint depth = 4;
  gint loops = 50;

  GOptionContext *ctx;
  GOptionEntry options[] = {
    {"children", 'c', 0, G_OPTION_ARG_INT, &children,
        "Number of children (branches on each level) (default: 3)", NULL},
    {"depth", 'd', 0, G_OPTION_ARG_INT, &depth,
        "Depth of pipeline hierarchy tree (default: 4)", NULL},
    {"flavour", 'f', 0, G_OPTION_ARG_STRING, &flavour_str,
        "Flavour (video|audio) controlling the kind of elements used "
          "(default: audio)", NULL},
    {"loops", 'l', 0, G_OPTION_ARG_INT, &loops,
        "How many loops to run (default: 50)", NULL},
    {NULL}
  };
  GError *err = NULL;
  GstBin *bin;
  GstClockTime start, end;
  GstElement *sink, *new_sink;
  gint i;

  g_set_prgname ("capsnego");

  /* check command line options */
  ctx = g_option_context_new ("");
  g_option_context_add_main_entries (ctx, options, NULL);
  g_option_context_add_group (ctx, gst_init_get_option_group ());
  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_print ("Error initializing: %s\n", GST_STR_NULL (err->message));
    return 1;
  }
  g_option_context_free (ctx);

  if (strcmp (flavour_str, "video") == 0)
    flavour = FLAVOUR_VIDEO;

  /* build pipeline */
  g_print ("building %s pipeline with depth = %d and children = %d\n",
      flavour_str, depth, children);
  start = gst_util_get_timestamp ();
  bin = GST_BIN (gst_pipeline_new ("pipeline"));
  sink = gst_element_factory_make ("fakesink", NULL);
  gst_bin_add (bin, sink);
  if (!create_node (bin, sink, "sink", &new_sink, children, flavour)) {
    goto Error;
  }
  if (!create_nodes (bin, new_sink, depth, children, flavour)) {
    goto Error;
  }
  end = gst_util_get_timestamp ();
  /* num-threads = num-sources = pow (children, depth) */
  g_print ("%" GST_TIME_FORMAT " built pipeline with %d elements\n",
      GST_TIME_ARGS (end - start), GST_BIN_NUMCHILDREN (bin));

  /* measure */
  g_print ("starting pipeline\n");
  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
  GST_DEBUG_BIN_TO_DOT_FILE (bin, GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE, "capsnego");

  start = gst_util_get_timestamp ();
  for (i = 0; i < loops; ++i) {
    gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
    event_loop (GST_ELEMENT (bin));
    gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
  }
  end = gst_util_get_timestamp ();
  g_print ("%" GST_TIME_FORMAT " reached PAUSED state (%d loop iterations)\n",
      GST_TIME_ARGS (end - start), loops);
  /* clean up */
Error:
  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
  gst_object_unref (bin);
  return 0;
}
