/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net>
 * Copyright (C) <2012> Ralph Giles <giles@mozilla.com>
 *
 * 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:element-shout2send
 *
 * shout2send pushes a media stream to an Icecast server
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 uridecodebin uri=file:///path/to/audiofile ! audioconvert ! vorbisenc ! oggmux ! shout2send mount=/stream.ogg port=8000 username=source password=somepassword ip=server_IP_address_or_hostname
 * ]| This pipeline demuxes, decodes, re-encodes and re-muxes an audio
 * media file into oggvorbis and sends the resulting stream to an Icecast
 * server. Properties mount, port, username and password are all server-config
 * dependent.
 * </refsect2>
 */

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

#include "gstshout2.h"
#include <stdlib.h>
#include <string.h>

#include "gst/gst-i18n-plugin.h"

GST_DEBUG_CATEGORY_STATIC (shout2_debug);
#define GST_CAT_DEFAULT shout2_debug


enum
{
  SIGNAL_CONNECTION_PROBLEM,    /* FIXME 2.0: remove this */
  LAST_SIGNAL
};

enum
{
  ARG_0,
  ARG_IP,                       /* the IP address or hostname of the server */
  ARG_PORT,                     /* the encoder port number on the server */
  ARG_PASSWORD,                 /* the encoder password on the server */
  ARG_USERNAME,                 /* the encoder username on the server */
  ARG_PUBLIC,                   /* is this stream public? */
  ARG_STREAMNAME,               /* Name of the stream */
  ARG_DESCRIPTION,              /* Description of the stream */
  ARG_GENRE,                    /* Genre of the stream */

  ARG_PROTOCOL,                 /* Protocol to connect with */

  ARG_MOUNT,                    /* mountpoint of stream (icecast only) */
  ARG_URL,                      /* the stream's homepage URL */

  ARG_TIMEOUT                   /* The max amount of time to wait for
                                   network activity */
};

#define DEFAULT_IP           "127.0.0.1"
#define DEFAULT_PORT         8000
#define DEFAULT_PASSWORD     "hackme"
#define DEFAULT_USERNAME     "source"
#define DEFAULT_PUBLIC     FALSE
#define DEFAULT_STREAMNAME   ""
#define DEFAULT_DESCRIPTION  ""
#define DEFAULT_GENRE        ""
#define DEFAULT_MOUNT        ""
#define DEFAULT_URL          ""
#define DEFAULT_PROTOCOL     SHOUT2SEND_PROTOCOL_HTTP
#define DEFAULT_TIMEOUT      10000

#ifdef SHOUT_FORMAT_WEBM
#define WEBM_CAPS "; video/webm; audio/webm"
#else
#define WEBM_CAPS ""
#endif
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/ogg; audio/ogg; video/ogg; "
        "audio/mpeg, mpegversion = (int) 1, layer = (int) [ 1, 3 ]" WEBM_CAPS));

static void gst_shout2send_finalize (GstShout2send * shout2send);

static gboolean gst_shout2send_event (GstBaseSink * sink, GstEvent * event);
static gboolean gst_shout2send_unlock (GstBaseSink * basesink);
static gboolean gst_shout2send_unlock_stop (GstBaseSink * basesink);
static GstFlowReturn gst_shout2send_render (GstBaseSink * sink,
    GstBuffer * buffer);
static gboolean gst_shout2send_start (GstBaseSink * basesink);
static gboolean gst_shout2send_stop (GstBaseSink * basesink);

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

static gboolean gst_shout2send_setcaps (GstBaseSink * basesink, GstCaps * caps);

static guint gst_shout2send_signals[LAST_SIGNAL] = { 0 };

#define GST_TYPE_SHOUT_PROTOCOL (gst_shout2send_protocol_get_type())
static GType
gst_shout2send_protocol_get_type (void)
{
  static GType shout2send_protocol_type = 0;
  static const GEnumValue shout2send_protocol[] = {
    {SHOUT2SEND_PROTOCOL_XAUDIOCAST,
        "Xaudiocast Protocol (icecast 1.3.x)", "xaudiocast"},
    {SHOUT2SEND_PROTOCOL_ICY, "Icy Protocol (ShoutCast)", "icy"},
    {SHOUT2SEND_PROTOCOL_HTTP, "Http Protocol (icecast 2.x)", "http"},
    {0, NULL, NULL},
  };

  if (!shout2send_protocol_type) {
    shout2send_protocol_type =
        g_enum_register_static ("GstShout2SendProtocol", shout2send_protocol);
  }


  return shout2send_protocol_type;
}

