/* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.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.
 */
#include <string.h>

#include <gst/rtp/gstrtpbuffer.h>
#include <gst/rtp/gstrtcpbuffer.h>

#include "rtpsource.h"

GST_DEBUG_CATEGORY_STATIC (rtp_source_debug);
#define GST_CAT_DEFAULT rtp_source_debug

#define RTP_MAX_PROBATION_LEN  32

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

#define DEFAULT_SSRC                 0
#define DEFAULT_IS_CSRC              FALSE
#define DEFAULT_IS_VALIDATED         FALSE
#define DEFAULT_IS_SENDER            FALSE
#define DEFAULT_SDES                 NULL
#define DEFAULT_PROBATION            RTP_DEFAULT_PROBATION

enum
{
  PROP_0,
  PROP_SSRC,
  PROP_IS_CSRC,
  PROP_IS_VALIDATED,
  PROP_IS_SENDER,
  PROP_SDES,
  PROP_STATS,
  PROP_PROBATION,
  PROP_LAST
};

/* GObject vmethods */
static void rtp_source_finalize (GObject * object);
static void rtp_source_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void rtp_source_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

/* static guint rtp_source_signals[LAST_SIGNAL] = { 0 }; */

G_DEFINE_TYPE (RTPSource, rtp_source, G_TYPE_OBJECT);

