/* GStreamer RTP DTMF source
 *
 * gstrtpdtmfsrc.c:
 *
 * Copyright (C) <2007> Nokia Corporation.
 *   Contact: Zeeshan Ali <zeeshan.ali@nokia.com>
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *               2000,2005 Wim Taymans <wim@fluendo.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-rtpdtmfsrc
 * @see_also: dtmfsrc, rtpdtmfdepay, rtpdtmfmux
 *
 * The RTPDTMFSrc element generates RTP DTMF (RFC 2833) event packets on request
 * from application. The application communicates the beginning and end of a
 * DTMF event using custom upstream gstreamer events. To report a DTMF event, an
 * application must send an event of type GST_EVENT_CUSTOM_UPSTREAM, having a
 * structure of name "dtmf-event" with fields set according to the following
 * table:
 *
 * <informaltable>
 * <tgroup cols='4'>
 * <colspec colname='Name' />
 * <colspec colname='Type' />
 * <colspec colname='Possible values' />
 * <colspec colname='Purpose' />
 * <thead>
 * <row>
 * <entry>Name</entry>
 * <entry>GType</entry>
 * <entry>Possible values</entry>
 * <entry>Purpose</entry>
 * </row>
 * </thead>
 * <tbody>
 * <row>
 * <entry>type</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-1</entry>
 * <entry>The application uses this field to specify which of the two methods
 * specified in RFC 2833 to use. The value should be 0 for tones and 1 for
 * named events. Tones are specified by their frequencies and events are specied
 * by their number. This element can only take events as input. Do not confuse
 * with "method" which specified the output.
 * </entry>
 * </row>
 * <row>
 * <entry>number</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-15</entry>
 * <entry>The event number.</entry>
 * </row>
 * <row>
 * <entry>volume</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-36</entry>
 * <entry>This field describes the power level of the tone, expressed in dBm0
 * after dropping the sign. Power levels range from 0 to -63 dBm0. The range of
 * valid DTMF is from 0 to -36 dBm0. Can be omitted if start is set to FALSE.
 * </entry>
 * </row>
 * <row>
 * <entry>start</entry>
 * <entry>G_TYPE_BOOLEAN</entry>
 * <entry>True or False</entry>
 * <entry>Whether the event is starting or ending.</entry>
 * </row>
 * <row>
 * <entry>method</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>1</entry>
 * <entry>The method used for sending event, this element will react if this
 * field is absent or 1.
 * </entry>
 * </row>
 * </tbody>
 * </tgroup>
 * </informaltable>
 *
 * For example, the following code informs the pipeline (and in turn, the
 * RTPDTMFSrc element inside the pipeline) about the start of an RTP DTMF named
 * event '1' of volume -25 dBm0:
 *
 * <programlisting>
 * structure = gst_structure_new ("dtmf-event",
 *                    "type", G_TYPE_INT, 1,
 *                    "number", G_TYPE_INT, 1,
 *                    "volume", G_TYPE_INT, 25,
 *                    "start", G_TYPE_BOOLEAN, TRUE, NULL);
 *
 * event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, structure);
 * gst_element_send_event (pipeline, event);
 * </programlisting>
 *
 * When a DTMF tone actually starts or stop, a "dtmf-event-processed"
 * element #GstMessage with the same fields as the "dtmf-event"
 * #GstEvent that was used to request the event. Also, if any event
 * has not been processed when the element goes from the PAUSED to the
 * READY state, then a "dtmf-event-dropped" message is posted on the
 * #GstBus in the order that they were received.
  */

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

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

#include <glib.h>

#include "gstrtpdtmfsrc.h"

#define GST_RTP_DTMF_TYPE_EVENT  1
#define DEFAULT_PTIME            40     /* ms */
#define DEFAULT_SSRC             -1
#define DEFAULT_PT               96
#define DEFAULT_TIMESTAMP_OFFSET -1
#define DEFAULT_SEQNUM_OFFSET    -1
#define DEFAULT_CLOCK_RATE       8000

#define DEFAULT_PACKET_REDUNDANCY 1
#define MIN_PACKET_REDUNDANCY 1
#define MAX_PACKET_REDUNDANCY 5

GST_DEBUG_CATEGORY_STATIC (gst_rtp_dtmf_src_debug);
#define GST_CAT_DEFAULT gst_rtp_dtmf_src_debug

/* signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_SSRC,
  PROP_TIMESTAMP_OFFSET,
  PROP_SEQNUM_OFFSET,
  PROP_PT,
  PROP_CLOCK_RATE,
  PROP_TIMESTAMP,
  PROP_SEQNUM,
  PROP_REDUNDANCY
};

static GstStaticPadTemplate gst_rtp_dtmf_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "payload = (int) [ 96, 127 ], "
        "clock-rate = (int) [ 0, MAX ], "
        "encoding-name = (string) \"TELEPHONE-EVENT\"")
    /*  "events = (string) \"0-15\" */
    );