#define gst_shout2send_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstShout2send, gst_shout2send, GST_TYPE_BASE_SINK,
    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));

static void
gst_shout2send_class_init (GstShout2sendClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_shout2send_set_property;
  gobject_class->get_property = gst_shout2send_get_property;
  gobject_class->finalize = (GObjectFinalizeFunc) gst_shout2send_finalize;

  /* FIXME: 2.0 Should probably change this prop name to "server" */
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_IP,
      g_param_spec_string ("ip", "ip", "IP address or hostname", DEFAULT_IP,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
      g_param_spec_int ("port", "port", "port", 1, G_MAXUSHORT, DEFAULT_PORT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PASSWORD,
      g_param_spec_string ("password", "password", "password", DEFAULT_PASSWORD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_USERNAME,
      g_param_spec_string ("username", "username", "username", DEFAULT_USERNAME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* metadata */
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PUBLIC,
      g_param_spec_boolean ("public", "public",
          "If the stream should be listed on the server's stream directory",
          DEFAULT_PUBLIC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STREAMNAME,
      g_param_spec_string ("streamname", "streamname", "name of the stream",
          DEFAULT_STREAMNAME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DESCRIPTION,
      g_param_spec_string ("description", "description", "description",
          DEFAULT_DESCRIPTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GENRE,
      g_param_spec_string ("genre", "genre", "genre", DEFAULT_GENRE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PROTOCOL,
      g_param_spec_enum ("protocol", "protocol", "Connection Protocol to use",
          GST_TYPE_SHOUT_PROTOCOL, DEFAULT_PROTOCOL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));


  /* icecast only */
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MOUNT,
      g_param_spec_string ("mount", "mount", "mount", DEFAULT_MOUNT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_URL,
      g_param_spec_string ("url", "url", "the stream's homepage URL",
          DEFAULT_URL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TIMEOUT,
      g_param_spec_uint ("timeout", "timeout",
          "Max amount of time to wait for network activity, in milliseconds",
          1, G_MAXUINT, DEFAULT_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* signals */
  gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM] =
      g_signal_new ("connection-problem", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_CLEANUP, G_STRUCT_OFFSET (GstShout2sendClass,
          connection_problem), NULL, NULL, g_cclosure_marshal_VOID__INT,
      G_TYPE_NONE, 1, G_TYPE_INT);

  gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_shout2send_start);
  gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_shout2send_stop);
  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_shout2send_unlock);
  gstbasesink_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_shout2send_unlock_stop);
  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_shout2send_render);
  gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_shout2send_event);
  gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_shout2send_setcaps);

  gst_element_class_add_static_pad_template (gstelement_class, &sink_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "Icecast network sink",
      "Sink/Network", "Sends data to an icecast server",
      "Wim Taymans <wim.taymans@chello.be>, "
      "Pedro Corte-Real <typo@netcabo.pt>, "
      "Zaheer Abbas Merali <zaheerabbas at merali dot org>");

  GST_DEBUG_CATEGORY_INIT (shout2_debug, "shout2", 0, "shout2send element");
}

static void
gst_shout2send_init (GstShout2send * shout2send)
{
  gst_base_sink_set_sync (GST_BASE_SINK (shout2send), FALSE);

  shout2send->timer = gst_poll_new (TRUE);

  shout2send->ip = g_strdup (DEFAULT_IP);
  shout2send->port = DEFAULT_PORT;
  shout2send->password = g_strdup (DEFAULT_PASSWORD);
  shout2send->username = g_strdup (DEFAULT_USERNAME);
  shout2send->streamname = g_strdup (DEFAULT_STREAMNAME);
  shout2send->description = g_strdup (DEFAULT_DESCRIPTION);
  shout2send->genre = g_strdup (DEFAULT_GENRE);
  shout2send->mount = g_strdup (DEFAULT_MOUNT);
  shout2send->url = g_strdup (DEFAULT_URL);
  shout2send->protocol = DEFAULT_PROTOCOL;
  shout2send->ispublic = DEFAULT_PUBLIC;
  shout2send->timeout = DEFAULT_TIMEOUT;

  shout2send->format = -1;
  shout2send->tags = gst_tag_list_new_empty ();
  shout2send->conn = NULL;
  shout2send->connected = FALSE;
  shout2send->songmetadata = NULL;
  shout2send->songartist = NULL;
  shout2send->songtitle = NULL;
}

static void
gst_shout2send_finalize (GstShout2send * shout2send)
{
  g_free (shout2send->ip);
  g_free (shout2send->password);
  g_free (shout2send->username);
  g_free (shout2send->streamname);
  g_free (shout2send->description);
  g_free (shout2send->genre);
  g_free (shout2send->mount);
  g_free (shout2send->url);

  gst_tag_list_unref (shout2send->tags);

  gst_poll_free (shout2send->timer);

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (shout2send));
}

static void
set_shout_metadata (const GstTagList * list, const gchar * tag,
    gpointer user_data)
{
  GstShout2send *shout2send = (GstShout2send *) user_data;
  char **shout_metadata = &(shout2send->songmetadata);
  char **song_artist = &(shout2send->songartist);
  char **song_title = &(shout2send->songtitle);

  gchar *value;

  GST_DEBUG ("tag: %s being added", tag);
  if (strcmp (tag, GST_TAG_ARTIST) == 0) {
    if (gst_tag_get_type (tag) == G_TYPE_STRING) {
      if (!gst_tag_list_get_string (list, tag, &value)) {
        GST_DEBUG ("Error reading \"%s\" tag value", tag);
        return;
      }

      if (*song_artist != NULL)
        g_free (*song_artist);

      *song_artist = g_strdup (value);
    }
  } else if (strcmp (tag, GST_TAG_TITLE) == 0) {
    if (gst_tag_get_type (tag) == G_TYPE_STRING) {
      if (!gst_tag_list_get_string (list, tag, &value)) {
        GST_DEBUG ("Error reading \"%s\" tag value", tag);
        return;
      }

      if (*song_title != NULL)
        g_free (*song_title);

      *song_title = g_strdup (value);
    }
  }

  if (*shout_metadata != NULL)
    g_free (*shout_metadata);


  if (*song_title && *song_artist) {
    *shout_metadata = g_strdup_printf ("%s - %s", *song_artist, *song_title);
  } else if (*song_title && *song_artist == NULL) {
    *shout_metadata = g_strdup_printf ("Unknown - %s", *song_title);
  } else if (*song_title == NULL && *song_artist) {
    *shout_metadata = g_strdup_printf ("%s - Unknown", *song_artist);
  } else {
    *shout_metadata = g_strdup_printf ("Unknown - Unknown");
  }

  GST_LOG ("shout metadata is now: %s", *shout_metadata);
}

#if 0
static void
gst_shout2send_set_metadata (GstShout2send * shout2send)
{
  const GstTagList *user_tags;
  GstTagList *copy;
  char *tempmetadata;
  shout_metadata_t *pmetadata;

  g_return_if_fail (shout2send != NULL);
  user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (shout2send));
  if ((shout2send->tags == NULL) && (user_tags == NULL)) {
    return;
  }
  copy = gst_tag_list_merge (user_tags, shout2send->tags,
      gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (shout2send)));
  /* lets get the artist and song tags */
  tempmetadata = NULL;
  gst_tag_list_foreach ((GstTagList *) copy, set_shout_metadata,
      (gpointer) & tempmetadata);
  if (tempmetadata) {
    pmetadata = shout_metadata_new ();
    shout_metadata_add (pmetadata, "song", tempmetadata);
    shout_set_metadata (shout2send->conn, pmetadata);
    shout_metadata_free (pmetadata);
  }

  gst_tag_list_unref (copy);
}
#endif