static void
rtp_source_class_init (RTPSourceClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;

  gobject_class->finalize = rtp_source_finalize;

  gobject_class->set_property = rtp_source_set_property;
  gobject_class->get_property = rtp_source_get_property;

  g_object_class_install_property (gobject_class, PROP_SSRC,
      g_param_spec_uint ("ssrc", "SSRC",
          "The SSRC of this source", 0, G_MAXUINT, DEFAULT_SSRC,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_IS_CSRC,
      g_param_spec_boolean ("is-csrc", "Is CSRC",
          "If this SSRC is acting as a contributing source",
          DEFAULT_IS_CSRC, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_IS_VALIDATED,
      g_param_spec_boolean ("is-validated", "Is Validated",
          "If this SSRC is validated", DEFAULT_IS_VALIDATED,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_IS_SENDER,
      g_param_spec_boolean ("is-sender", "Is Sender",
          "If this SSRC is a sender", DEFAULT_IS_SENDER,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * RTPSource::sdes
   *
   * The current SDES items of the source. Returns a structure with name
   * application/x-rtp-source-sdes and may contain the following fields:
   *
   *  'cname'       G_TYPE_STRING  : The canonical name
   *  'name'        G_TYPE_STRING  : The user name
   *  'email'       G_TYPE_STRING  : The user's electronic mail address
   *  'phone'       G_TYPE_STRING  : The user's phone number
   *  'location'    G_TYPE_STRING  : The geographic user location
   *  'tool'        G_TYPE_STRING  : The name of application or tool
   *  'note'        G_TYPE_STRING  : A notice about the source
   *
   *  other fields may be present and these represent private items in
   *  the SDES where the field name is the prefix.
   */
  g_object_class_install_property (gobject_class, PROP_SDES,
      g_param_spec_boxed ("sdes", "SDES",
          "The SDES information for this source",
          GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * RTPSource::stats
   *
   * The statistics of the source. This property returns a GstStructure with
   * name application/x-rtp-source-stats with the following fields:
   *
   *  "ssrc"         G_TYPE_UINT     The SSRC of this source
   *  "internal"     G_TYPE_BOOLEAN  If this source is the source of the session
   *  "validated"    G_TYPE_BOOLEAN  If the source is validated
   *  "received-bye" G_TYPE_BOOLEAN  If we received a BYE from this source
   *  "is-csrc"      G_TYPE_BOOLEAN  If this source was found as CSRC
   *  "is-sender"    G_TYPE_BOOLEAN  If this source is a sender
   *  "seqnum-base"  G_TYPE_INT      first seqnum if known
   *  "clock-rate"   G_TYPE_INT      the clock rate of the media
   *
   * The following two fields are only present when known.
   *
   *  "rtp-from"     G_TYPE_STRING   where we received the last RTP packet from
   *  "rtcp-from"    G_TYPE_STRING   where we received the last RTCP packet from
   *
   * The following fields make sense for internal sources and will only increase
   * when "is-sender" is TRUE:
   *
   *  "octets-sent"  G_TYPE_UINT64   number of bytes we sent
   *  "packets-sent" G_TYPE_UINT64   number of packets we sent
   *
   * The following fields make sense for non-internal sources and will only
   * increase when "is-sender" is TRUE.
   *
   *  "octets-received"  G_TYPE_UINT64  total number of bytes received
   *  "packets-received" G_TYPE_UINT64  total number of packets received
   *
   * Following fields are updated when "is-sender" is TRUE.
   *
   *  "bitrate"      G_TYPE_UINT64   bitrate in bits per second
   *  "jitter"       G_TYPE_UINT     estimated jitter
   *  "packets-lost" G_TYPE_INT      estimated amount of packets lost
   *
   * The last SR report this source sent. This only updates when "is-sender" is
   * TRUE.
   *
   *  "have-sr"         G_TYPE_BOOLEAN  the source has sent SR
   *  "sr-ntptime"      G_TYPE_UINT64   ntptime of SR
   *  "sr-rtptime"      G_TYPE_UINT     rtptime of SR
   *  "sr-octet-count"  G_TYPE_UINT     the number of bytes in the SR
   *  "sr-packet-count" G_TYPE_UINT     the number of packets in the SR
   *
   * The following fields are only present for non-internal sources and
   * represent the content of the last RB packet that was sent to this source.
   * These values are only updated when the source is sending.
   *
   *  "sent-rb"               G_TYPE_BOOLEAN  we have sent an RB
   *  "sent-rb-fractionlost"  G_TYPE_UINT     calculated lost fraction
   *  "sent-rb-packetslost"   G_TYPE_INT      lost packets
   *  "sent-rb-exthighestseq" G_TYPE_UINT     last seen seqnum
   *  "sent-rb-jitter"        G_TYPE_UINT     jitter
   *  "sent-rb-lsr"           G_TYPE_UINT     last SR time
   *  "sent-rb-dlsr"          G_TYPE_UINT     delay since last SR
   *
   * The following fields are only present for non-internal sources and
   * represents the last RB that this source sent. This is only updated
   * when the source is receiving data and sending RB blocks.
   *
   *  "have-rb"          G_TYPE_BOOLEAN  the source has sent RB
   *  "rb-fractionlost"  G_TYPE_UINT     lost fraction
   *  "rb-packetslost"   G_TYPE_INT      lost packets
   *  "rb-exthighestseq" G_TYPE_UINT     highest received seqnum
   *  "rb-jitter"        G_TYPE_UINT     reception jitter
   *  "rb-lsr"           G_TYPE_UINT     last SR time
   *  "rb-dlsr"          G_TYPE_UINT     delay since last SR
   *
   * The round trip of this source. This is calculated from the last RB
   * values and the recption time of the last RB packet. Only present for
   * non-internal sources.
   *
   *  "rb-round-trip"    G_TYPE_UINT     the round trip time in nanoseconds
   */
  g_object_class_install_property (gobject_class, PROP_STATS,
      g_param_spec_boxed ("stats", "Stats",
          "The stats of this source", GST_TYPE_STRUCTURE,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PROBATION,
      g_param_spec_uint ("probation", "Number of probations",
          "Consecutive packet sequence numbers to accept the source",
          0, G_MAXUINT, DEFAULT_PROBATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  GST_DEBUG_CATEGORY_INIT (rtp_source_debug, "rtpsource", 0, "RTP Source");
}

/**
 * rtp_source_reset:
 * @src: an #RTPSource
 *
 * Reset the stats of @src.
 */
void
rtp_source_reset (RTPSource * src)
{
  src->received_bye = FALSE;

  src->stats.cycles = -1;
  src->stats.jitter = 0;
  src->stats.transit = -1;
  src->stats.curr_sr = 0;
  src->stats.curr_rr = 0;
}

static void
rtp_source_init (RTPSource * src)
{
  /* sources are initialy on probation until we receive enough valid RTP
   * packets or a valid RTCP packet */
  src->validated = FALSE;
  src->internal = FALSE;
  src->probation = DEFAULT_PROBATION;
  src->curr_probation = src->probation;
  src->closing = FALSE;

  src->sdes = gst_structure_new_empty ("application/x-rtp-source-sdes");

  src->payload = -1;
  src->clock_rate = -1;
  src->packets = g_queue_new ();
  src->seqnum_base = -1;
  src->last_rtptime = -1;

  src->retained_feedback = g_queue_new ();

  rtp_source_reset (src);
}

static void
rtp_conflicting_address_free (RTPConflictingAddress * addr)
{
  g_object_unref (addr->address);
  g_free (addr);
}

static void
rtp_source_finalize (GObject * object)
{
  RTPSource *src;
  GstBuffer *buffer;

  src = RTP_SOURCE_CAST (object);

  while ((buffer = g_queue_pop_head (src->packets)))
    gst_buffer_unref (buffer);
  g_queue_free (src->packets);

  gst_structure_free (src->sdes);

  g_free (src->bye_reason);

  gst_caps_replace (&src->caps, NULL);

  g_list_foreach (src->conflicting_addresses,
      (GFunc) rtp_conflicting_address_free, NULL);
  g_list_free (src->conflicting_addresses);

  while ((buffer = g_queue_pop_head (src->retained_feedback)))
    gst_buffer_unref (buffer);
  g_queue_free (src->retained_feedback);

  if (src->rtp_from)
    g_object_unref (src->rtp_from);
  if (src->rtcp_from)
    g_object_unref (src->rtcp_from);

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

static GstStructure *
rtp_source_create_stats (RTPSource * src)
{
  GstStructure *s;
  gboolean is_sender = src->is_sender;
  gboolean internal = src->internal;
  gchar *address_str;
  gboolean have_rb;
  guint8 fractionlost = 0;
  gint32 packetslost = 0;
  guint32 exthighestseq = 0;
  guint32 jitter = 0;
  guint32 lsr = 0;
  guint32 dlsr = 0;
  guint32 round_trip = 0;
  gboolean have_sr;
  GstClockTime time = 0;
  guint64 ntptime = 0;
  guint32 rtptime = 0;
  guint32 packet_count = 0;
  guint32 octet_count = 0;


  /* common data for all types of sources */
  s = gst_structure_new ("application/x-rtp-source-stats",
      "ssrc", G_TYPE_UINT, (guint) src->ssrc,
      "internal", G_TYPE_BOOLEAN, internal,
      "validated", G_TYPE_BOOLEAN, src->validated,
      "received-bye", G_TYPE_BOOLEAN, src->received_bye,
      "is-csrc", G_TYPE_BOOLEAN, src->is_csrc,
      "is-sender", G_TYPE_BOOLEAN, is_sender,
      "seqnum-base", G_TYPE_INT, src->seqnum_base,
      "clock-rate", G_TYPE_INT, src->clock_rate, NULL);

  /* add address and port */
  if (src->rtp_from) {
    address_str = __g_socket_address_to_string (src->rtp_from);
    gst_structure_set (s, "rtp-from", G_TYPE_STRING, address_str, NULL);
    g_free (address_str);
  }
  if (src->rtcp_from) {
    address_str = __g_socket_address_to_string (src->rtcp_from);
    gst_structure_set (s, "rtcp-from", G_TYPE_STRING, address_str, NULL);
    g_free (address_str);
  }

  gst_structure_set (s,
      "octets-sent", G_TYPE_UINT64, src->stats.octets_sent,
      "packets-sent", G_TYPE_UINT64, src->stats.packets_sent,
      "octets-received", G_TYPE_UINT64, src->stats.octets_received,
      "packets-received", G_TYPE_UINT64, src->stats.packets_received,
      "bitrate", G_TYPE_UINT64, src->bitrate,
      "packets-lost", G_TYPE_INT,
      (gint) rtp_stats_get_packets_lost (&src->stats), "jitter", G_TYPE_UINT,
      (guint) (src->stats.jitter >> 4), NULL);

  /* get the last SR. */
  have_sr = rtp_source_get_last_sr (src, &time, &ntptime, &rtptime,
      &packet_count, &octet_count);
  gst_structure_set (s,
      "have-sr", G_TYPE_BOOLEAN, have_sr,
      "sr-ntptime", G_TYPE_UINT64, ntptime,
      "sr-rtptime", G_TYPE_UINT, (guint) rtptime,
      "sr-octet-count", G_TYPE_UINT, (guint) octet_count,
      "sr-packet-count", G_TYPE_UINT, (guint) packet_count, NULL);

  if (!internal) {
    /* get the last RB we sent */
    gst_structure_set (s,
        "sent-rb", G_TYPE_BOOLEAN, src->last_rr.is_valid,
        "sent-rb-fractionlost", G_TYPE_UINT, (guint) src->last_rr.fractionlost,
        "sent-rb-packetslost", G_TYPE_INT, (gint) src->last_rr.packetslost,
        "sent-rb-exthighestseq", G_TYPE_UINT,
        (guint) src->last_rr.exthighestseq, "sent-rb-jitter", G_TYPE_UINT,
        (guint) src->last_rr.jitter, "sent-rb-lsr", G_TYPE_UINT,
        (guint) src->last_rr.lsr, "sent-rb-dlsr", G_TYPE_UINT,
        (guint) src->last_rr.dlsr, NULL);

    /* get the last RB */
    have_rb = rtp_source_get_last_rb (src, &fractionlost, &packetslost,
        &exthighestseq, &jitter, &lsr, &dlsr, &round_trip);

    gst_structure_set (s,
        "have-rb", G_TYPE_BOOLEAN, have_rb,
        "rb-fractionlost", G_TYPE_UINT, (guint) fractionlost,
        "rb-packetslost", G_TYPE_INT, (gint) packetslost,
        "rb-exthighestseq", G_TYPE_UINT, (guint) exthighestseq,
        "rb-jitter", G_TYPE_UINT, (guint) jitter,
        "rb-lsr", G_TYPE_UINT, (guint) lsr,
        "rb-dlsr", G_TYPE_UINT, (guint) dlsr,
        "rb-round-trip", G_TYPE_UINT, (guint) round_trip, NULL);
  }

  return s;
}

/**
 * rtp_source_get_sdes_struct:
 * @src: an #RTPSource
 *
 * Get the SDES from @src. See the SDES property for more details.
 *
 * Returns: %GstStructure of type "application/x-rtp-source-sdes". The result is
 * valid until the SDES items of @src are modified.
 */
const GstStructure *
rtp_source_get_sdes_struct (RTPSource * src)
{
  g_return_val_if_fail (RTP_IS_SOURCE (src), NULL);

  return src->sdes;
}

static gboolean
sdes_struct_compare_func (GQuark field_id, const GValue * value,
    gpointer user_data)
{
  GstStructure *old;
  const gchar *field;

  old = GST_STRUCTURE (user_data);
  field = g_quark_to_string (field_id);

  if (!gst_structure_has_field (old, field))
    return FALSE;

  g_assert (G_VALUE_HOLDS_STRING (value));

  return strcmp (g_value_get_string (value), gst_structure_get_string (old,
          field)) == 0;
}

/**
 * rtp_source_set_sdes:
 * @src: an #RTPSource
 * @sdes: the SDES structure
 *
 * Store the @sdes in @src. @sdes must be a structure of type
 * "application/x-rtp-source-sdes", see the SDES property for more details.
 *
 * This function takes ownership of @sdes.
 *
 * Returns: %FALSE if the SDES was unchanged.
 */
gboolean
rtp_source_set_sdes_struct (RTPSource * src, GstStructure * sdes)
{
  gboolean changed;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
  g_return_val_if_fail (strcmp (gst_structure_get_name (sdes),
          "application/x-rtp-source-sdes") == 0, FALSE);

  changed = !gst_structure_foreach (sdes, sdes_struct_compare_func, src->sdes);

  if (changed) {
    gst_structure_free (src->sdes);
    src->sdes = sdes;
  } else {
    gst_structure_free (sdes);
  }

  return changed;
}

static void
rtp_source_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  RTPSource *src;

  src = RTP_SOURCE (object);

  switch (prop_id) {
    case PROP_SSRC:
      src->ssrc = g_value_get_uint (value);
      break;
    case PROP_PROBATION:
      src->probation = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
rtp_source_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  RTPSource *src;

  src = RTP_SOURCE (object);

  switch (prop_id) {
    case PROP_SSRC:
      g_value_set_uint (value, rtp_source_get_ssrc (src));
      break;
    case PROP_IS_CSRC:
      g_value_set_boolean (value, rtp_source_is_as_csrc (src));
      break;
    case PROP_IS_VALIDATED:
      g_value_set_boolean (value, rtp_source_is_validated (src));
      break;
    case PROP_IS_SENDER:
      g_value_set_boolean (value, rtp_source_is_sender (src));
      break;
    case PROP_SDES:
      g_value_set_boxed (value, rtp_source_get_sdes_struct (src));
      break;
    case PROP_STATS:
      g_value_take_boxed (value, rtp_source_create_stats (src));
      break;
    case PROP_PROBATION:
      g_value_set_uint (value, src->probation);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/**
 * rtp_source_new:
 * @ssrc: an SSRC
 *
 * Create a #RTPSource with @ssrc.
 *
 * Returns: a new #RTPSource. Use g_object_unref() after usage.
 */
RTPSource *
rtp_source_new (guint32 ssrc)
{
  RTPSource *src;

  src = g_object_new (RTP_TYPE_SOURCE, NULL);
  src->ssrc = ssrc;

  return src;
}

/**
 * rtp_source_set_callbacks:
 * @src: an #RTPSource
 * @cb: callback functions
 * @user_data: user data
 *
 * Set the callbacks for the source.
 */
void
rtp_source_set_callbacks (RTPSource * src, RTPSourceCallbacks * cb,
    gpointer user_data)
{
  g_return_if_fail (RTP_IS_SOURCE (src));

  src->callbacks.push_rtp = cb->push_rtp;
  src->callbacks.clock_rate = cb->clock_rate;
  src->user_data = user_data;
}

/**
 * rtp_source_get_ssrc:
 * @src: an #RTPSource
 *
 * Get the SSRC of @source.
 *
 * Returns: the SSRC of src.
 */
guint32
rtp_source_get_ssrc (RTPSource * src)
{
  guint32 result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), 0);

  result = src->ssrc;

  return result;
}

/**
 * rtp_source_set_as_csrc:
 * @src: an #RTPSource
 *
 * Configure @src as a CSRC, this will also validate @src.
 */
void
rtp_source_set_as_csrc (RTPSource * src)
{
  g_return_if_fail (RTP_IS_SOURCE (src));

  src->validated = TRUE;
  src->is_csrc = TRUE;
}

/**
 * rtp_source_is_as_csrc:
 * @src: an #RTPSource
 *
 * Check if @src is a contributing source.
 *
 * Returns: %TRUE if @src is acting as a contributing source.
 */
gboolean
rtp_source_is_as_csrc (RTPSource * src)
{
  gboolean result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  result = src->is_csrc;

  return result;
}

/**
 * rtp_source_is_active:
 * @src: an #RTPSource
 *
 * Check if @src is an active source. A source is active if it has been
 * validated and has not yet received a BYE packet
 *
 * Returns: %TRUE if @src is an qactive source.
 */
gboolean
rtp_source_is_active (RTPSource * src)
{
  gboolean result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  result = RTP_SOURCE_IS_ACTIVE (src);

  return result;
}

/**
 * rtp_source_is_validated:
 * @src: an #RTPSource
 *
 * Check if @src is a validated source.
 *
 * Returns: %TRUE if @src is a validated source.
 */
gboolean
rtp_source_is_validated (RTPSource * src)
{
  gboolean result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  result = src->validated;

  return result;
}

/**
 * rtp_source_is_sender:
 * @src: an #RTPSource
 *
 * Check if @src is a sending source.
 *
 * Returns: %TRUE if @src is a sending source.
 */
gboolean
rtp_source_is_sender (RTPSource * src)
{
  gboolean result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  result = RTP_SOURCE_IS_SENDER (src);

  return result;
}

/**
 * rtp_source_received_bye:
 * @src: an #RTPSource
 *
 * Check if @src has receoved a BYE packet.
 *
 * Returns: %TRUE if @src has received a BYE packet.
 */
gboolean
rtp_source_received_bye (RTPSource * src)
{
  gboolean result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  result = src->received_bye;

  return result;
}


/**
 * rtp_source_get_bye_reason:
 * @src: an #RTPSource
 *
 * Get the BYE reason for @src. Check if the source receoved a BYE message first
 * with rtp_source_received_bye().
 *
 * Returns: The BYE reason or NULL when no reason was given or the source did
 * not receive a BYE message yet. g_fee() after usage.
 */
gchar *
rtp_source_get_bye_reason (RTPSource * src)
{
  gchar *result;

  g_return_val_if_fail (RTP_IS_SOURCE (src), NULL);

  result = g_strdup (src->bye_reason);

  return result;
}

/**
 * rtp_source_update_caps:
 * @src: an #RTPSource
 * @caps: a #GstCaps
 *
 * Parse @caps and store all relevant information in @source.
 */
void
rtp_source_update_caps (RTPSource * src, GstCaps * caps)
{
  GstStructure *s;
  guint val;
  gint ival;

  /* nothing changed, return */
  if (caps == NULL || src->caps == caps)
    return;

  s = gst_caps_get_structure (caps, 0);

  if (gst_structure_get_int (s, "payload", &ival))
    src->payload = ival;
  else
    src->payload = -1;
  GST_DEBUG ("got payload %d", src->payload);

  if (gst_structure_get_int (s, "clock-rate", &ival))
    src->clock_rate = ival;
  else
    src->clock_rate = -1;

  GST_DEBUG ("got clock-rate %d", src->clock_rate);

  if (gst_structure_get_uint (s, "seqnum-base", &val))
    src->seqnum_base = val;
  else
    src->seqnum_base = -1;

  GST_DEBUG ("got seqnum-base %" G_GINT32_FORMAT, src->seqnum_base);

  gst_caps_replace (&src->caps, caps);
}

/**
 * rtp_source_set_sdes_string:
 * @src: an #RTPSource
 * @type: the type of the SDES item
 * @data: the SDES data
 *
 * Store an SDES item of @type in @src.
 *
 * Returns: %FALSE if the SDES item was unchanged or @type is unknown.
 */
gboolean
rtp_source_set_sdes_string (RTPSource * src, GstRTCPSDESType type,
    const gchar * data)
{
  const gchar *old;
  const gchar *field;

  field = gst_rtcp_sdes_type_to_name (type);

  if (gst_structure_has_field (src->sdes, field))
    old = gst_structure_get_string (src->sdes, field);
  else
    old = NULL;

  if (old == NULL && data == NULL)
    return FALSE;

  if (old != NULL && data != NULL && strcmp (old, data) == 0)
    return FALSE;

  if (data == NULL)
    gst_structure_remove_field (src->sdes, field);
  else
    gst_structure_set (src->sdes, field, G_TYPE_STRING, data, NULL);

  return TRUE;
}

/**
 * rtp_source_get_sdes_string:
 * @src: an #RTPSource
 * @type: the type of the SDES item
 *
 * Get the SDES item of @type from @src.
 *
 * Returns: a null-terminated copy of the SDES item or NULL when @type was not
 * valid or the SDES item was unset. g_free() after usage.
 */
gchar *
rtp_source_get_sdes_string (RTPSource * src, GstRTCPSDESType type)
{
  gchar *result;
  const gchar *type_name;

  g_return_val_if_fail (RTP_IS_SOURCE (src), NULL);

  if (type < 0 || type > GST_RTCP_SDES_PRIV - 1)
    return NULL;

  type_name = gst_rtcp_sdes_type_to_name (type);

  if (!gst_structure_has_field (src->sdes, type_name))
    return NULL;

  result = g_strdup (gst_structure_get_string (src->sdes, type_name));

  return result;
}

/**
 * rtp_source_set_rtp_from:
 * @src: an #RTPSource
 * @address: the RTP address to set
 *
 * Set that @src is receiving RTP packets from @address. This is used for
 * collistion checking.
 */
void
rtp_source_set_rtp_from (RTPSource * src, GSocketAddress * address)
{
  g_return_if_fail (RTP_IS_SOURCE (src));

  if (src->rtp_from)
    g_object_unref (src->rtp_from);
  src->rtp_from = G_SOCKET_ADDRESS (g_object_ref (address));
}

/**
 * rtp_source_set_rtcp_from:
 * @src: an #RTPSource
 * @address: the RTCP address to set
 *
 * Set that @src is receiving RTCP packets from @address. This is used for
 * collistion checking.
 */
void
rtp_source_set_rtcp_from (RTPSource * src, GSocketAddress * address)
{
  g_return_if_fail (RTP_IS_SOURCE (src));

  if (src->rtcp_from)
    g_object_unref (src->rtcp_from);
  src->rtcp_from = G_SOCKET_ADDRESS (g_object_ref (address));
}

static GstFlowReturn
push_packet (RTPSource * src, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;

  /* push queued packets first if any */
  while (!g_queue_is_empty (src->packets)) {
    GstBuffer *buffer = GST_BUFFER_CAST (g_queue_pop_head (src->packets));

    GST_LOG ("pushing queued packet");
    if (src->callbacks.push_rtp)
      src->callbacks.push_rtp (src, buffer, src->user_data);
    else
      gst_buffer_unref (buffer);
  }
  GST_LOG ("pushing new packet");
  /* push packet */
  if (src->callbacks.push_rtp)
    ret = src->callbacks.push_rtp (src, buffer, src->user_data);
  else
    gst_buffer_unref (buffer);

  return ret;
}

static gint
get_clock_rate (RTPSource * src, guint8 payload)
{
  if (src->payload == -1) {
    /* first payload received, nothing was in the caps, lock on to this payload */
    src->payload = payload;
    GST_DEBUG ("first payload %d", payload);
  } else if (payload != src->payload) {
    /* we have a different payload than before, reset the clock-rate */
    GST_DEBUG ("new payload %d", payload);
    src->payload = payload;
    src->clock_rate = -1;
    src->stats.transit = -1;
  }

  if (src->clock_rate == -1) {
    gint clock_rate = -1;

    if (src->callbacks.clock_rate)
      clock_rate = src->callbacks.clock_rate (src, payload, src->user_data);

    GST_DEBUG ("got clock-rate %d", clock_rate);

    src->clock_rate = clock_rate;
  }
  return src->clock_rate;
}

/* Jitter is the variation in the delay of received packets in a flow. It is
 * measured by comparing the interval when RTP packets were sent to the interval
 * at which they were received. For instance, if packet #1 and packet #2 leave
 * 50 milliseconds apart and arrive 60 milliseconds apart, then the jitter is 10
 * milliseconds. */
static void
calculate_jitter (RTPSource * src, GstBuffer * buffer,
    RTPArrivalStats * arrival)
{
  GstClockTime running_time;
  guint32 rtparrival, transit, rtptime;
  gint32 diff;
  gint clock_rate;
  guint8 pt;
  GstRTPBuffer rtp = { NULL };

  /* get arrival time */
  if ((running_time = arrival->running_time) == GST_CLOCK_TIME_NONE)
    goto no_time;

  if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp))
    goto invalid_packet;

  pt = gst_rtp_buffer_get_payload_type (&rtp);

  GST_LOG ("SSRC %08x got payload %d", src->ssrc, pt);

  /* get clockrate */
  if ((clock_rate = get_clock_rate (src, pt)) == -1) {
    gst_rtp_buffer_unmap (&rtp);
    goto no_clock_rate;
  }

  rtptime = gst_rtp_buffer_get_timestamp (&rtp);

  /* convert arrival time to RTP timestamp units, truncate to 32 bits, we don't
   * care about the absolute value, just the difference. */
  rtparrival = gst_util_uint64_scale_int (running_time, clock_rate, GST_SECOND);

  /* transit time is difference with RTP timestamp */
  transit = rtparrival - rtptime;

  /* get ABS diff with previous transit time */
  if (src->stats.transit != -1) {
    if (transit > src->stats.transit)
      diff = transit - src->stats.transit;
    else
      diff = src->stats.transit - transit;
  } else
    diff = 0;

  src->stats.transit = transit;

  /* update jitter, the value we store is scaled up so we can keep precision. */
  src->stats.jitter += diff - ((src->stats.jitter + 8) >> 4);

  src->stats.prev_rtptime = src->stats.last_rtptime;
  src->stats.last_rtptime = rtparrival;

  GST_LOG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %f",
      rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0);

  gst_rtp_buffer_unmap (&rtp);
  return;

  /* ERRORS */
no_time:
  {
    GST_WARNING ("cannot get current running_time");
    return;
  }
invalid_packet:
  {
    GST_WARNING ("invalid RTP packet");
    return;
  }
no_clock_rate:
  {
    GST_WARNING ("cannot get clock-rate for pt %d", pt);
    return;
  }
}

static void
init_seq (RTPSource * src, guint16 seq)
{
  src->stats.base_seq = seq;
  src->stats.max_seq = seq;
  src->stats.bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
  src->stats.cycles = 0;
  src->stats.packets_received = 0;
  src->stats.octets_received = 0;
  src->stats.bytes_received = 0;
  src->stats.prev_received = 0;
  src->stats.prev_expected = 0;

  GST_DEBUG ("base_seq %d", seq);
}

#define BITRATE_INTERVAL (2 * GST_SECOND)

static void
do_bitrate_estimation (RTPSource * src, GstClockTime running_time,
    guint64 * bytes_handled)
{
  guint64 elapsed;

  if (src->prev_rtime) {
    elapsed = running_time - src->prev_rtime;

    if (elapsed > BITRATE_INTERVAL) {
      guint64 rate;

      rate = gst_util_uint64_scale (*bytes_handled, 8 * GST_SECOND, elapsed);

      GST_LOG ("Elapsed %" G_GUINT64_FORMAT ", bytes %" G_GUINT64_FORMAT
          ", rate %" G_GUINT64_FORMAT, elapsed, *bytes_handled, rate);

      if (src->bitrate == 0)
        src->bitrate = rate;
      else
        src->bitrate = ((src->bitrate * 3) + rate) / 4;

      src->prev_rtime = running_time;
      *bytes_handled = 0;
    }
  } else {
    GST_LOG ("Reset bitrate measurement");
    src->prev_rtime = running_time;
    src->bitrate = 0;
  }
}

/**
 * rtp_source_process_rtp:
 * @src: an #RTPSource
 * @buffer: an RTP buffer
 *
 * Let @src handle the incomming RTP @buffer.
 *
 * Returns: a #GstFlowReturn.
 */
GstFlowReturn
rtp_source_process_rtp (RTPSource * src, GstBuffer * buffer,
    RTPArrivalStats * arrival)
{
  GstFlowReturn result = GST_FLOW_OK;
  guint16 seqnr, udelta;
  RTPSourceStats *stats;
  guint16 expected;
  GstRTPBuffer rtp = { NULL };

  g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
  g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);

  stats = &src->stats;

  if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp))
    goto invalid_packet;

  seqnr = gst_rtp_buffer_get_seq (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  if (stats->cycles == -1) {
    GST_DEBUG ("received first buffer");
    /* first time we heard of this source */
    init_seq (src, seqnr);
    src->stats.max_seq = seqnr - 1;
    src->curr_probation = src->probation;
  }

  udelta = seqnr - stats->max_seq;

  /* if we are still on probation, check seqnum */
  if (src->curr_probation) {
    expected = src->stats.max_seq + 1;

    /* when in probation, we require consecutive seqnums */
    if (seqnr == expected) {
      /* expected packet */
      GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected);
      src->curr_probation--;
      src->stats.max_seq = seqnr;
      if (src->curr_probation == 0) {
        GST_DEBUG ("probation done!");
        init_seq (src, seqnr);
      } else {
        GstBuffer *q;

        GST_DEBUG ("probation %d: queue buffer", src->curr_probation);
        /* when still in probation, keep packets in a list. */
        g_queue_push_tail (src->packets, buffer);
        /* remove packets from queue if there are too many */
        while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) {
          q = g_queue_pop_head (src->packets);
          gst_buffer_unref (q);
        }
        goto done;
      }
    } else {
      /* unexpected seqnum in probation */
      goto probation_seqnum;
    }
  } else if (udelta < RTP_MAX_DROPOUT) {
    /* in order, with permissible gap */
    if (seqnr < stats->max_seq) {
      /* sequence number wrapped - count another 64K cycle. */
      stats->cycles += RTP_SEQ_MOD;
    }
    stats->max_seq = seqnr;
  } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
    /* the sequence number made a very large jump */
    if (seqnr == stats->bad_seq) {
      /* two sequential packets -- assume that the other side
       * restarted without telling us so just re-sync
       * (i.e., pretend this was the first packet).  */
      init_seq (src, seqnr);
    } else {
      /* unacceptable jump */
      stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1);
      goto bad_sequence;
    }
  } else {
    /* duplicate or reordered packet, will be filtered by jitterbuffer. */
    GST_WARNING ("duplicate or reordered packet (seqnr %d)", seqnr);
  }

  src->stats.octets_received += arrival->payload_len;
  src->stats.bytes_received += arrival->bytes;
  src->stats.packets_received++;
  /* for the bitrate estimation */
  src->bytes_received += arrival->payload_len;
  /* the source that sent the packet must be a sender */
  src->is_sender = TRUE;
  src->validated = TRUE;

  do_bitrate_estimation (src, arrival->running_time, &src->bytes_received);

  GST_LOG ("seq %d, PC: %" G_GUINT64_FORMAT ", OC: %" G_GUINT64_FORMAT,
      seqnr, src->stats.packets_received, src->stats.octets_received);

  /* calculate jitter for the stats */
  calculate_jitter (src, buffer, arrival);

  /* we're ready to push the RTP packet now */
  result = push_packet (src, buffer);

done:
  return result;

  /* ERRORS */
invalid_packet:
  {
    GST_WARNING ("invalid packet received");
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
bad_sequence:
  {
    GST_WARNING ("unacceptable seqnum received");
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
probation_seqnum:
  {
    GST_WARNING ("probation: seqnr %d != expected %d", seqnr, expected);
    src->curr_probation = src->probation;
    src->stats.max_seq = seqnr;
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
}

/**
 * rtp_source_process_bye:
 * @src: an #RTPSource
 * @reason: the reason for leaving
 *
 * Notify @src that a BYE packet has been received. This will make the source
 * inactive.
 */
void
rtp_source_process_bye (RTPSource * src, const gchar * reason)
{
  g_return_if_fail (RTP_IS_SOURCE (src));

  GST_DEBUG ("marking SSRC %08x as BYE, reason: %s", src->ssrc,
      GST_STR_NULL (reason));

  /* copy the reason and mark as received_bye */
  g_free (src->bye_reason);
  src->bye_reason = g_strdup (reason);
  src->received_bye = TRUE;
}

static gboolean
set_ssrc (GstBuffer ** buffer, guint idx, RTPSource * src)
{
  GstRTPBuffer rtp = { NULL };

  *buffer = gst_buffer_make_writable (*buffer);
  if (gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp)) {
    gst_rtp_buffer_set_ssrc (&rtp, src->ssrc);
    gst_rtp_buffer_unmap (&rtp);
  }
  return TRUE;
}

/**
 * rtp_source_send_rtp:
 * @src: an #RTPSource
 * @data: an RTP buffer or a list of RTP buffers
 * @is_list: if @data is a buffer or list
 * @running_time: the running time of @data
 *
 * Send @data (an RTP buffer or list of buffers) originating from @src.
 * This will make @src a sender. This function takes ownership of @data and
 * modifies the SSRC in the RTP packet to that of @src when needed.
 *
 * Returns: a #GstFlowReturn.
 */
GstFlowReturn
rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list,
    GstClockTime running_time)
{
  GstFlowReturn result;
  guint len;
  guint32 rtptime;
  guint64 ext_rtptime;
  guint64 rt_diff, rtp_diff;
  GstBufferList *list = NULL;
  GstBuffer *buffer = NULL;
  guint packets;
  guint32 ssrc;
  GstRTPBuffer rtp = { NULL };

  g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
  g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR);

  if (is_list) {
    list = GST_BUFFER_LIST_CAST (data);

    /* We can grab the caps from the first group, since all
     * groups of a buffer list have same caps. */
    buffer = gst_buffer_list_get (list, 0);
    if (!buffer)
      goto no_buffer;
  } else {
    buffer = GST_BUFFER_CAST (data);
  }

  /* we are a sender now */
  src->is_sender = TRUE;

  if (is_list) {
    gint i;

    /* Each group makes up a network packet. */
    packets = gst_buffer_list_length (list);
    for (i = 0, len = 0; i < packets; i++) {
      if (!gst_rtp_buffer_map (gst_buffer_list_get (list, i), GST_MAP_READ,
              &rtp))
        goto invalid_packet;

      len += gst_rtp_buffer_get_payload_len (&rtp);
      gst_rtp_buffer_unmap (&rtp);
    }
    /* subsequent info taken from first list member */
    gst_rtp_buffer_map (gst_buffer_list_get (list, 0), GST_MAP_READ, &rtp);
  } else {
    packets = 1;
    if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp))
      goto invalid_packet;

    len = gst_rtp_buffer_get_payload_len (&rtp);
  }

  /* update stats for the SR */
  src->stats.packets_sent += packets;
  src->stats.octets_sent += len;
  src->bytes_sent += len;

  do_bitrate_estimation (src, running_time, &src->bytes_sent);

  rtptime = gst_rtp_buffer_get_timestamp (&rtp);
  ext_rtptime = src->last_rtptime;
  ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);

  GST_LOG ("SSRC %08x, RTP %" G_GUINT64_FORMAT ", running_time %"
      GST_TIME_FORMAT, src->ssrc, ext_rtptime, GST_TIME_ARGS (running_time));

  if (ext_rtptime > src->last_rtptime) {
    rtp_diff = ext_rtptime - src->last_rtptime;
    rt_diff = running_time - src->last_rtime;

    /* calc the diff so we can detect drift at the sender. This can also be used
     * to guestimate the clock rate if the NTP time is locked to the RTP
     * timestamps (as is the case when the capture device is providing the clock). */
    GST_LOG ("SSRC %08x, diff RTP %" G_GUINT64_FORMAT ", diff running_time %"
        GST_TIME_FORMAT, src->ssrc, rtp_diff, GST_TIME_ARGS (rt_diff));
  }

  /* we keep track of the last received RTP timestamp and the corresponding
   * buffer running_time so that we can use this info when constructing SR reports */
  src->last_rtime = running_time;
  src->last_rtptime = ext_rtptime;

  /* push packet */
  if (!src->callbacks.push_rtp) {
    gst_rtp_buffer_unmap (&rtp);
    goto no_callback;
  }

  ssrc = gst_rtp_buffer_get_ssrc (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  if (ssrc != src->ssrc) {
    /* the SSRC of the packet is not correct, make a writable buffer and
     * update the SSRC. This could involve a complete copy of the packet when
     * it is not writable. Usually the payloader will use caps negotiation to
     * get the correct SSRC from the session manager before pushing anything. */

    /* FIXME, we don't want to warn yet because we can't inform any payloader
     * of the changes SSRC yet because we don't implement pad-alloc. */
    GST_LOG ("updating SSRC from %08x to %08x, fix the payloader", ssrc,
        src->ssrc);

    if (is_list) {
      list = gst_buffer_list_make_writable (list);
      gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc, src);
    } else {
      set_ssrc (&buffer, 0, src);
    }
  }
  GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT, is_list ? "list" : "packet",
      src->stats.packets_sent);

  result = src->callbacks.push_rtp (src, data, src->user_data);

  return result;

  /* ERRORS */