G_DEFINE_TYPE (GstRTPDTMFSrc, gst_rtp_dtmf_src, GST_TYPE_BASE_SRC);

static void gst_rtp_dtmf_src_finalize (GObject * object);

static void gst_rtp_dtmf_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rtp_dtmf_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static gboolean gst_rtp_dtmf_src_handle_event (GstBaseSrc * basesrc,
    GstEvent * event);
static GstStateChangeReturn gst_rtp_dtmf_src_change_state (GstElement * element,
    GstStateChange transition);
static void gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc * dtmfsrc,
    gint event_number, gint event_volume);
static void gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc * dtmfsrc);

static gboolean gst_rtp_dtmf_src_unlock (GstBaseSrc * src);
static gboolean gst_rtp_dtmf_src_unlock_stop (GstBaseSrc * src);
static GstFlowReturn gst_rtp_dtmf_src_create (GstBaseSrc * basesrc,
    guint64 offset, guint length, GstBuffer ** buffer);
static gboolean gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc);
static gboolean gst_rtp_dtmf_src_query (GstBaseSrc * basesrc, GstQuery * query);


static void
gst_rtp_dtmf_src_class_init (GstRTPDTMFSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstBaseSrcClass *gstbasesrc_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_rtp_dtmf_src_debug,
      "rtpdtmfsrc", 0, "rtpdtmfsrc element");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_dtmf_src_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP DTMF packet generator", "Source/Network",
      "Generates RTP DTMF packets", "Zeeshan Ali <zeeshan.ali@nokia.com>");

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_finalize);
  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_get_property);

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMESTAMP,
      g_param_spec_uint ("timestamp", "Timestamp",
          "The RTP timestamp of the last processed packet",
          0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM,
      g_param_spec_uint ("seqnum", "Sequence number",
          "The RTP sequence number of the last processed packet",
          0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass),
      PROP_TIMESTAMP_OFFSET, g_param_spec_int ("timestamp-offset",
          "Timestamp Offset",
          "Offset to add to all outgoing timestamps (-1 = random)", -1,
          G_MAXINT, DEFAULT_TIMESTAMP_OFFSET,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM_OFFSET,
      g_param_spec_int ("seqnum-offset", "Sequence number Offset",
          "Offset to add to all outgoing seqnum (-1 = random)", -1, G_MAXINT,
          DEFAULT_SEQNUM_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CLOCK_RATE,
      g_param_spec_uint ("clock-rate", "clockrate",
          "The clock-rate at which to generate the dtmf packets",
          0, G_MAXUINT, DEFAULT_CLOCK_RATE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
      g_param_spec_uint ("ssrc", "SSRC",
          "The SSRC of the packets (-1 == random)",
          0, G_MAXUINT, DEFAULT_SSRC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
      g_param_spec_uint ("pt", "payload type",
          "The payload type of the packets",
          0, 0x80, DEFAULT_PT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_REDUNDANCY,
      g_param_spec_uint ("packet-redundancy", "Packet Redundancy",
          "Number of packets to send to indicate start and stop dtmf events",
          MIN_PACKET_REDUNDANCY, MAX_PACKET_REDUNDANCY,
          DEFAULT_PACKET_REDUNDANCY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_change_state);

  gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_unlock);
  gstbasesrc_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_unlock_stop);

  gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_handle_event);
  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_create);
  gstbasesrc_class->negotiate = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_negotiate);
  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_query);
}

static void
gst_rtp_dtmf_src_event_free (GstRTPDTMFSrcEvent * event)
{
  if (event) {
    if (event->payload)
      g_slice_free (GstRTPDTMFPayload, event->payload);
    g_slice_free (GstRTPDTMFSrcEvent, event);
  }
}

static void
gst_rtp_dtmf_src_init (GstRTPDTMFSrc * object)
{
  gst_base_src_set_format (GST_BASE_SRC (object), GST_FORMAT_TIME);
  gst_base_src_set_live (GST_BASE_SRC (object), TRUE);

  object->ssrc = DEFAULT_SSRC;
  object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
  object->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
  object->pt = DEFAULT_PT;
  object->clock_rate = DEFAULT_CLOCK_RATE;
  object->ptime = DEFAULT_PTIME;
  object->packet_redundancy = DEFAULT_PACKET_REDUNDANCY;

  object->event_queue =
      g_async_queue_new_full ((GDestroyNotify) gst_rtp_dtmf_src_event_free);
  object->payload = NULL;

  GST_DEBUG_OBJECT (object, "init done");
}