static gboolean
gst_shout2send_event (GstBaseSink * sink, GstEvent * event)
{
  GstShout2send *shout2send;
  gboolean ret = TRUE;

  shout2send = GST_SHOUT2SEND (sink);

  GST_LOG_OBJECT (shout2send, "got %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:{
      /* vorbis audio doesn't need metadata setting on the icecast level, only mp3 */
      if (shout2send->tags && shout2send->format == SHOUT_FORMAT_MP3) {
        GstTagList *list;

        gst_event_parse_tag (event, &list);
        GST_DEBUG_OBJECT (shout2send, "tags=%" GST_PTR_FORMAT, list);
        gst_tag_list_insert (shout2send->tags,
            list,
            gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (shout2send)));
        /* lets get the artist and song tags */
        gst_tag_list_foreach ((GstTagList *) list,
            set_shout_metadata, shout2send);
        if (shout2send->songmetadata && shout2send->connected) {
          shout_metadata_t *pmetadata;

          GST_DEBUG_OBJECT (shout2send, "metadata now: %s",
              shout2send->songmetadata);

          pmetadata = shout_metadata_new ();
          shout_metadata_add (pmetadata, "song", shout2send->songmetadata);
          shout_set_metadata (shout2send->conn, pmetadata);
          shout_metadata_free (pmetadata);
        }
      }
      break;
    }
    default:{
      GST_LOG_OBJECT (shout2send, "let base class handle event");
      if (GST_BASE_SINK_CLASS (parent_class)->event) {
        event = gst_event_ref (event);
        ret = GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
      }
      break;
    }
  }

  return ret;
}