invalid_packet:
  {
    GST_WARNING ("invalid packet received");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
    return GST_FLOW_OK;
  }
no_buffer:
  {
    GST_WARNING ("no buffers in buffer list");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
    return GST_FLOW_OK;
  }
no_callback:
  {
    GST_WARNING ("no callback installed, dropping packet");
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
    return GST_FLOW_OK;
  }
}

/**
 * rtp_source_process_sr:
 * @src: an #RTPSource
 * @time: time of packet arrival
 * @ntptime: the NTP time in 32.32 fixed point
 * @rtptime: the RTP time
 * @packet_count: the packet count
 * @octet_count: the octect count
 *
 * Update the sender report in @src.
 */
void
rtp_source_process_sr (RTPSource * src, GstClockTime time, guint64 ntptime,
    guint32 rtptime, guint32 packet_count, guint32 octet_count)
{
  RTPSenderReport *curr;
  gint curridx;

  g_return_if_fail (RTP_IS_SOURCE (src));

  GST_DEBUG ("got SR packet: SSRC %08x, NTP %08x:%08x, RTP %" G_GUINT32_FORMAT
      ", PC %" G_GUINT32_FORMAT ", OC %" G_GUINT32_FORMAT, src->ssrc,
      (guint32) (ntptime >> 32), (guint32) (ntptime & 0xffffffff), rtptime,
      packet_count, octet_count);

  curridx = src->stats.curr_sr ^ 1;
  curr = &src->stats.sr[curridx];

  /* this is a sender now */
  src->is_sender = TRUE;

  /* update current */
  curr->is_valid = TRUE;
  curr->ntptime = ntptime;
  curr->rtptime = rtptime;
  curr->packet_count = packet_count;
  curr->octet_count = octet_count;
  curr->time = time;

  /* make current */
  src->stats.curr_sr = curridx;

  src->stats.prev_rtcptime = src->stats.last_rtcptime;
  src->stats.last_rtcptime = time;
}