static void
gst_rtp_dtmf_src_finalize (GObject * object)
{
  GstRTPDTMFSrc *dtmfsrc;

  dtmfsrc = GST_RTP_DTMF_SRC (object);

  if (dtmfsrc->event_queue) {
    g_async_queue_unref (dtmfsrc->event_queue);
    dtmfsrc->event_queue = NULL;
  }


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

static gboolean
gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc * dtmfsrc,
    const GstStructure * event_structure)
{
  gint event_type;
  gboolean start;
  gint method;
  GstClockTime last_stop;
  gint event_number;
  gint event_volume;
  gboolean correct_order;

  if (!gst_structure_get_int (event_structure, "type", &event_type) ||
      !gst_structure_get_boolean (event_structure, "start", &start) ||
      event_type != GST_RTP_DTMF_TYPE_EVENT)
    goto failure;

  if (gst_structure_get_int (event_structure, "method", &method)) {
    if (method != 1) {
      goto failure;
    }
  }

  if (start)
    if (!gst_structure_get_int (event_structure, "number", &event_number) ||
        !gst_structure_get_int (event_structure, "volume", &event_volume))
      goto failure;

  GST_OBJECT_LOCK (dtmfsrc);
  if (gst_structure_get_clock_time (event_structure, "last-stop", &last_stop))
    dtmfsrc->last_stop = last_stop;
  else
    dtmfsrc->last_stop = GST_CLOCK_TIME_NONE;
  correct_order = (start != dtmfsrc->last_event_was_start);
  dtmfsrc->last_event_was_start = start;
  GST_OBJECT_UNLOCK (dtmfsrc);

  if (!correct_order)
    goto failure;

  if (start) {
    if (!gst_structure_get_int (event_structure, "number", &event_number) ||
        !gst_structure_get_int (event_structure, "volume", &event_volume))
      goto failure;

    GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d",
        event_number, event_volume);
    gst_rtp_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume);
  }

  else {
    GST_DEBUG_OBJECT (dtmfsrc, "Received stop event");
    gst_rtp_dtmf_src_add_stop_event (dtmfsrc);
  }

  return TRUE;
failure:
  return FALSE;
}

static gboolean
gst_rtp_dtmf_src_handle_custom_upstream (GstRTPDTMFSrc * dtmfsrc,
    GstEvent * event)
{
  gboolean result = FALSE;
  gchar *struct_str;
  const GstStructure *structure;

  GstState state;
  GstStateChangeReturn ret;

  ret = gst_element_get_state (GST_ELEMENT (dtmfsrc), &state, NULL, 0);
  if (ret != GST_STATE_CHANGE_SUCCESS || state != GST_STATE_PLAYING) {
    GST_DEBUG_OBJECT (dtmfsrc, "Received event while not in PLAYING state");
    goto ret;
  }

  GST_DEBUG_OBJECT (dtmfsrc, "Received event is of our interest");
  structure = gst_event_get_structure (event);
  struct_str = gst_structure_to_string (structure);
  GST_DEBUG_OBJECT (dtmfsrc, "Event has structure %s", struct_str);
  g_free (struct_str);
  if (structure && gst_structure_has_name (structure, "dtmf-event"))
    result = gst_rtp_dtmf_src_handle_dtmf_event (dtmfsrc, structure);

ret:
  return result;
}

static gboolean
gst_rtp_dtmf_src_handle_event (GstBaseSrc * basesrc, GstEvent * event)
{
  GstRTPDTMFSrc *dtmfsrc;
  gboolean result = FALSE;

  dtmfsrc = GST_RTP_DTMF_SRC (basesrc);

  GST_DEBUG_OBJECT (dtmfsrc, "Received an event on the src pad");
  if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) {
    result = gst_rtp_dtmf_src_handle_custom_upstream (dtmfsrc, event);
  }

  return result;
}

