/* 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_clear_error (&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_clear_error (&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));
    g_clear_error (&err);
    g_option_context_free (ctx);
    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;
}