/**
 * rtp_source_process_rb:
 * @src: an #RTPSource
 * @ntpnstime: the current time in nanoseconds since 1970
 * @fractionlost: fraction lost since last SR/RR
 * @packetslost: the cumululative number of packets lost
 * @exthighestseq: the extended last sequence number received
 * @jitter: the interarrival jitter
 * @lsr: the last SR packet from this source
 * @dlsr: the delay since last SR packet
 *
 * Update the report block in @src.
 */
void
rtp_source_process_rb (RTPSource * src, guint64 ntpnstime,
    guint8 fractionlost, gint32 packetslost, guint32 exthighestseq,
    guint32 jitter, guint32 lsr, guint32 dlsr)
{
  RTPReceiverReport *curr;
  gint curridx;
  guint32 ntp, A;
  guint64 f_ntp;

  g_return_if_fail (RTP_IS_SOURCE (src));

  GST_DEBUG ("got RB packet: SSRC %08x, FL %2x, PL %d, HS %" G_GUINT32_FORMAT
      ", jitter %" G_GUINT32_FORMAT ", LSR %04x:%04x, DLSR %04x:%04x",
      src->ssrc, fractionlost, packetslost, exthighestseq, jitter, lsr >> 16,
      lsr & 0xffff, dlsr >> 16, dlsr & 0xffff);

  curridx = src->stats.curr_rr ^ 1;
  curr = &src->stats.rr[curridx];

  /* update current */
  curr->is_valid = TRUE;
  curr->fractionlost = fractionlost;
  curr->packetslost = packetslost;
  curr->exthighestseq = exthighestseq;
  curr->jitter = jitter;
  curr->lsr = lsr;
  curr->dlsr = dlsr;

  /* convert the NTP time in nanoseconds to 32.32 fixed point */
  f_ntp = gst_util_uint64_scale (ntpnstime, (1LL << 32), GST_SECOND);
  /* calculate round trip, round the time up */
  ntp = ((f_ntp + 0xffff) >> 16) & 0xffffffff;

  A = dlsr + lsr;
  if (A > 0 && ntp > A)
    A = ntp - A;
  else
    A = 0;
  curr->round_trip = A;

  GST_DEBUG ("NTP %04x:%04x, round trip %04x:%04x", ntp >> 16, ntp & 0xffff,
      A >> 16, A & 0xffff);

  /* make current */
  src->stats.curr_rr = curridx;
}