static void
gst_rtp_dtmf_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRTPDTMFSrc *dtmfsrc;

  dtmfsrc = GST_RTP_DTMF_SRC (object);

  switch (prop_id) {
    case PROP_TIMESTAMP_OFFSET:
      dtmfsrc->ts_offset = g_value_get_int (value);
      break;
    case PROP_SEQNUM_OFFSET:
      dtmfsrc->seqnum_offset = g_value_get_int (value);
      break;
    case PROP_CLOCK_RATE:
      dtmfsrc->clock_rate = g_value_get_uint (value);
      dtmfsrc->dirty = TRUE;
      break;
    case PROP_SSRC:
      dtmfsrc->ssrc = g_value_get_uint (value);
      break;
    case PROP_PT:
      dtmfsrc->pt = g_value_get_uint (value);
      dtmfsrc->dirty = TRUE;
      break;
    case PROP_REDUNDANCY:
      dtmfsrc->packet_redundancy = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_dtmf_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstRTPDTMFSrc *dtmfsrc;

  dtmfsrc = GST_RTP_DTMF_SRC (object);

  switch (prop_id) {
    case PROP_TIMESTAMP_OFFSET:
      g_value_set_int (value, dtmfsrc->ts_offset);
      break;
    case PROP_SEQNUM_OFFSET:
      g_value_set_int (value, dtmfsrc->seqnum_offset);
      break;
    case PROP_CLOCK_RATE:
      g_value_set_uint (value, dtmfsrc->clock_rate);
      break;
    case PROP_SSRC:
      g_value_set_uint (value, dtmfsrc->ssrc);
      break;
    case PROP_PT:
      g_value_set_uint (value, dtmfsrc->pt);
      break;
    case PROP_TIMESTAMP:
      g_value_set_uint (value, dtmfsrc->rtp_timestamp);
      break;
    case PROP_SEQNUM:
      g_value_set_uint (value, dtmfsrc->seqnum);
      break;
    case PROP_REDUNDANCY:
      g_value_set_uint (value, dtmfsrc->packet_redundancy);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_rtp_dtmf_prepare_timestamps (GstRTPDTMFSrc * dtmfsrc)
{
  GstClockTime last_stop;

  GST_OBJECT_LOCK (dtmfsrc);
  last_stop = dtmfsrc->last_stop;
  GST_OBJECT_UNLOCK (dtmfsrc);

  if (GST_CLOCK_TIME_IS_VALID (last_stop)) {
    dtmfsrc->start_timestamp = last_stop;
  } else {
    GstClock *clock = gst_element_get_clock (GST_ELEMENT (dtmfsrc));

    if (clock == NULL)
      return FALSE;

    dtmfsrc->start_timestamp = gst_clock_get_time (clock)
        - gst_element_get_base_time (GST_ELEMENT (dtmfsrc));
    gst_object_unref (clock);
  }

  /* If the last stop was in the past, then lets add the buffers together */
  if (dtmfsrc->start_timestamp < dtmfsrc->timestamp)
    dtmfsrc->start_timestamp = dtmfsrc->timestamp;

  dtmfsrc->timestamp = dtmfsrc->start_timestamp;

  dtmfsrc->rtp_timestamp = dtmfsrc->ts_base +
      gst_util_uint64_scale_int (gst_segment_to_running_time (&GST_BASE_SRC
          (dtmfsrc)->segment, GST_FORMAT_TIME, dtmfsrc->timestamp),
      dtmfsrc->clock_rate, GST_SECOND);

  return TRUE;
}


static void
gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc * dtmfsrc, gint event_number,
    gint event_volume)
{

  GstRTPDTMFSrcEvent *event = g_slice_new0 (GstRTPDTMFSrcEvent);
  event->event_type = RTP_DTMF_EVENT_TYPE_START;

  event->payload = g_slice_new0 (GstRTPDTMFPayload);
  event->payload->event = CLAMP (event_number, MIN_EVENT, MAX_EVENT);
  event->payload->volume = CLAMP (event_volume, MIN_VOLUME, MAX_VOLUME);

  g_async_queue_push (dtmfsrc->event_queue, event);
}

static void
gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc * dtmfsrc)
{

  GstRTPDTMFSrcEvent *event = g_slice_new0 (GstRTPDTMFSrcEvent);
  event->event_type = RTP_DTMF_EVENT_TYPE_STOP;

  g_async_queue_push (dtmfsrc->event_queue, event);
}


static void
gst_rtp_dtmf_prepare_rtp_headers (GstRTPDTMFSrc * dtmfsrc,
    GstRTPBuffer * rtpbuf)
{
  gst_rtp_buffer_set_ssrc (rtpbuf, dtmfsrc->current_ssrc);
  gst_rtp_buffer_set_payload_type (rtpbuf, dtmfsrc->pt);
  /* Only the very first packet gets a marker */
  if (dtmfsrc->first_packet) {
    gst_rtp_buffer_set_marker (rtpbuf, TRUE);
  } else if (dtmfsrc->last_packet) {
    dtmfsrc->payload->e = 1;
  }

  dtmfsrc->seqnum++;
  gst_rtp_buffer_set_seq (rtpbuf, dtmfsrc->seqnum);

  /* timestamp of RTP header */
  gst_rtp_buffer_set_timestamp (rtpbuf, dtmfsrc->rtp_timestamp);
}

