/* GStreamer - AirPort Express Audio Sink -
 *
 * Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
 * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
 *
 * RAW PCM input only as defined by the following GST_STATIC_PAD_TEMPLATE
 *
 * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
 *
 * gstapexsink.c 
 *
 * 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 <string.h>

#include "gstapexsink.h"

GST_DEBUG_CATEGORY_STATIC (apexsink_debug);
#define GST_CAT_DEFAULT apexsink_debug

static GstStaticPadTemplate gst_apexsink_sink_factory = GST_STATIC_PAD_TEMPLATE
    ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS
    (GST_APEX_RAOP_INPUT_TYPE ","
        "width = (int) " GST_APEX_RAOP_INPUT_WIDTH ","
        "depth = (int) " GST_APEX_RAOP_INPUT_DEPTH ","
        "endianness = (int) " GST_APEX_RAOP_INPUT_ENDIAN ","
        "channels = (int) " GST_APEX_RAOP_INPUT_CHANNELS ","
        "rate = (int) " GST_APEX_RAOP_INPUT_BIT_RATE ","
        "signed = (boolean) " GST_APEX_RAOP_INPUT_SIGNED)
    );


enum
{
  APEX_PROP_HOST = 1,
  APEX_PROP_PORT,
  APEX_PROP_VOLUME,
  APEX_PROP_JACK_TYPE,
  APEX_PROP_JACK_STATUS,
  APEX_PROP_GENERATION,
  APEX_PROP_TRANSPORT_PROTOCOL,
};

#define DEFAULT_APEX_HOST		""
#define DEFAULT_APEX_PORT		5000
#define DEFAULT_APEX_VOLUME		1.0
#define DEFAULT_APEX_JACK_TYPE		GST_APEX_JACK_TYPE_UNDEFINED
#define DEFAULT_APEX_JACK_STATUS	GST_APEX_JACK_STATUS_UNDEFINED
#define DEFAULT_APEX_GENERATION		GST_APEX_GENERATION_ONE
#define DEFAULT_APEX_TRANSPORT_PROTOCOL	GST_APEX_TCP

/* genum apex jack resolution */
GType
gst_apexsink_jackstatus_get_type (void)
{
  static GType jackstatus_type = 0;
  static const GEnumValue jackstatus[] = {
    {GST_APEX_JACK_STATUS_UNDEFINED, "GST_APEX_JACK_STATUS_UNDEFINED",
        "Jack status undefined"},
    {GST_APEX_JACK_STATUS_DISCONNECTED, "GST_APEX_JACK_STATUS_DISCONNECTED",
        "Jack disconnected"},
    {GST_APEX_JACK_STATUS_CONNECTED, "GST_APEX_JACK_STATUS_CONNECTED",
        "Jack connected"},
    {0, NULL, NULL},
  };

  if (!jackstatus_type) {
    jackstatus_type = g_enum_register_static ("GstApExJackStatus", jackstatus);
  }

  return jackstatus_type;
}

GType
gst_apexsink_jacktype_get_type (void)
{
  static GType jacktype_type = 0;
  static const GEnumValue jacktype[] = {
    {GST_APEX_JACK_TYPE_UNDEFINED, "GST_APEX_JACK_TYPE_UNDEFINED",
        "Undefined jack type"},
    {GST_APEX_JACK_TYPE_ANALOG, "GST_APEX_JACK_TYPE_ANALOG", "Analog jack"},
    {GST_APEX_JACK_TYPE_DIGITAL, "GST_APEX_JACK_TYPE_DIGITAL", "Digital jack"},
    {0, NULL, NULL},
  };

  if (!jacktype_type) {
    jacktype_type = g_enum_register_static ("GstApExJackType", jacktype);
  }

  return jacktype_type;
}