static gboolean
gst_shout2send_start (GstBaseSink * basesink)
{
  GstShout2send *sink = GST_SHOUT2SEND (basesink);
  const gchar *cur_prop;
  gshort proto = 3;
  gchar *version_string;

  GST_DEBUG_OBJECT (sink, "starting");

  sink->conn = shout_new ();

  switch (sink->protocol) {
    case SHOUT2SEND_PROTOCOL_XAUDIOCAST:
      proto = SHOUT_PROTOCOL_XAUDIOCAST;
      break;
    case SHOUT2SEND_PROTOCOL_ICY:
      proto = SHOUT_PROTOCOL_ICY;
      break;
    case SHOUT2SEND_PROTOCOL_HTTP:
      proto = SHOUT_PROTOCOL_HTTP;
      break;
  }

  cur_prop = "protocol";
  GST_DEBUG_OBJECT (sink, "setting protocol: %d", sink->protocol);
  if (shout_set_protocol (sink->conn, proto) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "ip";
  GST_DEBUG_OBJECT (sink, "setting IP/hostname: %s", sink->ip);
  if (shout_set_host (sink->conn, sink->ip) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "port";
  GST_DEBUG_OBJECT (sink, "setting port: %u", sink->port);
  if (shout_set_port (sink->conn, sink->port) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "password";
  GST_DEBUG_OBJECT (sink, "setting password: %s", sink->password);
  if (shout_set_password (sink->conn, sink->password) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "public";
  GST_DEBUG_OBJECT (sink, "setting %s: %u", cur_prop, sink->ispublic);
  if (shout_set_public (sink->conn,
          (sink->ispublic ? 1 : 0)) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "streamname";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, sink->streamname);
  if (shout_set_name (sink->conn, sink->streamname) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "description";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, sink->description);
  if (shout_set_description (sink->conn, sink->description) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "genre";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, sink->genre);
  if (shout_set_genre (sink->conn, sink->genre) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "mount";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, sink->mount);
  if (shout_set_mount (sink->conn, sink->mount) != SHOUTERR_SUCCESS)
    goto set_failed;

  cur_prop = "username";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, sink->username);
  if (shout_set_user (sink->conn, sink->username) != SHOUTERR_SUCCESS)
    goto set_failed;

  version_string = gst_version_string ();
  cur_prop = "agent";
  GST_DEBUG_OBJECT (sink, "setting %s: %s", cur_prop, version_string);
  if (shout_set_agent (sink->conn, version_string) != SHOUTERR_SUCCESS) {
    g_free (version_string);
    goto set_failed;
  }

  g_free (version_string);
  return TRUE;

/* ERROR */
set_failed:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL),
        ("Error setting %s: %s", cur_prop, shout_get_error (sink->conn)));
    return FALSE;
  }
}