static GstBuffer *
gst_rtp_dtmf_src_create_next_rtp_packet (GstRTPDTMFSrc * dtmfsrc)
{
  GstBuffer *buf;
  GstRTPDTMFPayload *payload;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

  buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);

  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtpbuffer);

  gst_rtp_dtmf_prepare_rtp_headers (dtmfsrc, &rtpbuffer);

  /* timestamp and duration of GstBuffer */
  /* Redundant buffer have no duration ... */
  if (dtmfsrc->redundancy_count > 1)
    GST_BUFFER_DURATION (buf) = 0;
  else
    GST_BUFFER_DURATION (buf) = dtmfsrc->ptime * GST_MSECOND;
  GST_BUFFER_PTS (buf) = dtmfsrc->timestamp;

  payload = (GstRTPDTMFPayload *) gst_rtp_buffer_get_payload (&rtpbuffer);

  /* copy payload and convert to network-byte order */
  memmove (payload, dtmfsrc->payload, sizeof (GstRTPDTMFPayload));

  payload->duration = g_htons (payload->duration);

  if (dtmfsrc->redundancy_count <= 1 && dtmfsrc->last_packet) {
    GstClockTime inter_digit_interval = MIN_INTER_DIGIT_INTERVAL;

    if (inter_digit_interval % dtmfsrc->ptime != 0)
      inter_digit_interval += dtmfsrc->ptime -
          (MIN_INTER_DIGIT_INTERVAL % dtmfsrc->ptime);

    GST_BUFFER_DURATION (buf) += inter_digit_interval * GST_MSECOND;
  }

  GST_LOG_OBJECT (dtmfsrc, "Creating new buffer with event %u duration "
      " gst: %" GST_TIME_FORMAT " at %" GST_TIME_FORMAT "(rtp ts:%u dur:%u)",
      dtmfsrc->payload->event, GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), dtmfsrc->rtp_timestamp,
      dtmfsrc->payload->duration);

  /* duration of DTMF payloadfor the NEXT packet */
  /* not updated for redundant packets */
  if (dtmfsrc->redundancy_count <= 1)
    dtmfsrc->payload->duration += dtmfsrc->ptime * dtmfsrc->clock_rate / 1000;

  if (GST_CLOCK_TIME_IS_VALID (dtmfsrc->timestamp))
    dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);

  gst_rtp_buffer_unmap (&rtpbuffer);

  return buf;
}

static GstMessage *
gst_dtmf_src_prepare_message (GstRTPDTMFSrc * dtmfsrc,
    const gchar * message_name, GstRTPDTMFSrcEvent * event)
{
  GstStructure *s;

  switch (event->event_type) {
    case RTP_DTMF_EVENT_TYPE_START:
      s = gst_structure_new (message_name,
          "type", G_TYPE_INT, 1,
          "method", G_TYPE_INT, 1,
          "start", G_TYPE_BOOLEAN, TRUE,
          "number", G_TYPE_INT, event->payload->event,
          "volume", G_TYPE_INT, event->payload->volume, NULL);
      break;
    case RTP_DTMF_EVENT_TYPE_STOP:
      s = gst_structure_new (message_name,
          "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 1,
          "start", G_TYPE_BOOLEAN, FALSE, NULL);
      break;
    case RTP_DTMF_EVENT_TYPE_PAUSE_TASK:
      return NULL;
    default:
      return NULL;
  }

  return gst_message_new_element (GST_OBJECT (dtmfsrc), s);
}

static void
gst_dtmf_src_post_message (GstRTPDTMFSrc * dtmfsrc, const gchar * message_name,
    GstRTPDTMFSrcEvent * event)
{
  GstMessage *m = gst_dtmf_src_prepare_message (dtmfsrc, message_name, event);


  if (m)
    gst_element_post_message (GST_ELEMENT (dtmfsrc), m);
}