/**
 * rtp_source_get_new_sr:
 * @src: an #RTPSource
 * @ntpnstime: the current time in nanoseconds since 1970
 * @running_time: the current running_time of the pipeline.
 * @ntptime: the NTP time in 32.32 fixed point
 * @rtptime: the RTP time corresponding to @ntptime
 * @packet_count: the packet count
 * @octet_count: the octect count
 *
 * Get new values to put into a new SR report from this source.
 *
 * @running_time and @ntpnstime are captured at the same time and represent the
 * running time of the pipeline clock and the absolute current system time in
 * nanoseconds respectively. Together with the last running_time and rtp timestamp
 * we have observed in the source, we can generate @ntptime and @rtptime for an SR
 * packet. @ntptime is basically the fixed point representation of @ntpnstime
 * and @rtptime the associated RTP timestamp.
 *
 * Returns: %TRUE on success.
 */
gboolean
rtp_source_get_new_sr (RTPSource * src, guint64 ntpnstime,
    GstClockTime running_time, guint64 * ntptime, guint32 * rtptime,
    guint32 * packet_count, guint32 * octet_count)
{
  guint64 t_rtp;
  guint64 t_current_ntp;
  GstClockTimeDiff diff;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  /* We last saw a buffer with last_rtptime at last_rtime. Given a running_time
   * and an NTP time, we can scale the RTP timestamps so that they match the
   * given NTP time.  for scaling, we assume that the slope of the rtptime vs
   * running_time vs ntptime curve is close to 1, which is certainly
   * sufficient for the frequency at which we report SR and the rate we send
   * out RTP packets. */
  t_rtp = src->last_rtptime;

  GST_DEBUG ("last_rtime %" GST_TIME_FORMAT ", last_rtptime %"
      G_GUINT64_FORMAT, GST_TIME_ARGS (src->last_rtime), t_rtp);

  if (src->clock_rate != -1) {
    /* get the diff between the clock running_time and the buffer running_time.
     * This is the elapsed time, as measured against the pipeline clock, between
     * when the rtp timestamp was observed and the current running_time.
     *
     * We need to apply this diff to the RTP timestamp to get the RTP timestamp
     * for the given ntpnstime. */
    diff = GST_CLOCK_DIFF (src->last_rtime, running_time);

    /* now translate the diff to RTP time, handle positive and negative cases.
     * If there is no diff, we already set rtptime correctly above. */
    if (diff > 0) {
      GST_DEBUG ("running_time %" GST_TIME_FORMAT ", diff %" GST_TIME_FORMAT,
          GST_TIME_ARGS (running_time), GST_TIME_ARGS (diff));
      t_rtp += gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND);
    } else {
      diff = -diff;
      GST_DEBUG ("running_time %" GST_TIME_FORMAT ", diff -%" GST_TIME_FORMAT,
          GST_TIME_ARGS (running_time), GST_TIME_ARGS (diff));
      t_rtp -= gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND);
    }
  } else {
    GST_WARNING ("no clock-rate, cannot interpolate rtp time");
  }

  /* convert the NTP time in nanoseconds to 32.32 fixed point */
  t_current_ntp = gst_util_uint64_scale (ntpnstime, (1LL << 32), GST_SECOND);

  GST_DEBUG ("NTP %08x:%08x, RTP %" G_GUINT32_FORMAT,
      (guint32) (t_current_ntp >> 32), (guint32) (t_current_ntp & 0xffffffff),
      (guint32) t_rtp);

  if (ntptime)
    *ntptime = t_current_ntp;
  if (rtptime)
    *rtptime = t_rtp;
  if (packet_count)
    *packet_count = src->stats.packets_sent;
  if (octet_count)
    *octet_count = src->stats.octets_sent;

  return TRUE;
}