static GstFlowReturn
gst_shout2send_connect (GstShout2send * sink)
{
  GstFlowReturn fret = GST_FLOW_OK;
  gint ret;
  GstClockTime start_ts;

  GST_DEBUG_OBJECT (sink, "Connection format is: %d", sink->format);

  if (sink->format == -1)
    goto no_caps;

  if (shout_set_nonblocking (sink->conn, 1) != SHOUTERR_SUCCESS)
    goto could_not_set_nonblocking;

  if (shout_set_format (sink->conn, sink->format) != SHOUTERR_SUCCESS)
    goto could_not_set_format;

  GST_DEBUG_OBJECT (sink, "connecting");

  start_ts = gst_util_get_timestamp ();
  ret = shout_open (sink->conn);

  /* wait for connection or timeout */
  while (ret == SHOUTERR_BUSY) {
    if (gst_util_get_timestamp () - start_ts > sink->timeout * GST_MSECOND) {
      goto connection_timeout;
    }
    if (gst_poll_wait (sink->timer, 10 * GST_MSECOND) == -1) {
      GST_LOG_OBJECT (sink, "unlocked");

      fret = gst_base_sink_wait_preroll (GST_BASE_SINK (sink));
      if (fret != GST_FLOW_OK)
        goto done;
    }
    ret = shout_get_connected (sink->conn);
  }

  if (ret != SHOUTERR_CONNECTED && ret != SHOUTERR_SUCCESS)
    goto could_not_connect;

  GST_DEBUG_OBJECT (sink, "connected to server");
  sink->connected = TRUE;

  /* initialize sending rate monitoring */
  sink->prev_queuelen = 0;
  sink->data_sent = 0;
  sink->stalled = TRUE;
  sink->datasent_reset_ts = sink->stalled_ts = gst_util_get_timestamp ();

  /* let's set metadata */
  if (sink->songmetadata) {
    shout_metadata_t *pmetadata;

    GST_DEBUG_OBJECT (sink, "shout metadata now: %s", sink->songmetadata);
    pmetadata = shout_metadata_new ();
    shout_metadata_add (pmetadata, "song", sink->songmetadata);
    shout_set_metadata (sink->conn, pmetadata);
    shout_metadata_free (pmetadata);
  }

done:
  return fret;

/* ERRORS */
no_caps:
  {
    GST_ELEMENT_ERROR (sink, CORE, NEGOTIATION, (NULL),
        ("No input caps received."));
    return GST_FLOW_NOT_NEGOTIATED;
  }

could_not_set_nonblocking:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL),
        ("Error configuring libshout to use non-blocking i/o: %s",
            shout_get_error (sink->conn)));
    return GST_FLOW_ERROR;
  }

could_not_set_format:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL),
        ("Error setting connection format: %s", shout_get_error (sink->conn)));
    return GST_FLOW_ERROR;
  }

could_not_connect:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        (_("Could not connect to server")),
        ("shout_open() failed: err=%s", shout_get_error (sink->conn)));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return GST_FLOW_ERROR;
  }

connection_timeout:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        (_("Could not connect to server")), ("connection timed out"));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return GST_FLOW_ERROR;
  }
}

static gboolean
gst_shout2send_stop (GstBaseSink * basesink)
{
  GstShout2send *sink = GST_SHOUT2SEND (basesink);

  if (sink->conn) {
    if (sink->connected)
      shout_close (sink->conn);
    shout_free (sink->conn);
    sink->conn = NULL;
  }

  if (sink->songmetadata) {
    g_free (sink->songmetadata);
    sink->songmetadata = NULL;
  }

  sink->connected = FALSE;
  sink->format = -1;

  return TRUE;
}

static gboolean
gst_shout2send_unlock (GstBaseSink * basesink)
{
  GstShout2send *sink;

  sink = GST_SHOUT2SEND (basesink);

  GST_DEBUG_OBJECT (basesink, "unlock");
  gst_poll_set_flushing (sink->timer, TRUE);

  return TRUE;
}