static GstFlowReturn
gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset,
    guint length, GstBuffer ** buffer)
{
  GstRTPDTMFSrcEvent *event;
  GstRTPDTMFSrc *dtmfsrc;
  GstClock *clock;
  GstClockID *clockid;
  GstClockReturn clockret;
  GstMessage *message;
  GQueue messages = G_QUEUE_INIT;

  dtmfsrc = GST_RTP_DTMF_SRC (basesrc);

  do {

    if (dtmfsrc->payload == NULL) {
      GST_DEBUG_OBJECT (dtmfsrc, "popping");
      event = g_async_queue_pop (dtmfsrc->event_queue);

      GST_DEBUG_OBJECT (dtmfsrc, "popped %d", event->event_type);

      switch (event->event_type) {
        case RTP_DTMF_EVENT_TYPE_STOP:
          GST_WARNING_OBJECT (dtmfsrc,
              "Received a DTMF stop event when already stopped");
          gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event);
          break;

        case RTP_DTMF_EVENT_TYPE_START:
          dtmfsrc->first_packet = TRUE;
          dtmfsrc->last_packet = FALSE;
          /* Set the redundancy on the first packet */
          dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
          if (!gst_rtp_dtmf_prepare_timestamps (dtmfsrc))
            goto no_clock;

          g_queue_push_tail (&messages,
              gst_dtmf_src_prepare_message (dtmfsrc, "dtmf-event-processed",
                  event));
          dtmfsrc->payload = event->payload;
          dtmfsrc->payload->duration =
              dtmfsrc->ptime * dtmfsrc->clock_rate / 1000;
          event->payload = NULL;
          break;

        case RTP_DTMF_EVENT_TYPE_PAUSE_TASK:
          /*
           * We're pushing it back because it has to stay in there until
           * the task is really paused (and the queue will then be flushed
           */
          GST_OBJECT_LOCK (dtmfsrc);
          if (dtmfsrc->paused) {
            g_async_queue_push (dtmfsrc->event_queue, event);
            goto paused_locked;
          }
          GST_OBJECT_UNLOCK (dtmfsrc);
          break;
      }

      gst_rtp_dtmf_src_event_free (event);
    } else if (!dtmfsrc->first_packet && !dtmfsrc->last_packet &&
        (dtmfsrc->timestamp - dtmfsrc->start_timestamp) / GST_MSECOND >=
        MIN_PULSE_DURATION) {
      GST_DEBUG_OBJECT (dtmfsrc, "try popping");
      event = g_async_queue_try_pop (dtmfsrc->event_queue);


      if (event != NULL) {
        GST_DEBUG_OBJECT (dtmfsrc, "try popped %d", event->event_type);

        switch (event->event_type) {
          case RTP_DTMF_EVENT_TYPE_START:
            GST_WARNING_OBJECT (dtmfsrc,
                "Received two consecutive DTMF start events");
            gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event);
            break;

          case RTP_DTMF_EVENT_TYPE_STOP:
            dtmfsrc->first_packet = FALSE;
            dtmfsrc->last_packet = TRUE;
            /* Set the redundancy on the last packet */
            dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
            g_queue_push_tail (&messages,
                gst_dtmf_src_prepare_message (dtmfsrc, "dtmf-event-processed",
                    event));
            break;

          case RTP_DTMF_EVENT_TYPE_PAUSE_TASK:
            /*
             * We're pushing it back because it has to stay in there until
             * the task is really paused (and the queue will then be flushed)
             */
            GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
            GST_OBJECT_LOCK (dtmfsrc);
            if (dtmfsrc->paused) {
              g_async_queue_push (dtmfsrc->event_queue, event);
              goto paused_locked;
            }
            GST_OBJECT_UNLOCK (dtmfsrc);
            break;
        }
        gst_rtp_dtmf_src_event_free (event);
      }
    }
  } while (dtmfsrc->payload == NULL);


  GST_DEBUG_OBJECT (dtmfsrc, "Processed events, now lets wait on the clock");

  clock = gst_element_get_clock (GST_ELEMENT (basesrc));
  if (!clock)
    goto no_clock;
  clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp +
      gst_element_get_base_time (GST_ELEMENT (dtmfsrc)));
  gst_object_unref (clock);

  GST_OBJECT_LOCK (dtmfsrc);
  if (!dtmfsrc->paused) {
    dtmfsrc->clockid = clockid;
    GST_OBJECT_UNLOCK (dtmfsrc);

    clockret = gst_clock_id_wait (clockid, NULL);

    GST_OBJECT_LOCK (dtmfsrc);
    if (dtmfsrc->paused)
      clockret = GST_CLOCK_UNSCHEDULED;
  } else {
    clockret = GST_CLOCK_UNSCHEDULED;
  }
  gst_clock_id_unref (clockid);
  dtmfsrc->clockid = NULL;
  GST_OBJECT_UNLOCK (dtmfsrc);

  while ((message = g_queue_pop_head (&messages)) != NULL)
    gst_element_post_message (GST_ELEMENT (dtmfsrc), message);

  if (clockret == GST_CLOCK_UNSCHEDULED) {
    goto paused;
  }

send_last:

  if (dtmfsrc->dirty)
    if (!gst_rtp_dtmf_src_negotiate (basesrc))
      return GST_FLOW_NOT_NEGOTIATED;

  /* create buffer to hold the payload */
  *buffer = gst_rtp_dtmf_src_create_next_rtp_packet (dtmfsrc);

  if (dtmfsrc->redundancy_count)
    dtmfsrc->redundancy_count--;

  /* Only the very first one has a marker */
  dtmfsrc->first_packet = FALSE;

  /* This is the end of the event */
  if (dtmfsrc->last_packet == TRUE && dtmfsrc->redundancy_count == 0) {

    g_slice_free (GstRTPDTMFPayload, dtmfsrc->payload);
    dtmfsrc->payload = NULL;

    dtmfsrc->last_packet = FALSE;
  }

  return GST_FLOW_OK;