/**
 * rtp_source_get_new_rb:
 * @src: an #RTPSource
 * @time: the current time of the system clock
 * @fractionlost: fraction lost since last SR/RR
 * @packetslost: the cumululative number of packets lost
 * @exthighestseq: the extended last sequence number received
 * @jitter: the interarrival jitter
 * @lsr: the last SR packet from this source
 * @dlsr: the delay since last SR packet
 *
 * Get new values to put into a new report block from this source.
 *
 * Returns: %TRUE on success.
 */
gboolean
rtp_source_get_new_rb (RTPSource * src, GstClockTime time,
    guint8 * fractionlost, gint32 * packetslost, guint32 * exthighestseq,
    guint32 * jitter, guint32 * lsr, guint32 * dlsr)
{
  RTPSourceStats *stats;
  guint64 extended_max, expected;
  guint64 expected_interval, received_interval, ntptime;
  gint64 lost, lost_interval;
  guint32 fraction, LSR, DLSR;
  GstClockTime sr_time;

  stats = &src->stats;

  extended_max = stats->cycles + stats->max_seq;
  expected = extended_max - stats->base_seq + 1;

  GST_DEBUG ("ext_max %" G_GUINT64_FORMAT ", expected %" G_GUINT64_FORMAT
      ", received %" G_GUINT64_FORMAT ", base_seq %" G_GUINT32_FORMAT,
      extended_max, expected, stats->packets_received, stats->base_seq);

  lost = expected - stats->packets_received;
  lost = CLAMP (lost, -0x800000, 0x7fffff);

  expected_interval = expected - stats->prev_expected;
  stats->prev_expected = expected;
  received_interval = stats->packets_received - stats->prev_received;
  stats->prev_received = stats->packets_received;

  lost_interval = expected_interval - received_interval;

  if (expected_interval == 0 || lost_interval <= 0)
    fraction = 0;
  else
    fraction = (lost_interval << 8) / expected_interval;

  GST_DEBUG ("add RR for SSRC %08x", src->ssrc);
  /* we scaled the jitter up for additional precision */
  GST_DEBUG ("fraction %" G_GUINT32_FORMAT ", lost %" G_GINT64_FORMAT
      ", extseq %" G_GUINT64_FORMAT ", jitter %d", fraction, lost,
      extended_max, stats->jitter >> 4);

  if (rtp_source_get_last_sr (src, &sr_time, &ntptime, NULL, NULL, NULL)) {
    GstClockTime diff;

    /* LSR is middle 32 bits of the last ntptime */
    LSR = (ntptime >> 16) & 0xffffffff;
    diff = time - sr_time;
    GST_DEBUG ("last SR time diff %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));
    /* DLSR, delay since last SR is expressed in 1/65536 second units */
    DLSR = gst_util_uint64_scale_int (diff, 65536, GST_SECOND);
  } else {
    /* No valid SR received, LSR/DLSR are set to 0 then */
    GST_DEBUG ("no valid SR received");
    LSR = 0;
    DLSR = 0;
  }
  GST_DEBUG ("LSR %04x:%04x, DLSR %04x:%04x", LSR >> 16, LSR & 0xffff,
      DLSR >> 16, DLSR & 0xffff);

  if (fractionlost)
    *fractionlost = fraction;
  if (packetslost)
    *packetslost = lost;
  if (exthighestseq)
    *exthighestseq = extended_max;
  if (jitter)
    *jitter = stats->jitter >> 4;
  if (lsr)
    *lsr = LSR;
  if (dlsr)
    *dlsr = DLSR;

  return TRUE;
}

/**
 * rtp_source_get_last_sr:
 * @src: an #RTPSource
 * @time: time of packet arrival
 * @ntptime: the NTP time in 32.32 fixed point
 * @rtptime: the RTP time
 * @packet_count: the packet count
 * @octet_count: the octect count
 *
 * Get the values of the last sender report as set with rtp_source_process_sr().
 *
 * Returns: %TRUE if there was a valid SR report.
 */
gboolean
rtp_source_get_last_sr (RTPSource * src, GstClockTime * time, guint64 * ntptime,
    guint32 * rtptime, guint32 * packet_count, guint32 * octet_count)
{
  RTPSenderReport *curr;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  curr = &src->stats.sr[src->stats.curr_sr];
  if (!curr->is_valid)
    return FALSE;

  if (ntptime)
    *ntptime = curr->ntptime;
  if (rtptime)
    *rtptime = curr->rtptime;
  if (packet_count)
    *packet_count = curr->packet_count;
  if (octet_count)
    *octet_count = curr->octet_count;
  if (time)
    *time = curr->time;

  return TRUE;
}

/**
 * rtp_source_get_last_rb:
 * @src: an #RTPSource
 * @fractionlost: fraction lost since last SR/RR
 * @packetslost: the cumululative number of packets lost
 * @exthighestseq: the extended last sequence number received
 * @jitter: the interarrival jitter
 * @lsr: the last SR packet from this source
 * @dlsr: the delay since last SR packet
 * @round_trip: the round trip time
 *
 * Get the values of the last RB report set with rtp_source_process_rb().
 *
 * Returns: %TRUE if there was a valid SB report.
 */
gboolean
rtp_source_get_last_rb (RTPSource * src, guint8 * fractionlost,
    gint32 * packetslost, guint32 * exthighestseq, guint32 * jitter,
    guint32 * lsr, guint32 * dlsr, guint32 * round_trip)
{
  RTPReceiverReport *curr;

  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);

  curr = &src->stats.rr[src->stats.curr_rr];
  if (!curr->is_valid)
    return FALSE;

  if (fractionlost)
    *fractionlost = curr->fractionlost;
  if (packetslost)
    *packetslost = curr->packetslost;
  if (exthighestseq)
    *exthighestseq = curr->exthighestseq;
  if (jitter)
    *jitter = curr->jitter;
  if (lsr)
    *lsr = curr->lsr;
  if (dlsr)
    *dlsr = curr->dlsr;
  if (round_trip)
    *round_trip = curr->round_trip;

  return TRUE;
}