GType
gst_apexsink_generation_get_type (void)
{
  static GType generation_type = 0;
  static const GEnumValue generation[] = {
    {GST_APEX_GENERATION_ONE, "generation-one",
        "First generation (e.g., original AirPort Express)"},
    {GST_APEX_GENERATION_TWO, "generation-two",
        "Second generation (e.g., Apple TV v2)"},
    {0, NULL, NULL},
  };

  if (!generation_type) {
    generation_type = g_enum_register_static ("GstApExGeneration", generation);
  }

  return generation_type;
}

GType
gst_apexsink_transport_protocol_get_type (void)
{
  static GType transport_protocol_type = 0;
  static const GEnumValue transport_protocol[] = {
    {GST_APEX_TCP, "tcp", "TCP"},
    {GST_APEX_UDP, "udp", "UDP"},
    {0, NULL, NULL},
  };

  if (!transport_protocol_type) {
    transport_protocol_type =
        g_enum_register_static ("GstApExTransportProtocol", transport_protocol);
  }

  return transport_protocol_type;
}


static void gst_apexsink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_apexsink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_apexsink_finalise (GObject * object);

static gboolean gst_apexsink_open (GstAudioSink * asink);
static gboolean gst_apexsink_prepare (GstAudioSink * asink,
    GstRingBufferSpec * spec);
static guint gst_apexsink_write (GstAudioSink * asink, gpointer data,
    guint length);
static gboolean gst_apexsink_unprepare (GstAudioSink * asink);
static guint gst_apexsink_delay (GstAudioSink * asink);
static void gst_apexsink_reset (GstAudioSink * asink);
static gboolean gst_apexsink_close (GstAudioSink * asink);
static GstStateChangeReturn gst_apexsink_change_state (GstElement * element,
    GstStateChange transition);

/* mixer interface standard api */
static void gst_apexsink_interfaces_init (GType type);
static void gst_apexsink_implements_interface_init (GstImplementsInterfaceClass
    * iface);
static void gst_apexsink_mixer_interface_init (GstMixerInterface * iface);

static gboolean gst_apexsink_interface_supported (GstImplementsInterface *
    iface, GType iface_type);
static const GList *gst_apexsink_mixer_list_tracks (GstMixer * mixer);
static void gst_apexsink_mixer_set_volume (GstMixer * mixer,
    GstMixerTrack * track, gint * volumes);
static void gst_apexsink_mixer_get_volume (GstMixer * mixer,
    GstMixerTrack * track, gint * volumes);

GST_BOILERPLATE_FULL (GstApExSink, gst_apexsink, GstAudioSink,
    GST_TYPE_AUDIO_SINK, gst_apexsink_interfaces_init);

/* apex sink interface(s) stuff */
static void
gst_apexsink_interfaces_init (GType type)
{
  static const GInterfaceInfo implements_interface_info =
      { (GInterfaceInitFunc) gst_apexsink_implements_interface_init, NULL,
    NULL
  };
  static const GInterfaceInfo mixer_interface_info =
      { (GInterfaceInitFunc) gst_apexsink_mixer_interface_init, NULL, NULL };

  g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
      &implements_interface_info);
  g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_interface_info);
}

static void
gst_apexsink_implements_interface_init (GstImplementsInterfaceClass * iface)
{
  iface->supported = gst_apexsink_interface_supported;
}

static void
gst_apexsink_mixer_interface_init (GstMixerInterface * iface)
{
  GST_MIXER_TYPE (iface) = GST_MIXER_SOFTWARE;

  iface->list_tracks = gst_apexsink_mixer_list_tracks;
  iface->set_volume = gst_apexsink_mixer_set_volume;
  iface->get_volume = gst_apexsink_mixer_get_volume;
}

static gboolean
gst_apexsink_interface_supported (GstImplementsInterface * iface,
    GType iface_type)
{
  g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);

  return TRUE;
}

static const GList *
gst_apexsink_mixer_list_tracks (GstMixer * mixer)
{
  GstApExSink *apexsink = GST_APEX_SINK (mixer);

  return apexsink->tracks;
}