paused_locked:

  GST_OBJECT_UNLOCK (dtmfsrc);

paused:

  if (dtmfsrc->payload) {
    dtmfsrc->first_packet = FALSE;
    dtmfsrc->last_packet = TRUE;
    /* Set the redundanc on the last packet */
    dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
    goto send_last;
  } else {
    return GST_FLOW_FLUSHING;
  }

no_clock:
  GST_ELEMENT_ERROR (dtmfsrc, STREAM, MUX, ("No available clock"),
      ("No available clock"));
  gst_pad_pause_task (GST_BASE_SRC_PAD (dtmfsrc));
  return GST_FLOW_ERROR;
}


static gboolean
gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc)
{
  GstCaps *srccaps, *peercaps;
  GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
  gboolean ret;

  /* fill in the defaults, there properties cannot be negotiated. */
  srccaps = gst_caps_new_simple ("application/x-rtp",
      "media", G_TYPE_STRING, "audio",
      "encoding-name", G_TYPE_STRING, "TELEPHONE-EVENT", NULL);

  /* the peer caps can override some of the defaults */
  peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
  if (peercaps == NULL) {
    /* no peer caps, just add the other properties */
    gst_caps_set_simple (srccaps,
        "payload", G_TYPE_INT, dtmfsrc->pt,
        "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc,
        "timestamp-offset", G_TYPE_UINT, dtmfsrc->ts_base,
        "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
        "seqnum-offset", G_TYPE_UINT, dtmfsrc->seqnum_base, NULL);

    GST_DEBUG_OBJECT (dtmfsrc, "no peer caps: %" GST_PTR_FORMAT, srccaps);
  } else {
    GstCaps *temp;
    GstStructure *s;
    const GValue *value;
    gint pt;
    gint clock_rate;

    /* peer provides caps we can use to fixate, intersect. This always returns a
     * writable caps. */
    temp = gst_caps_intersect (srccaps, peercaps);
    gst_caps_unref (srccaps);
    gst_caps_unref (peercaps);

    if (!temp) {
      GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
      return FALSE;
    }

    if (gst_caps_is_empty (temp)) {
      GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
      gst_caps_unref (temp);
      return FALSE;
    }

    /* now fixate, start by taking the first caps */
    temp = gst_caps_truncate (temp);
    temp = gst_caps_make_writable (temp);
    srccaps = temp;

    /* get first structure */
    s = gst_caps_get_structure (srccaps, 0);

    if (gst_structure_get_int (s, "payload", &pt)) {
      /* use peer pt */
      dtmfsrc->pt = pt;
      GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
    } else {
      if (gst_structure_has_field (s, "payload")) {
        /* can only fixate if there is a field */
        gst_structure_fixate_field_nearest_int (s, "payload", dtmfsrc->pt);
        gst_structure_get_int (s, "payload", &pt);
        GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
      } else {
        /* no pt field, use the internal pt */
        pt = dtmfsrc->pt;
        gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
        GST_LOG_OBJECT (dtmfsrc, "using internal pt %d", pt);
      }
    }

    if (gst_structure_get_int (s, "clock-rate", &clock_rate)) {
      dtmfsrc->clock_rate = clock_rate;
      GST_LOG_OBJECT (dtmfsrc, "using clock-rate from caps %d",
          dtmfsrc->clock_rate);
    } else {
      GST_LOG_OBJECT (dtmfsrc, "using existing clock-rate %d",
          dtmfsrc->clock_rate);
    }
    gst_structure_set (s, "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate, NULL);


    if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ssrc");
      dtmfsrc->current_ssrc = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer ssrc %08x", dtmfsrc->current_ssrc);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc, NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal ssrc %08x",
          dtmfsrc->current_ssrc);
    }

    if (gst_structure_has_field_typed (s, "timestamp-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "timestamp-offset");
      dtmfsrc->ts_base = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer timestamp-offset %u",
          dtmfsrc->ts_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "timestamp-offset", G_TYPE_UINT, dtmfsrc->ts_base,
          NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal timestamp-offset %u",
          dtmfsrc->ts_base);
    }
    if (gst_structure_has_field_typed (s, "seqnum-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "seqnum-offset");
      dtmfsrc->seqnum_base = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer seqnum-offset %u",
          dtmfsrc->seqnum_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "seqnum-offset", G_TYPE_UINT, dtmfsrc->seqnum_base,
          NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal seqnum-offset %u",
          dtmfsrc->seqnum_base);
    }

    if (gst_structure_has_field_typed (s, "ptime", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ptime");
      dtmfsrc->ptime = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer ptime %u", dtmfsrc->ptime);
    } else if (gst_structure_has_field_typed (s, "maxptime", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "maxptime");
      dtmfsrc->ptime = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer maxptime as ptime %u",
          dtmfsrc->ptime);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ptime", G_TYPE_UINT, dtmfsrc->ptime, NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal ptime %u", dtmfsrc->ptime);
    }


    GST_DEBUG_OBJECT (dtmfsrc, "with peer caps: %" GST_PTR_FORMAT, srccaps);
  }

  ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
  gst_caps_unref (srccaps);

  dtmfsrc->dirty = FALSE;

  return ret;

}