/**
 * rtp_source_find_conflicting_address:
 * @src: The source the packet came in
 * @address: address to check for
 * @time: The time when the packet that is possibly in conflict arrived
 *
 * Checks if an address which has a conflict is already known. If it is
 * a known conflict, remember the time
 *
 * Returns: TRUE if it was a known conflict, FALSE otherwise
 */
gboolean
rtp_source_find_conflicting_address (RTPSource * src, GSocketAddress * address,
    GstClockTime time)
{
  GList *item;

  for (item = g_list_first (src->conflicting_addresses);
      item; item = g_list_next (item)) {
    RTPConflictingAddress *known_conflict = item->data;

    if (__g_socket_address_equal (address, known_conflict->address)) {
      known_conflict->time = time;
      return TRUE;
    }
  }

  return FALSE;
}

/**
 * rtp_source_add_conflicting_address:
 * @src: The source the packet came in
 * @address: address to remember
 * @time: The time when the packet that is in conflict arrived
 *
 * Adds a new conflict address
 */
void
rtp_source_add_conflicting_address (RTPSource * src,
    GSocketAddress * address, GstClockTime time)
{
  RTPConflictingAddress *new_conflict;

  new_conflict = g_new0 (RTPConflictingAddress, 1);

  new_conflict->address = G_SOCKET_ADDRESS (g_object_ref (address));
  new_conflict->time = time;

  src->conflicting_addresses = g_list_prepend (src->conflicting_addresses,
      new_conflict);
}