static gboolean
gst_shout2send_unlock_stop (GstBaseSink * basesink)
{
  GstShout2send *sink;

  sink = GST_SHOUT2SEND (basesink);

  GST_DEBUG_OBJECT (basesink, "unlock_stop");
  gst_poll_set_flushing (sink->timer, FALSE);

  return TRUE;
}

static GstFlowReturn
gst_shout2send_render (GstBaseSink * basesink, GstBuffer * buf)
{
  GstShout2send *sink;
  glong ret;
  gint delay;
  GstFlowReturn fret = GST_FLOW_OK;
  GstMapInfo map;
  GstClockTime now;
  ssize_t queuelen;

  sink = GST_SHOUT2SEND (basesink);

  /* we connect here because we need to know the format before we can set up
   * the connection, which we don't know yet in _start(), and also because we
   * don't want to block the application thread */
  if (!sink->connected) {
    fret = gst_shout2send_connect (sink);
    if (fret != GST_FLOW_OK)
      goto done;
  }

  delay = shout_delay (sink->conn);

  if (delay > 0) {
    GST_LOG_OBJECT (sink, "waiting %d msec", delay);
    if (gst_poll_wait (sink->timer, GST_MSECOND * delay) == -1) {
      GST_LOG_OBJECT (sink, "unlocked");

      fret = gst_base_sink_wait_preroll (basesink);
      if (fret != GST_FLOW_OK)
        goto done;
    }
  } else {
    GST_LOG_OBJECT (sink, "we're %d msec late", -delay);
  }

  /* accumulate how much data have actually been sent
   * to the network since the last call to shout_send() */
  queuelen = shout_queuelen (sink->conn);
  if (sink->prev_queuelen > 0)
    sink->data_sent += sink->prev_queuelen - queuelen;

  gst_buffer_map (buf, &map, GST_MAP_READ);

  /* add map.size instead of re-reading the queue length because
   * the data may actually be sent immediately */
  sink->prev_queuelen = queuelen + map.size;

  GST_LOG_OBJECT (sink, "sending %u bytes of data, queue length now is %"
      G_GUINT64_FORMAT, (guint) map.size, sink->prev_queuelen);

  ret = shout_send (sink->conn, map.data, map.size);

  gst_buffer_unmap (buf, &map);
  if (ret != SHOUTERR_SUCCESS)
    goto send_error;

  now = gst_util_get_timestamp ();
  if (now - sink->datasent_reset_ts >= 500 * GST_MSECOND) {
    guint64 send_rate;

    send_rate = gst_util_uint64_scale (sink->data_sent, GST_SECOND,
        now - sink->datasent_reset_ts);

    if (send_rate == 0 && !sink->stalled) {
      sink->stalled = TRUE;
      sink->stalled_ts = now;
    } else if (send_rate > 0 && sink->stalled) {
      sink->stalled = FALSE;
    }

    sink->data_sent = 0;
    sink->datasent_reset_ts = now;

    GST_DEBUG_OBJECT (sink, "sending rate is %" G_GUINT64_FORMAT " bps, "
        "stalled %d, stalled_ts %" GST_TIME_FORMAT, send_rate, sink->stalled,
        GST_TIME_ARGS (sink->stalled_ts));

    if (sink->stalled && now - sink->stalled_ts >= sink->timeout * GST_MSECOND) {
      GST_WARNING_OBJECT (sink, "network send queue is stalled for too long");
      goto network_error;
    }
  }

done:

  return fret;

/* ERRORS */
send_error:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("shout_send() failed: %s", shout_get_error (sink->conn)));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return GST_FLOW_ERROR;
  }

network_error:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("network timeout reached"));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        SHOUTERR_BUSY);
    return GST_FLOW_ERROR;
  }
}