static gboolean
gst_rtp_dtmf_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
    {
      GstClockTime latency;

      latency = dtmfsrc->ptime * GST_MSECOND;
      gst_query_set_latency (query, gst_base_src_is_live (basesrc), latency,
          GST_CLOCK_TIME_NONE);
      GST_DEBUG_OBJECT (dtmfsrc, "Reporting latency of %" GST_TIME_FORMAT,
          GST_TIME_ARGS (latency));
      res = TRUE;
    }
      break;
    default:
      res = GST_BASE_SRC_CLASS (gst_rtp_dtmf_src_parent_class)->query (basesrc,
          query);
      break;
  }

  return res;
}

static void
gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc * dtmfsrc)
{
  if (dtmfsrc->ssrc == -1)
    dtmfsrc->current_ssrc = g_random_int ();
  else
    dtmfsrc->current_ssrc = dtmfsrc->ssrc;

  if (dtmfsrc->seqnum_offset == -1)
    dtmfsrc->seqnum_base = g_random_int_range (0, G_MAXUINT16);
  else
    dtmfsrc->seqnum_base = dtmfsrc->seqnum_offset;
  dtmfsrc->seqnum = dtmfsrc->seqnum_base;

  if (dtmfsrc->ts_offset == -1)
    dtmfsrc->ts_base = g_random_int ();
  else
    dtmfsrc->ts_base = dtmfsrc->ts_offset;

  dtmfsrc->timestamp = 0;
}

static GstStateChangeReturn
gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
{
  GstRTPDTMFSrc *dtmfsrc;
  GstStateChangeReturn result;
  gboolean no_preroll = FALSE;
  GstRTPDTMFSrcEvent *event = NULL;

  dtmfsrc = GST_RTP_DTMF_SRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_rtp_dtmf_src_ready_to_paused (dtmfsrc);

      /* Flushing the event queue */
      while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) {
        gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event);
        gst_rtp_dtmf_src_event_free (event);
      }
      dtmfsrc->last_event_was_start = FALSE;

      no_preroll = TRUE;
      break;
    default:
      break;
  }

  if ((result =
          GST_ELEMENT_CLASS (gst_rtp_dtmf_src_parent_class)->change_state
          (element, transition)) == GST_STATE_CHANGE_FAILURE)
    goto failure;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      no_preroll = TRUE;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:

      /* Flushing the event queue */
      while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) {
        gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event);
        gst_rtp_dtmf_src_event_free (event);
      }
      dtmfsrc->last_event_was_start = FALSE;

      /* Indicate that we don't do PRE_ROLL */
      break;

    default:
      break;
  }

  if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
    result = GST_STATE_CHANGE_NO_PREROLL;

  return result;

  /* ERRORS */
failure:
  {
    GST_ERROR_OBJECT (dtmfsrc, "parent failed state change");
    return result;
  }
}


static gboolean
gst_rtp_dtmf_src_unlock (GstBaseSrc * src)
{
  GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (src);
  GstRTPDTMFSrcEvent *event = NULL;

  GST_DEBUG_OBJECT (dtmfsrc, "Called unlock");

  GST_OBJECT_LOCK (dtmfsrc);
  dtmfsrc->paused = TRUE;
  if (dtmfsrc->clockid) {
    gst_clock_id_unschedule (dtmfsrc->clockid);
  }
  GST_OBJECT_UNLOCK (dtmfsrc);

  GST_DEBUG_OBJECT (dtmfsrc, "Pushing the PAUSE_TASK event on unlock request");
  event = g_slice_new0 (GstRTPDTMFSrcEvent);
  event->event_type = RTP_DTMF_EVENT_TYPE_PAUSE_TASK;
  g_async_queue_push (dtmfsrc->event_queue, event);

  return TRUE;
}


static gboolean
gst_rtp_dtmf_src_unlock_stop (GstBaseSrc * src)
{
  GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (src);

  GST_DEBUG_OBJECT (dtmfsrc, "Unlock stopped");

  GST_OBJECT_LOCK (dtmfsrc);
  dtmfsrc->paused = FALSE;
  GST_OBJECT_UNLOCK (dtmfsrc);

  return TRUE;
}

gboolean
gst_rtp_dtmf_src_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpdtmfsrc",
      GST_RANK_NONE, GST_TYPE_RTP_DTMF_SRC);
}