/**
 * rtp_source_timeout:
 * @src: The #RTPSource
 * @current_time: The current time
 * @collision_timeout: The amount of time after which a collision is timed out
 * @feedback_retention_window: The running time before which retained feedback
 * packets have to be discarded
 *
 * This is processed on each RTCP interval. It times out old collisions.
 * It also times out old retained feedback packets
 */
void
rtp_source_timeout (RTPSource * src, GstClockTime current_time,
    GstClockTime collision_timeout, GstClockTime feedback_retention_window)
{
  GList *item;
  GstRTCPPacket *pkt;

  item = g_list_first (src->conflicting_addresses);
  while (item) {
    RTPConflictingAddress *known_conflict = item->data;
    GList *next_item = g_list_next (item);

    if (known_conflict->time < current_time - collision_timeout) {
      gchar *buf;

      src->conflicting_addresses =
          g_list_delete_link (src->conflicting_addresses, item);
      buf = __g_socket_address_to_string (known_conflict->address);
      GST_DEBUG ("collision %p timed out: %s", known_conflict, buf);
      g_free (buf);
      g_object_unref (known_conflict->address);
      g_free (known_conflict);
    }
    item = next_item;
  }

  /* Time out AVPF packets that are older than the desired length */
  while ((pkt = g_queue_peek_tail (src->retained_feedback)) &&
      GST_BUFFER_TIMESTAMP (pkt) < feedback_retention_window)
    gst_buffer_unref (g_queue_pop_tail (src->retained_feedback));
}

static gint
compare_buffers (gconstpointer a, gconstpointer b, gpointer user_data)
{
  const GstBuffer *bufa = a;
  const GstBuffer *bufb = b;

  return GST_BUFFER_TIMESTAMP (bufa) - GST_BUFFER_TIMESTAMP (bufb);
}

void
rtp_source_retain_rtcp_packet (RTPSource * src, GstRTCPPacket * packet,
    GstClockTime running_time)
{
  GstBuffer *buffer;

  buffer = gst_buffer_copy_region (packet->rtcp->buffer, GST_BUFFER_COPY_MEMORY,
      packet->offset, (gst_rtcp_packet_get_length (packet) + 1) * 4);

  GST_BUFFER_TIMESTAMP (buffer) = running_time;

  g_queue_insert_sorted (src->retained_feedback, buffer, compare_buffers, NULL);
}

gboolean
rtp_source_has_retained (RTPSource * src, GCompareFunc func, gconstpointer data)
{
  if (g_queue_find_custom (src->retained_feedback, data, func))
    return TRUE;
  else
    return FALSE;
}