static void
gst_apexsink_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track,
    gint * volumes)
{
  GstApExSink *apexsink = GST_APEX_SINK (mixer);

  apexsink->volume = volumes[0];

  if (apexsink->gst_apexraop != NULL)
    gst_apexraop_set_volume (apexsink->gst_apexraop, apexsink->volume);
}

static void
gst_apexsink_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track,
    gint * volumes)
{
  GstApExSink *apexsink = GST_APEX_SINK (mixer);

  volumes[0] = apexsink->volume;
}

/* sink base init */
static void
gst_apexsink_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_static_metadata (element_class,
      "Apple AirPort Express Audio Sink", "Sink/Audio/Wireless",
      "Output stream to an AirPort Express",
      "Jérémie Bernard [GRemi] <gremimail@gmail.com>");
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_apexsink_sink_factory));
}

/* sink class init */
static void
gst_apexsink_class_init (GstApExSinkClass * klass)
{
  GST_DEBUG_CATEGORY_INIT (apexsink_debug, GST_APEX_SINK_NAME, 0,
      "AirPort Express sink");

  parent_class = g_type_class_peek_parent (klass);

  ((GObjectClass *) klass)->get_property =
      GST_DEBUG_FUNCPTR (gst_apexsink_get_property);
  ((GObjectClass *) klass)->set_property =
      GST_DEBUG_FUNCPTR (gst_apexsink_set_property);
  ((GObjectClass *) klass)->finalize =
      GST_DEBUG_FUNCPTR (gst_apexsink_finalise);

  ((GstAudioSinkClass *) klass)->open = GST_DEBUG_FUNCPTR (gst_apexsink_open);
  ((GstAudioSinkClass *) klass)->prepare =
      GST_DEBUG_FUNCPTR (gst_apexsink_prepare);
  ((GstAudioSinkClass *) klass)->write = GST_DEBUG_FUNCPTR (gst_apexsink_write);
  ((GstAudioSinkClass *) klass)->unprepare =
      GST_DEBUG_FUNCPTR (gst_apexsink_unprepare);
  ((GstAudioSinkClass *) klass)->delay = GST_DEBUG_FUNCPTR (gst_apexsink_delay);
  ((GstAudioSinkClass *) klass)->reset = GST_DEBUG_FUNCPTR (gst_apexsink_reset);
  ((GstAudioSinkClass *) klass)->close = GST_DEBUG_FUNCPTR (gst_apexsink_close);

  ((GstElementClass *) klass)->change_state =
      GST_DEBUG_FUNCPTR (gst_apexsink_change_state);

  g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_HOST,
      g_param_spec_string ("host", "Host", "AirPort Express target host",
          DEFAULT_APEX_HOST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_PORT,
      g_param_spec_uint ("port", "Port", "AirPort Express target port", 0,
          32000, DEFAULT_APEX_PORT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /* we need to expose the volume as a double for playbin. Internally we keep
   * it as an int between 0 and 100, where 75 corresponds to 1.0.
   * FIXME we should store the volume as a double. */
  g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_VOLUME,
      g_param_spec_double ("volume", "Volume", "AirPort Express target volume",
          0.0, 10.0, DEFAULT_APEX_VOLUME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_JACK_TYPE,
      g_param_spec_enum ("jack-type", "Jack Type",
          "AirPort Express connected jack type", GST_APEX_SINK_JACKTYPE_TYPE,
          DEFAULT_APEX_JACK_TYPE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property ((GObjectClass *) klass,
      APEX_PROP_JACK_STATUS, g_param_spec_enum ("jack-status", "Jack Status",
          "AirPort Express jack connection status",
          GST_APEX_SINK_JACKSTATUS_TYPE, DEFAULT_APEX_JACK_STATUS,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property ((GObjectClass *) klass,
      APEX_PROP_GENERATION, g_param_spec_enum ("generation", "Generation",
          "AirPort device generation",
          GST_APEX_SINK_GENERATION_TYPE, DEFAULT_APEX_GENERATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property ((GObjectClass *) klass,
      APEX_PROP_TRANSPORT_PROTOCOL, g_param_spec_enum ("transport-protocol",
          "Transport Protocol", "AirPort transport protocol",
          GST_APEX_SINK_TRANSPORT_PROTOCOL_TYPE,
          DEFAULT_APEX_TRANSPORT_PROTOCOL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

/* sink plugin instance init */
static void
gst_apexsink_init (GstApExSink * apexsink, GstApExSinkClass * g_class)
{
  GstMixerTrack *track = NULL;

  track = g_object_new (GST_TYPE_MIXER_TRACK, NULL);
  track->label = g_strdup ("Airport Express");
  track->num_channels = GST_APEX_RAOP_CHANNELS;
  track->min_volume = 0;
  track->max_volume = 100;
  track->flags = GST_MIXER_TRACK_OUTPUT;

  apexsink->host = g_strdup (DEFAULT_APEX_HOST);
  apexsink->port = DEFAULT_APEX_PORT;
  apexsink->volume = CLAMP (DEFAULT_APEX_VOLUME * 75, 0, 100);
  apexsink->gst_apexraop = NULL;
  apexsink->tracks = g_list_append (apexsink->tracks, track);
  apexsink->clock = gst_system_clock_obtain ();
  apexsink->clock_id = NULL;

  GST_INFO_OBJECT (apexsink,
      "ApEx sink default initialization, target=\"%s\", port=\"%d\", volume=\"%d%%\"",
      apexsink->host, apexsink->port, apexsink->volume);
}

/* apex sink set property */
static void
gst_apexsink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstApExSink *sink = GST_APEX_SINK (object);

  switch (prop_id) {
    case APEX_PROP_HOST:
      if (sink->gst_apexraop == NULL) {
        g_free (sink->host);
        sink->host = g_value_dup_string (value);

        GST_INFO_OBJECT (sink, "ApEx sink target set to \"%s\"", sink->host);
      } else {
        G_OBJECT_WARN_INVALID_PSPEC (object, "host", prop_id, pspec);
      }
      break;
    case APEX_PROP_PORT:
      if (sink->gst_apexraop == NULL) {
        sink->port = g_value_get_uint (value);

        GST_INFO_OBJECT (sink, "ApEx port set to \"%d\"", sink->port);
      } else {
        G_OBJECT_WARN_INVALID_PSPEC (object, "port", prop_id, pspec);
      }
      break;
    case APEX_PROP_VOLUME:
    {
      gdouble volume;

      volume = g_value_get_double (value);
      volume *= 75.0;

      sink->volume = CLAMP (volume, 0, 100);

      if (sink->gst_apexraop != NULL)
        gst_apexraop_set_volume (sink->gst_apexraop, sink->volume);

      GST_INFO_OBJECT (sink, "ApEx volume set to \"%d%%\"", sink->volume);
      break;
    }
    case APEX_PROP_GENERATION:
      if (sink->gst_apexraop == NULL) {
        sink->generation = g_value_get_enum (value);

        GST_INFO_OBJECT (sink, "ApEx generation set to \"%d\"",
            sink->generation);
      } else {
        GST_WARNING_OBJECT (sink,
            "SET-PROPERTY : generation property may not be set when apexsink opened !");
      }
      break;
    case APEX_PROP_TRANSPORT_PROTOCOL:
      if (sink->gst_apexraop == NULL) {
        sink->transport_protocol = g_value_get_enum (value);

        GST_INFO_OBJECT (sink, "ApEx transport protocol set to \"%d\"",
            sink->transport_protocol);
      } else {
        GST_WARNING_OBJECT (sink,
            "SET-PROPERTY : transport protocol property may not be set when apexsink opened !");
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* apex sink get property */
static void
gst_apexsink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstApExSink *sink = GST_APEX_SINK (object);

  switch (prop_id) {
    case APEX_PROP_HOST:
      g_value_set_string (value, sink->host);
      break;
    case APEX_PROP_PORT:
      g_value_set_uint (value, sink->port);
      break;
    case APEX_PROP_VOLUME:
      g_value_set_double (value, ((gdouble) sink->volume) / 75.0);
      break;
    case APEX_PROP_JACK_TYPE:
      g_value_set_enum (value, gst_apexraop_get_jacktype (sink->gst_apexraop));
      break;
    case APEX_PROP_JACK_STATUS:
      g_value_set_enum (value,
          gst_apexraop_get_jackstatus (sink->gst_apexraop));
      break;
    case APEX_PROP_GENERATION:
      g_value_set_enum (value,
          gst_apexraop_get_generation (sink->gst_apexraop));
      break;
    case APEX_PROP_TRANSPORT_PROTOCOL:
      g_value_set_enum (value,
          gst_apexraop_get_transport_protocol (sink->gst_apexraop));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* apex sink finalize */
static void
gst_apexsink_finalise (GObject * object)
{
  GstApExSink *sink = GST_APEX_SINK (object);

  if (sink->tracks) {
    g_list_foreach (sink->tracks, (GFunc) g_object_unref, NULL);
    g_list_free (sink->tracks);
    sink->tracks = NULL;
  }

  gst_object_unref (sink->clock);

  g_free (sink->host);

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

/* sink open : open the device */
static gboolean
gst_apexsink_open (GstAudioSink * asink)
{
  int res;
  GstApExSink *apexsink = (GstApExSink *) asink;

  apexsink->gst_apexraop = gst_apexraop_new (apexsink->host,
      apexsink->port, apexsink->generation, apexsink->transport_protocol);

  if ((res = gst_apexraop_connect (apexsink->gst_apexraop)) != GST_RTSP_STS_OK) {
    GST_ERROR_OBJECT (apexsink,
        "%s : network or RAOP failure, connection refused or timeout, RTSP code=%d",
        apexsink->host, res);
    return FALSE;
  }

  GST_INFO_OBJECT (apexsink,
      "OPEN : ApEx sink successfully connected to \"%s:%d\", ANNOUNCE, SETUP and RECORD requests performed",
      apexsink->host, apexsink->port);

  switch (gst_apexraop_get_jackstatus (apexsink->gst_apexraop)) {
    case GST_APEX_JACK_STATUS_CONNECTED:
      GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack is connected");
      break;
    case GST_APEX_JACK_STATUS_DISCONNECTED:
      GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack is disconnected !");
      break;
    default:
      GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack status is undefined !");
      break;
  }

  switch (gst_apexraop_get_jacktype (apexsink->gst_apexraop)) {
    case GST_APEX_JACK_TYPE_ANALOG:
      GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack type is analog");
      break;
    case GST_APEX_JACK_TYPE_DIGITAL:
      GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack type is digital");
      break;
    default:
      GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack type is undefined !");
      break;
  }

  if ((res =
          gst_apexraop_set_volume (apexsink->gst_apexraop,
              apexsink->volume)) != GST_RTSP_STS_OK) {
    GST_WARNING_OBJECT (apexsink,
        "%s : could not set initial volume to \"%d%%\", RTSP code=%d",
        apexsink->host, apexsink->volume, res);
  } else {
    GST_INFO_OBJECT (apexsink,
        "OPEN : ApEx sink successfully set volume to \"%d%%\"",
        apexsink->volume);
  }

  return TRUE;
}

/* prepare sink : configure the device with the specified format */
static gboolean
gst_apexsink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
{
  GstApExSink *apexsink = (GstApExSink *) asink;
  GstApExGeneration gen = gst_apexraop_get_generation (apexsink->gst_apexraop);

  apexsink->latency_time = spec->latency_time;

  spec->segsize = gen == GST_APEX_GENERATION_ONE
      ? GST_APEX_RAOP_V1_SAMPLES_PER_FRAME * GST_APEX_RAOP_BYTES_PER_SAMPLE
      : GST_APEX_RAOP_V2_SAMPLES_PER_FRAME * GST_APEX_RAOP_BYTES_PER_SAMPLE;
  spec->segtotal = 2;

  memset (spec->silence_sample, 0, sizeof (spec->silence_sample));

  GST_INFO_OBJECT (apexsink,
      "PREPARE : ApEx sink ready to stream at %dHz, %d bytes per sample, %d channels, %d bytes segments (%dkB/s)",
      spec->rate, spec->bytes_per_sample, spec->channels, spec->segsize,
      spec->rate * spec->bytes_per_sample / 1000);

  return TRUE;
}

/* sink write : write samples to the device */
static guint
gst_apexsink_write (GstAudioSink * asink, gpointer data, guint length)
{
  guint written;
  GstApExSink *apexsink = (GstApExSink *) asink;

  if ((written =
          gst_apexraop_write (apexsink->gst_apexraop, data,
              length)) != length) {
    GST_INFO_OBJECT (apexsink,
        "WRITE : %d of %d bytes sent, skipping frame samples...", written,
        length);
  } else {
    GST_INFO_OBJECT (apexsink, "WRITE : %d bytes sent", length);
    /* NOTE, previous calculation subtracted apexsink->latency_time from this;
     * however, the value below is less than apexsink->latency_time for generation 2.
     * In this case, the number went negative (actualy wrapped around into a big number).
     */
    apexsink->clock_id = gst_clock_new_single_shot_id (apexsink->clock,
        (GstClockTime) (gst_clock_get_time (apexsink->clock) +
            ((length * 1000000000.)
                / (GST_APEX_RAOP_BITRATE * GST_APEX_RAOP_BYTES_PER_SAMPLE))));
    gst_clock_id_wait (apexsink->clock_id, NULL);
    gst_clock_id_unref (apexsink->clock_id);
    apexsink->clock_id = NULL;
  }

  return length;
}

/* unprepare sink : undo operations done by prepare */
static gboolean
gst_apexsink_unprepare (GstAudioSink * asink)
{
  GST_INFO_OBJECT (asink, "UNPREPARE");

  return TRUE;
}

/* delay sink : get the estimated number of samples written but not played yet by the device */
static guint
gst_apexsink_delay (GstAudioSink * asink)
{
  GST_LOG_OBJECT (asink, "DELAY");

  return 0;
}

/* reset sink : unblock writes and flush the device */
static void
gst_apexsink_reset (GstAudioSink * asink)
{
  int res;
  GstApExSink *apexsink = (GstApExSink *) asink;

  GST_INFO_OBJECT (apexsink, "RESET : flushing buffer...");

  if ((res = gst_apexraop_flush (apexsink->gst_apexraop)) == GST_RTSP_STS_OK) {
    GST_INFO_OBJECT (apexsink, "RESET : ApEx buffer flush success");
  } else {
    GST_WARNING_OBJECT (apexsink,
        "RESET : could not flush ApEx buffer, RTSP code=%d", res);
  }
}

/* sink close : close the device */
static gboolean
gst_apexsink_close (GstAudioSink * asink)
{
  GstApExSink *apexsink = (GstApExSink *) asink;

  gst_apexraop_close (apexsink->gst_apexraop);
  gst_apexraop_free (apexsink->gst_apexraop);

  GST_INFO_OBJECT (apexsink, "CLOSE : ApEx sink closed connection");

  return TRUE;
}

static GstStateChangeReturn
gst_apexsink_change_state (GstElement * element, GstStateChange transition)
{
  GstApExSink *apexsink = (GstApExSink *) element;

  if (apexsink->clock_id && transition == GST_STATE_CHANGE_PAUSED_TO_READY) {
    gst_clock_id_unschedule (apexsink->clock_id);
    gst_clock_id_unref (apexsink->clock_id);
    apexsink->clock_id = NULL;
  }
  return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
}