static void
gst_shout2send_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstShout2send *shout2send;

  shout2send = GST_SHOUT2SEND (object);
  switch (prop_id) {

    case ARG_IP:
      g_free (shout2send->ip);
      shout2send->ip = g_strdup (g_value_get_string (value));
      break;
    case ARG_PORT:
      shout2send->port = g_value_get_int (value);
      break;
    case ARG_PASSWORD:
      g_free (shout2send->password);
      shout2send->password = g_strdup (g_value_get_string (value));
      break;
    case ARG_USERNAME:
      g_free (shout2send->username);
      shout2send->username = g_strdup (g_value_get_string (value));
      break;
    case ARG_PUBLIC:
      shout2send->ispublic = g_value_get_boolean (value);
      break;
    case ARG_STREAMNAME:       /* Name of the stream */
      g_free (shout2send->streamname);
      shout2send->streamname = g_strdup (g_value_get_string (value));
      break;
    case ARG_DESCRIPTION:      /* Description of the stream */
      g_free (shout2send->description);
      shout2send->description = g_strdup (g_value_get_string (value));
      break;
    case ARG_GENRE:            /* Genre of the stream */
      g_free (shout2send->genre);
      shout2send->genre = g_strdup (g_value_get_string (value));
      break;
    case ARG_PROTOCOL:         /* protocol to connect with */
      shout2send->protocol = g_value_get_enum (value);
      break;
    case ARG_MOUNT:            /* mountpoint of stream (icecast only) */
      g_free (shout2send->mount);
      shout2send->mount = g_strdup (g_value_get_string (value));
      break;
    case ARG_URL:              /* the stream's homepage URL */
      g_free (shout2send->url);
      shout2send->url = g_strdup (g_value_get_string (value));
      break;
    case ARG_TIMEOUT:
      shout2send->timeout = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_shout2send_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstShout2send *shout2send;

  shout2send = GST_SHOUT2SEND (object);
  switch (prop_id) {

    case ARG_IP:
      g_value_set_string (value, shout2send->ip);
      break;
    case ARG_PORT:
      g_value_set_int (value, shout2send->port);
      break;
    case ARG_PASSWORD:
      g_value_set_string (value, shout2send->password);
      break;
    case ARG_USERNAME:
      g_value_set_string (value, shout2send->username);
      break;
    case ARG_PUBLIC:
      g_value_set_boolean (value, shout2send->ispublic);
      break;
    case ARG_STREAMNAME:       /* Name of the stream */
      g_value_set_string (value, shout2send->streamname);
      break;
    case ARG_DESCRIPTION:      /* Description of the stream */
      g_value_set_string (value, shout2send->description);
      break;
    case ARG_GENRE:            /* Genre of the stream */
      g_value_set_string (value, shout2send->genre);
      break;
    case ARG_PROTOCOL:         /* protocol to connect with */
      g_value_set_enum (value, shout2send->protocol);
      break;
    case ARG_MOUNT:            /* mountpoint of stream (icecast only) */
      g_value_set_string (value, shout2send->mount);
      break;
    case ARG_URL:              /* the stream's homepage URL */
      g_value_set_string (value, shout2send->url);
      break;
    case ARG_TIMEOUT:
      g_value_set_uint (value, shout2send->timeout);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_shout2send_setcaps (GstBaseSink * basesink, GstCaps * caps)
{
  const gchar *mimetype;
  GstShout2send *shout2send;
  gboolean ret = TRUE;

  shout2send = GST_SHOUT2SEND (basesink);

  mimetype = gst_structure_get_name (gst_caps_get_structure (caps, 0));

  GST_DEBUG_OBJECT (shout2send, "mimetype of caps given is: %s", mimetype);

  if (!strcmp (mimetype, "audio/mpeg")) {
    shout2send->format = SHOUT_FORMAT_MP3;
  } else if (g_str_has_suffix (mimetype, "/ogg")) {
    shout2send->format = SHOUT_FORMAT_OGG;
#ifdef SHOUT_FORMAT_WEBM
  } else if (g_str_has_suffix (mimetype, "/webm")) {
    shout2send->format = SHOUT_FORMAT_WEBM;
#endif
  } else {
    ret = FALSE;
  }

  return ret;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
#ifdef ENABLE_NLS
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */

  return gst_element_register (plugin, "shout2send", GST_RANK_NONE,
      GST_TYPE_SHOUT2SEND);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    shout2,
    "Sends data to an icecast server using libshout2",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
