/*
 * Farsight Voice+Video library
 *
 *  Copyright 2007 Collabora Ltd,
 *  Copyright 2007 Nokia Corporation
 *   @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>.
 *  Copyright 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.
 *
 */

/**
 * SECTION:element-rtpjitterbuffer
 *
 * This element reorders and removes duplicate RTP packets as they are received
 * from a network source.
 *
 * The element needs the clock-rate of the RTP payload in order to estimate the
 * delay. This information is obtained either from the caps on the sink pad or,
 * when no caps are present, from the #GstRtpJitterBuffer::request-pt-map signal.
 * To clear the previous pt-map use the #GstRtpJitterBuffer::clear-pt-map signal.
 *
 * The rtpjitterbuffer will wait for missing packets up to a configurable time
 * limit using the #GstRtpJitterBuffer:latency property. Packets arriving too
 * late are considered to be lost packets. If the #GstRtpJitterBuffer:do-lost
 * property is set, lost packets will result in a custom serialized downstream
 * event of name GstRTPPacketLost. The lost packet events are usually used by a
 * depayloader or other element to create concealment data or some other logic
 * to gracefully handle the missing packets.
 *
 * The jitterbuffer will use the DTS (or PTS if no DTS is set) of the incomming
 * buffer and the rtptime inside the RTP packet to create a PTS on the outgoing
 * buffer.
 *
 * The jitterbuffer can also be configured to send early retransmission events
 * upstream by setting the #GstRtpJitterBuffer:do-retransmission property. In
 * this mode, the jitterbuffer tries to estimate when a packet should arrive and
 * sends a custom upstream event named GstRTPRetransmissionRequest when the
 * packet is considered late. The initial expected packet arrival time is
 * calculated as follows:
 *
 * - If seqnum N arrived at time T, seqnum N+1 is expected to arrive at
 *     T + packet-spacing + #GstRtpJitterBuffer:rtx-delay. The packet spacing is
 *     calculated from the DTS (or PTS is no DTS) of two consecutive RTP
 *     packets with different rtptime.
 *
 * - If seqnum N0 arrived at time T0 and seqnum Nm arrived at time Tm,
 *     seqnum Ni is expected at time Ti = T0 + i*(Tm - T0)/(Nm - N0). Any
 *     previously scheduled timeout is overwritten.
 *
 * - If seqnum N arrived, all seqnum older than
 *     N - #GstRtpJitterBuffer:rtx-delay-reorder are considered late
 *     immediately. This is to request fast feedback for abonormally reorder
 *     packets before any of the previous timeouts is triggered.
 *
 * A late packet triggers the GstRTPRetransmissionRequest custom upstream
 * event. After the initial timeout expires and the retransmission event is
 * sent, the timeout is scheduled for
 * T + #GstRtpJitterBuffer:rtx-retry-timeout. If the missing packet did not
 * arrive after #GstRtpJitterBuffer:rtx-retry-timeout, a new
 * GstRTPRetransmissionRequest is sent upstream and the timeout is rescheduled
 * again for T + #GstRtpJitterBuffer:rtx-retry-timeout. This repeats until
 * #GstRtpJitterBuffer:rtx-retry-period elapsed, at which point no further
 * retransmission requests are sent and the regular logic is performed to
 * schedule a lost packet as discussed above.
 *
 * This element acts as a live element and so adds #GstRtpJitterBuffer:latency
 * to the pipeline.
 *
 * This element will automatically be used inside rtpbin.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 rtspsrc location=rtsp://192.168.1.133:8554/mpeg1or2AudioVideoTest ! rtpjitterbuffer ! rtpmpvdepay ! mpeg2dec ! xvimagesink
 * ]| Connect to a streaming server and decode the MPEG video. The jitterbuffer is
 * inserted into the pipeline to smooth out network jitter and to reorder the
 * out-of-order RTP packets.
 * </refsect2>
 */

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

#include <stdlib.h>
#include <string.h>
#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtpjitterbuffer.h"
#include "rtpjitterbuffer.h"
#include "rtpstats.h"

#include <gst/glib-compat-private.h>

GST_DEBUG_CATEGORY (rtpjitterbuffer_debug);
#define GST_CAT_DEFAULT (rtpjitterbuffer_debug)

/* RTPJitterBuffer signals and args */
enum
{
  SIGNAL_REQUEST_PT_MAP,
  SIGNAL_CLEAR_PT_MAP,
  SIGNAL_HANDLE_SYNC,
  SIGNAL_ON_NPT_STOP,
  SIGNAL_SET_ACTIVE,
  LAST_SIGNAL
};

#define DEFAULT_LATENCY_MS          200
#define DEFAULT_DROP_ON_LATENCY     FALSE
#define DEFAULT_TS_OFFSET           0
#define DEFAULT_DO_LOST             FALSE
#define DEFAULT_MODE                RTP_JITTER_BUFFER_MODE_SLAVE
#define DEFAULT_PERCENT             0
#define DEFAULT_DO_RETRANSMISSION   FALSE
#define DEFAULT_RTX_NEXT_SEQNUM     TRUE
#define DEFAULT_RTX_DELAY           -1
#define DEFAULT_RTX_MIN_DELAY       0
#define DEFAULT_RTX_DELAY_REORDER   3
#define DEFAULT_RTX_RETRY_TIMEOUT   -1
#define DEFAULT_RTX_MIN_RETRY_TIMEOUT   -1
#define DEFAULT_RTX_RETRY_PERIOD    -1
#define DEFAULT_RTX_MAX_RETRIES    -1

#define DEFAULT_AUTO_RTX_DELAY (20 * GST_MSECOND)
#define DEFAULT_AUTO_RTX_TIMEOUT (40 * GST_MSECOND)

enum
{
  PROP_0,
  PROP_LATENCY,
  PROP_DROP_ON_LATENCY,
  PROP_TS_OFFSET,
  PROP_DO_LOST,
  PROP_MODE,
  PROP_PERCENT,
  PROP_DO_RETRANSMISSION,
  PROP_RTX_NEXT_SEQNUM,
  PROP_RTX_DELAY,
  PROP_RTX_MIN_DELAY,
  PROP_RTX_DELAY_REORDER,
  PROP_RTX_RETRY_TIMEOUT,
  PROP_RTX_MIN_RETRY_TIMEOUT,
  PROP_RTX_RETRY_PERIOD,
  PROP_RTX_MAX_RETRIES,
  PROP_STATS
};

#define JBUF_LOCK(priv)   (g_mutex_lock (&(priv)->jbuf_lock))

#define JBUF_LOCK_CHECK(priv,label) G_STMT_START {    \
  JBUF_LOCK (priv);                                   \
  if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK))    \
    goto label;                                       \
} G_STMT_END
#define JBUF_UNLOCK(priv) (g_mutex_unlock (&(priv)->jbuf_lock))

#define JBUF_WAIT_TIMER(priv)   G_STMT_START {            \
  GST_DEBUG ("waiting timer");                            \
  (priv)->waiting_timer = TRUE;                           \
  g_cond_wait (&(priv)->jbuf_timer, &(priv)->jbuf_lock);  \
  (priv)->waiting_timer = FALSE;                          \
  GST_DEBUG ("waiting timer done");                       \
} G_STMT_END
#define JBUF_SIGNAL_TIMER(priv) G_STMT_START {            \
  if (G_UNLIKELY ((priv)->waiting_timer)) {               \
    GST_DEBUG ("signal timer");                           \
    g_cond_signal (&(priv)->jbuf_timer);                  \
  }                                                       \
} G_STMT_END

#define JBUF_WAIT_EVENT(priv,label) G_STMT_START {       \
  GST_DEBUG ("waiting event");                           \
  (priv)->waiting_event = TRUE;                          \
  g_cond_wait (&(priv)->jbuf_event, &(priv)->jbuf_lock); \
  (priv)->waiting_event = FALSE;                         \
  GST_DEBUG ("waiting event done");                      \
  if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK))       \
    goto label;                                          \
} G_STMT_END
#define JBUF_SIGNAL_EVENT(priv) G_STMT_START {           \
  if (G_UNLIKELY ((priv)->waiting_event)) {              \
    GST_DEBUG ("signal event");                          \
    g_cond_signal (&(priv)->jbuf_event);                 \
  }                                                      \
} G_STMT_END

#define JBUF_WAIT_QUERY(priv,label) G_STMT_START {       \
  GST_DEBUG ("waiting query");                           \
  (priv)->waiting_query = TRUE;                          \
  g_cond_wait (&(priv)->jbuf_query, &(priv)->jbuf_lock); \
  (priv)->waiting_query = FALSE;                         \
  GST_DEBUG ("waiting query done");                      \
  if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK))       \
    goto label;                                          \
} G_STMT_END
#define JBUF_SIGNAL_QUERY(priv,res) G_STMT_START {       \
  (priv)->last_query = res;                              \
  if (G_UNLIKELY ((priv)->waiting_query)) {              \
    GST_DEBUG ("signal query");                          \
    g_cond_signal (&(priv)->jbuf_query);                 \
  }                                                      \
} G_STMT_END


struct _GstRtpJitterBufferPrivate
{
  GstPad *sinkpad, *srcpad;
  GstPad *rtcpsinkpad;

  RTPJitterBuffer *jbuf;
  GMutex jbuf_lock;
  gboolean waiting_timer;
  GCond jbuf_timer;
  gboolean waiting_event;
  GCond jbuf_event;
  gboolean waiting_query;
  GCond jbuf_query;
  gboolean last_query;
  gboolean discont;
  gboolean ts_discont;
  gboolean active;
  guint64 out_offset;

  gboolean timer_running;
  GThread *timer_thread;

  /* properties */
  guint latency_ms;
  guint64 latency_ns;
  gboolean drop_on_latency;
  gint64 ts_offset;
  gboolean do_lost;
  gboolean do_retransmission;
  gboolean rtx_next_seqnum;
  gint rtx_delay;
  guint rtx_min_delay;
  gint rtx_delay_reorder;
  gint rtx_retry_timeout;
  gint rtx_min_retry_timeout;
  gint rtx_retry_period;
  gint rtx_max_retries;

  /* the last seqnum we pushed out */
  guint32 last_popped_seqnum;
  /* the next expected seqnum we push */
  guint32 next_seqnum;
  /* seqnum-base, if known */
  guint32 seqnum_base;
  /* last output time */
  GstClockTime last_out_time;
  /* last valid input timestamp and rtptime pair */
  GstClockTime ips_dts;
  guint64 ips_rtptime;
  GstClockTime packet_spacing;

  GQueue gap_packets;

  /* the next expected seqnum we receive */
  GstClockTime last_in_dts;
  guint32 last_in_seqnum;
  guint32 next_in_seqnum;

  GArray *timers;

  /* start and stop ranges */
  GstClockTime npt_start;
  GstClockTime npt_stop;
  guint64 ext_timestamp;
  guint64 last_elapsed;
  guint64 estimated_eos;
  GstClockID eos_id;

  /* state */
  gboolean eos;
  guint last_percent;

  /* clock rate and rtp timestamp offset */
  gint last_pt;
  gint32 clock_rate;
  gint64 clock_base;
  gint64 prev_ts_offset;

  /* when we are shutting down */
  GstFlowReturn srcresult;
  gboolean blocked;

  /* for sync */
  GstSegment segment;
  GstClockID clock_id;
  GstClockTime timer_timeout;
  guint16 timer_seqnum;
  /* the latency of the upstream peer, we have to take this into account when
   * synchronizing the buffers. */
  GstClockTime peer_latency;
  guint64 ext_rtptime;
  GstBuffer *last_sr;

  /* some accounting */
  guint64 num_late;
  guint64 num_duplicates;
  guint64 num_rtx_requests;
  guint64 num_rtx_success;
  guint64 num_rtx_failed;
  gdouble avg_rtx_num;
  guint64 avg_rtx_rtt;

  /* for the jitter */
  GstClockTime last_dts;
  guint64 last_rtptime;
  GstClockTime avg_jitter;
};

typedef enum
{
  TIMER_TYPE_EXPECTED,
  TIMER_TYPE_LOST,
  TIMER_TYPE_DEADLINE,
  TIMER_TYPE_EOS
} TimerType;

typedef struct
{
  guint idx;
  guint16 seqnum;
  guint num;
  TimerType type;
  GstClockTime timeout;
  GstClockTime duration;
  GstClockTime rtx_base;
  GstClockTime rtx_delay;
  GstClockTime rtx_retry;
  GstClockTime rtx_last;
  guint num_rtx_retry;
} TimerData;

#define GST_RTP_JITTER_BUFFER_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_RTP_JITTER_BUFFER, \
                                GstRtpJitterBufferPrivate))

static GstStaticPadTemplate gst_rtp_jitter_buffer_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp"
        /* "clock-rate = (int) [ 1, 2147483647 ], "
         * "payload = (int) , "
         * "encoding-name = (string) "
         */ )
    );

static GstStaticPadTemplate gst_rtp_jitter_buffer_sink_rtcp_template =
GST_STATIC_PAD_TEMPLATE ("sink_rtcp",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("application/x-rtcp")
    );

static GstStaticPadTemplate gst_rtp_jitter_buffer_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp"
        /* "payload = (int) , "
         * "clock-rate = (int) , "
         * "encoding-name = (string) "
         */ )
    );

static guint gst_rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 };

#define gst_rtp_jitter_buffer_parent_class parent_class
G_DEFINE_TYPE (GstRtpJitterBuffer, gst_rtp_jitter_buffer, GST_TYPE_ELEMENT);

/* object overrides */
static void gst_rtp_jitter_buffer_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_rtp_jitter_buffer_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_rtp_jitter_buffer_finalize (GObject * object);

/* element overrides */
static GstStateChangeReturn gst_rtp_jitter_buffer_change_state (GstElement
    * element, GstStateChange transition);
static GstPad *gst_rtp_jitter_buffer_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * filter);
static void gst_rtp_jitter_buffer_release_pad (GstElement * element,
    GstPad * pad);
static GstClock *gst_rtp_jitter_buffer_provide_clock (GstElement * element);

/* pad overrides */
static GstCaps *gst_rtp_jitter_buffer_getcaps (GstPad * pad, GstCaps * filter);
static GstIterator *gst_rtp_jitter_buffer_iterate_internal_links (GstPad * pad,
    GstObject * parent);

/* sinkpad overrides */
static gboolean gst_rtp_jitter_buffer_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static GstFlowReturn gst_rtp_jitter_buffer_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);

static gboolean gst_rtp_jitter_buffer_sink_rtcp_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static GstFlowReturn gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);

static gboolean gst_rtp_jitter_buffer_sink_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

/* srcpad overrides */
static gboolean gst_rtp_jitter_buffer_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_rtp_jitter_buffer_src_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static void gst_rtp_jitter_buffer_loop (GstRtpJitterBuffer * jitterbuffer);
static gboolean gst_rtp_jitter_buffer_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static void
gst_rtp_jitter_buffer_clear_pt_map (GstRtpJitterBuffer * jitterbuffer);
static GstClockTime
gst_rtp_jitter_buffer_set_active (GstRtpJitterBuffer * jitterbuffer,
    gboolean active, guint64 base_time);
static void do_handle_sync (GstRtpJitterBuffer * jitterbuffer);

static void unschedule_current_timer (GstRtpJitterBuffer * jitterbuffer);
static void remove_all_timers (GstRtpJitterBuffer * jitterbuffer);

static void wait_next_timeout (GstRtpJitterBuffer * jitterbuffer);

static GstStructure *gst_rtp_jitter_buffer_create_stats (GstRtpJitterBuffer *
    jitterbuffer);

static void
gst_rtp_jitter_buffer_class_init (GstRtpJitterBufferClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  g_type_class_add_private (klass, sizeof (GstRtpJitterBufferPrivate));

  gobject_class->finalize = gst_rtp_jitter_buffer_finalize;

  gobject_class->set_property = gst_rtp_jitter_buffer_set_property;
  gobject_class->get_property = gst_rtp_jitter_buffer_get_property;

  /**
   * GstRtpJitterBuffer:latency:
   *
   * The maximum latency of the jitterbuffer. Packets will be kept in the buffer
   * for at most this time.
   */
  g_object_class_install_property (gobject_class, PROP_LATENCY,
      g_param_spec_uint ("latency", "Buffer latency in ms",
          "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:drop-on-latency:
   *
   * Drop oldest buffers when the queue is completely filled.
   */
  g_object_class_install_property (gobject_class, PROP_DROP_ON_LATENCY,
      g_param_spec_boolean ("drop-on-latency",
          "Drop buffers when maximum latency is reached",
          "Tells the jitterbuffer to never exceed the given latency in size",
          DEFAULT_DROP_ON_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:ts-offset:
   *
   * Adjust GStreamer output buffer timestamps in the jitterbuffer with offset.
   * This is mainly used to ensure interstream synchronisation.
   */
  g_object_class_install_property (gobject_class, PROP_TS_OFFSET,
      g_param_spec_int64 ("ts-offset", "Timestamp Offset",
          "Adjust buffer timestamps with offset in nanoseconds", G_MININT64,
          G_MAXINT64, DEFAULT_TS_OFFSET,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer:do-lost:
   *
   * Send out a GstRTPPacketLost event downstream when a packet is considered
   * lost.
   */
  g_object_class_install_property (gobject_class, PROP_DO_LOST,
      g_param_spec_boolean ("do-lost", "Do Lost",
          "Send an event downstream when a packet is lost", DEFAULT_DO_LOST,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer:mode:
   *
   * Control the buffering and timestamping mode used by the jitterbuffer.
   */
  g_object_class_install_property (gobject_class, PROP_MODE,
      g_param_spec_enum ("mode", "Mode",
          "Control the buffering algorithm in use", RTP_TYPE_JITTER_BUFFER_MODE,
          DEFAULT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:percent:
   *
   * The percent of the jitterbuffer that is filled.
   */
  g_object_class_install_property (gobject_class, PROP_PERCENT,
      g_param_spec_int ("percent", "percent",
          "The buffer filled percent", 0, 100,
          0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:do-retransmission:
   *
   * Send out a GstRTPRetransmission event upstream when a packet is considered
   * late and should be retransmitted.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_DO_RETRANSMISSION,
      g_param_spec_boolean ("do-retransmission", "Do Retransmission",
          "Send retransmission events upstream when a packet is late",
          DEFAULT_DO_RETRANSMISSION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer:rtx-next-seqnum
   *
   * Estimate when the next packet should arrive and schedule a retransmission
   * request for it.
   * This is, when packet N arrives, a GstRTPRetransmission event is schedule
   * for packet N+1. So it will be requested if it does not arrive at the expected time.
   * The expected time is calculated using the dts of N and the packet spacing.
   *
   * Since: 1.6
   */
  g_object_class_install_property (gobject_class, PROP_RTX_NEXT_SEQNUM,
      g_param_spec_boolean ("rtx-next-seqnum", "RTX next seqnum",
          "Estimate when the next packet should arrive and schedule a "
          "retransmission request for it.",
          DEFAULT_RTX_NEXT_SEQNUM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer:rtx-delay:
   *
   * When a packet did not arrive at the expected time, wait this extra amount
   * of time before sending a retransmission event.
   *
   * When -1 is used, the max jitter will be used as extra delay.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_RTX_DELAY,
      g_param_spec_int ("rtx-delay", "RTX Delay",
          "Extra time in ms to wait before sending retransmission "
          "event (-1 automatic)", -1, G_MAXINT, DEFAULT_RTX_DELAY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer:rtx-min-delay:
   *
   * When a packet did not arrive at the expected time, wait at least this extra amount
   * of time before sending a retransmission event.
   *
   * Since: 1.6
   */
  g_object_class_install_property (gobject_class, PROP_RTX_MIN_DELAY,
      g_param_spec_uint ("rtx-min-delay", "Minimum RTX Delay",
          "Minimum time in ms to wait before sending retransmission "
          "event", 0, G_MAXUINT, DEFAULT_RTX_MIN_DELAY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:rtx-delay-reorder:
   *
   * Assume that a retransmission event should be sent when we see
   * this much packet reordering.
   *
   * When -1 is used, the value will be estimated based on observed packet
   * reordering.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_RTX_DELAY_REORDER,
      g_param_spec_int ("rtx-delay-reorder", "RTX Delay Reorder",
          "Sending retransmission event when this much reordering (-1 automatic)",
          -1, G_MAXINT, DEFAULT_RTX_DELAY_REORDER,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer::rtx-retry-timeout:
   *
   * When no packet has been received after sending a retransmission event
   * for this time, retry sending a retransmission event.
   *
   * When -1 is used, the value will be estimated based on observed round
   * trip time.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_RTX_RETRY_TIMEOUT,
      g_param_spec_int ("rtx-retry-timeout", "RTX Retry Timeout",
          "Retry sending a transmission event after this timeout in "
          "ms (-1 automatic)", -1, G_MAXINT, DEFAULT_RTX_RETRY_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer::rtx-min-retry-timeout:
   *
   * The minimum amount of time between retry timeouts. When
   * GstRtpJitterBuffer::rtx-retry-timeout is -1, this value ensures a
   * minimum interval between retry timeouts.
   *
   * When -1 is used, the value will be estimated based on the
   * packet spacing.
   *
   * Since: 1.6
   */
  g_object_class_install_property (gobject_class, PROP_RTX_MIN_RETRY_TIMEOUT,
      g_param_spec_int ("rtx-min-retry-timeout", "RTX Min Retry Timeout",
          "Minimum timeout between sending a transmission event in "
          "ms (-1 automatic)", -1, G_MAXINT, DEFAULT_RTX_MIN_RETRY_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:rtx-retry-period:
   *
   * The amount of time to try to get a retransmission.
   *
   * When -1 is used, the value will be estimated based on the jitterbuffer
   * latency and the observed round trip time.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_RTX_RETRY_PERIOD,
      g_param_spec_int ("rtx-retry-period", "RTX Retry Period",
          "Try to get a retransmission for this many ms "
          "(-1 automatic)", -1, G_MAXINT, DEFAULT_RTX_RETRY_PERIOD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:rtx-max-retries:
   *
   * The maximum number of retries to request a retransmission.
   *
   * This implies that as maximum (rtx-max-retries + 1) retransmissions will be requested.
   * When -1 is used, the number of retransmission request will not be limited.
   *
   * Since: 1.6
   */
  g_object_class_install_property (gobject_class, PROP_RTX_MAX_RETRIES,
      g_param_spec_int ("rtx-max-retries", "RTX Max Retries",
          "The maximum number of retries to request a retransmission. "
          "(-1 not limited)", -1, G_MAXINT, DEFAULT_RTX_MAX_RETRIES,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRtpJitterBuffer:stats:
   *
   * Various jitterbuffer statistics. This property returns a GstStructure
   * with name application/x-rtp-jitterbuffer-stats with the following fields:
   *
   * <itemizedlist>
   * <listitem>
   *   <para>
   *   #guint64
   *   <classname>&quot;rtx-count&quot;</classname>:
   *   the number of retransmissions requested.
   *   </para>
   * </listitem>
   * <listitem>
   *   <para>
   *   #guint64
   *   <classname>&quot;rtx-success-count&quot;</classname>:
   *   the number of successful retransmissions.
   *   </para>
   * </listitem>
   * <listitem>
   *   <para>
   *   #gdouble
   *   <classname>&quot;rtx-per-packet&quot;</classname>:
   *   average number of RTX per packet.
   *   </para>
   * </listitem>
   * <listitem>
   *   <para>
   *   #guint64
   *   <classname>&quot;rtx-rtt&quot;</classname>:
   *   average round trip time per RTX.
   *   </para>
   * </listitem>
   * </itemizedlist>
   *
   * Since: 1.4
   */
  g_object_class_install_property (gobject_class, PROP_STATS,
      g_param_spec_boxed ("stats", "Statistics",
          "Various statistics", GST_TYPE_STRUCTURE,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRtpJitterBuffer::request-pt-map:
   * @buffer: the object which received the signal
   * @pt: the pt
   *
   * Request the payload type as #GstCaps for @pt.
   */
  gst_rtp_jitter_buffer_signals[SIGNAL_REQUEST_PT_MAP] =
      g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass,
          request_pt_map), NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_CAPS, 1, G_TYPE_UINT);
  /**
   * GstRtpJitterBuffer::handle-sync:
   * @buffer: the object which received the signal
   * @struct: a GstStructure containing sync values.
   *
   * Be notified of new sync values.
   */
  gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC] =
      g_signal_new ("handle-sync", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass,
          handle_sync), NULL, NULL, g_cclosure_marshal_VOID__BOXED,
      G_TYPE_NONE, 1, GST_TYPE_STRUCTURE | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GstRtpJitterBuffer::on-npt-stop:
   * @buffer: the object which received the signal
   *
   * Signal that the jitterbufer has pushed the RTP packet that corresponds to
   * the npt-stop position.
   */
  gst_rtp_jitter_buffer_signals[SIGNAL_ON_NPT_STOP] =
      g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass,
          on_npt_stop), NULL, NULL, g_cclosure_marshal_VOID__VOID,
      G_TYPE_NONE, 0, G_TYPE_NONE);

  /**
   * GstRtpJitterBuffer::clear-pt-map:
   * @buffer: the object which received the signal
   *
   * Invalidate the clock-rate as obtained with the
   * #GstRtpJitterBuffer::request-pt-map signal.
   */
  gst_rtp_jitter_buffer_signals[SIGNAL_CLEAR_PT_MAP] =
      g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstRtpJitterBufferClass, clear_pt_map), NULL, NULL,
      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);

  /**
   * GstRtpJitterBuffer::set-active:
   * @buffer: the object which received the signal
   *
   * Start pushing out packets with the given base time. This signal is only
   * useful in buffering mode.
   *
   * Returns: the time of the last pushed packet.
   */
  gst_rtp_jitter_buffer_signals[SIGNAL_SET_ACTIVE] =
      g_signal_new ("set-active", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (GstRtpJitterBufferClass, set_active), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_UINT64, 2, G_TYPE_BOOLEAN,
      G_TYPE_UINT64);

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_change_state);
  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_request_new_pad);
  gstelement_class->release_pad =
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_release_pad);
  gstelement_class->provide_clock =
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_provide_clock);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_jitter_buffer_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_rtcp_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP packet jitter-buffer", "Filter/Network/RTP",
      "A buffer that deals with network jitter and other transmission faults",
      "Philippe Kalaf <philippe.kalaf@collabora.co.uk>, "
      "Wim Taymans <wim.taymans@gmail.com>");

  klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_clear_pt_map);
  klass->set_active = GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_set_active);

  GST_DEBUG_CATEGORY_INIT
      (rtpjitterbuffer_debug, "rtpjitterbuffer", 0, "RTP Jitter Buffer");
}

static void
gst_rtp_jitter_buffer_init (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = GST_RTP_JITTER_BUFFER_GET_PRIVATE (jitterbuffer);
  jitterbuffer->priv = priv;

  priv->latency_ms = DEFAULT_LATENCY_MS;
  priv->latency_ns = priv->latency_ms * GST_MSECOND;
  priv->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
  priv->do_lost = DEFAULT_DO_LOST;
  priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
  priv->rtx_next_seqnum = DEFAULT_RTX_NEXT_SEQNUM;
  priv->rtx_delay = DEFAULT_RTX_DELAY;
  priv->rtx_min_delay = DEFAULT_RTX_MIN_DELAY;
  priv->rtx_delay_reorder = DEFAULT_RTX_DELAY_REORDER;
  priv->rtx_retry_timeout = DEFAULT_RTX_RETRY_TIMEOUT;
  priv->rtx_min_retry_timeout = DEFAULT_RTX_MIN_RETRY_TIMEOUT;
  priv->rtx_retry_period = DEFAULT_RTX_RETRY_PERIOD;
  priv->rtx_max_retries = DEFAULT_RTX_MAX_RETRIES;

  priv->last_dts = -1;
  priv->last_rtptime = -1;
  priv->avg_jitter = 0;
  priv->timers = g_array_new (FALSE, TRUE, sizeof (TimerData));
  priv->jbuf = rtp_jitter_buffer_new ();
  g_mutex_init (&priv->jbuf_lock);
  g_cond_init (&priv->jbuf_timer);
  g_cond_init (&priv->jbuf_event);
  g_cond_init (&priv->jbuf_query);
  g_queue_init (&priv->gap_packets);

  /* reset skew detection initialy */
  rtp_jitter_buffer_reset_skew (priv->jbuf);
  rtp_jitter_buffer_set_delay (priv->jbuf, priv->latency_ns);
  rtp_jitter_buffer_set_buffering (priv->jbuf, FALSE);
  priv->active = TRUE;

  priv->srcpad =
      gst_pad_new_from_static_template (&gst_rtp_jitter_buffer_src_template,
      "src");

  gst_pad_set_activatemode_function (priv->srcpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_src_activate_mode));
  gst_pad_set_query_function (priv->srcpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_src_query));
  gst_pad_set_event_function (priv->srcpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_src_event));

  priv->sinkpad =
      gst_pad_new_from_static_template (&gst_rtp_jitter_buffer_sink_template,
      "sink");

  gst_pad_set_chain_function (priv->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_chain));
  gst_pad_set_event_function (priv->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_sink_event));
  gst_pad_set_query_function (priv->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_sink_query));

  gst_element_add_pad (GST_ELEMENT (jitterbuffer), priv->srcpad);
  gst_element_add_pad (GST_ELEMENT (jitterbuffer), priv->sinkpad);

  GST_OBJECT_FLAG_SET (jitterbuffer, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
}

#define IS_DROPABLE(it) (((it)->type == ITEM_TYPE_BUFFER) || ((it)->type == ITEM_TYPE_LOST))

#define ITEM_TYPE_BUFFER        0
#define ITEM_TYPE_LOST          1
#define ITEM_TYPE_EVENT         2
#define ITEM_TYPE_QUERY         3

static RTPJitterBufferItem *
alloc_item (gpointer data, guint type, GstClockTime dts, GstClockTime pts,
    guint seqnum, guint count, guint rtptime)
{
  RTPJitterBufferItem *item;

  item = g_slice_new (RTPJitterBufferItem);
  item->data = data;
  item->next = NULL;
  item->prev = NULL;
  item->type = type;
  item->dts = dts;
  item->pts = pts;
  item->seqnum = seqnum;
  item->count = count;
  item->rtptime = rtptime;

  return item;
}

static void
free_item (RTPJitterBufferItem * item)
{
  g_return_if_fail (item != NULL);

  if (item->data && item->type != ITEM_TYPE_QUERY)
    gst_mini_object_unref (item->data);
  g_slice_free (RTPJitterBufferItem, item);
}

static void
free_item_and_retain_events (RTPJitterBufferItem * item, gpointer user_data)
{
  GList **l = user_data;

  if (item->data && item->type == ITEM_TYPE_EVENT
      && GST_EVENT_IS_STICKY (item->data)) {
    *l = g_list_prepend (*l, item->data);
  } else if (item->data && item->type != ITEM_TYPE_QUERY) {
    gst_mini_object_unref (item->data);
  }
  g_slice_free (RTPJitterBufferItem, item);
}

static void
gst_rtp_jitter_buffer_finalize (GObject * object)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER (object);
  priv = jitterbuffer->priv;

  g_array_free (priv->timers, TRUE);
  g_mutex_clear (&priv->jbuf_lock);
  g_cond_clear (&priv->jbuf_timer);
  g_cond_clear (&priv->jbuf_event);
  g_cond_clear (&priv->jbuf_query);

  rtp_jitter_buffer_flush (priv->jbuf, (GFunc) free_item, NULL);
  g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
  g_queue_clear (&priv->gap_packets);
  g_object_unref (priv->jbuf);

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

static GstIterator *
gst_rtp_jitter_buffer_iterate_internal_links (GstPad * pad, GstObject * parent)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstPad *otherpad = NULL;
  GstIterator *it = NULL;
  GValue val = { 0, };

  jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (parent);

  if (pad == jitterbuffer->priv->sinkpad) {
    otherpad = jitterbuffer->priv->srcpad;
  } else if (pad == jitterbuffer->priv->srcpad) {
    otherpad = jitterbuffer->priv->sinkpad;
  } else if (pad == jitterbuffer->priv->rtcpsinkpad) {
    it = gst_iterator_new_single (GST_TYPE_PAD, NULL);
  }

  if (it == NULL) {
    g_value_init (&val, GST_TYPE_PAD);
    g_value_set_object (&val, otherpad);
    it = gst_iterator_new_single (GST_TYPE_PAD, &val);
    g_value_unset (&val);
  }

  return it;
}

static GstPad *
create_rtcp_sink (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  GST_DEBUG_OBJECT (jitterbuffer, "creating RTCP sink pad");

  priv->rtcpsinkpad =
      gst_pad_new_from_static_template
      (&gst_rtp_jitter_buffer_sink_rtcp_template, "sink_rtcp");
  gst_pad_set_chain_function (priv->rtcpsinkpad,
      gst_rtp_jitter_buffer_chain_rtcp);
  gst_pad_set_event_function (priv->rtcpsinkpad,
      (GstPadEventFunction) gst_rtp_jitter_buffer_sink_rtcp_event);
  gst_pad_set_iterate_internal_links_function (priv->rtcpsinkpad,
      gst_rtp_jitter_buffer_iterate_internal_links);
  gst_pad_set_active (priv->rtcpsinkpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (jitterbuffer), priv->rtcpsinkpad);

  return priv->rtcpsinkpad;
}

static void
remove_rtcp_sink (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  GST_DEBUG_OBJECT (jitterbuffer, "removing RTCP sink pad");

  gst_pad_set_active (priv->rtcpsinkpad, FALSE);

  gst_element_remove_pad (GST_ELEMENT_CAST (jitterbuffer), priv->rtcpsinkpad);
  priv->rtcpsinkpad = NULL;
}

static GstPad *
gst_rtp_jitter_buffer_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * filter)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstElementClass *klass;
  GstPad *result;
  GstRtpJitterBufferPrivate *priv;

  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (GST_IS_RTP_JITTER_BUFFER (element), NULL);

  jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (element);
  priv = jitterbuffer->priv;
  klass = GST_ELEMENT_GET_CLASS (element);

  GST_DEBUG_OBJECT (element, "requesting pad %s", GST_STR_NULL (name));

  /* figure out the template */
  if (templ == gst_element_class_get_pad_template (klass, "sink_rtcp")) {
    if (priv->rtcpsinkpad != NULL)
      goto exists;

    result = create_rtcp_sink (jitterbuffer);
  } else
    goto wrong_template;

  return result;

  /* ERRORS */
wrong_template:
  {
    g_warning ("rtpjitterbuffer: this is not our template");
    return NULL;
  }
exists:
  {
    g_warning ("rtpjitterbuffer: pad already requested");
    return NULL;
  }
}

static void
gst_rtp_jitter_buffer_release_pad (GstElement * element, GstPad * pad)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  g_return_if_fail (GST_IS_RTP_JITTER_BUFFER (element));
  g_return_if_fail (GST_IS_PAD (pad));

  jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (element);
  priv = jitterbuffer->priv;

  GST_DEBUG_OBJECT (element, "releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  if (priv->rtcpsinkpad == pad) {
    remove_rtcp_sink (jitterbuffer);
  } else
    goto wrong_pad;

  return;

  /* ERRORS */
wrong_pad:
  {
    g_warning ("gstjitterbuffer: asked to release an unknown pad");
    return;
  }
}

static GstClock *
gst_rtp_jitter_buffer_provide_clock (GstElement * element)
{
  return gst_system_clock_obtain ();
}

static void
gst_rtp_jitter_buffer_clear_pt_map (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  /* this will trigger a new pt-map request signal, FIXME, do something better. */

  JBUF_LOCK (priv);
  priv->clock_rate = -1;
  /* do not clear current content, but refresh state for new arrival */
  GST_DEBUG_OBJECT (jitterbuffer, "reset jitterbuffer");
  rtp_jitter_buffer_reset_skew (priv->jbuf);
  JBUF_UNLOCK (priv);
}

static GstClockTime
gst_rtp_jitter_buffer_set_active (GstRtpJitterBuffer * jbuf, gboolean active,
    guint64 offset)
{
  GstRtpJitterBufferPrivate *priv;
  GstClockTime last_out;
  RTPJitterBufferItem *item;

  priv = jbuf->priv;

  JBUF_LOCK (priv);
  GST_DEBUG_OBJECT (jbuf, "setting active %d with offset %" GST_TIME_FORMAT,
      active, GST_TIME_ARGS (offset));

  if (active != priv->active) {
    /* add the amount of time spent in paused to the output offset. All
     * outgoing buffers will have this offset applied to their timestamps in
     * order to make them arrive in time in the sink. */
    priv->out_offset = offset;
    GST_DEBUG_OBJECT (jbuf, "out offset %" GST_TIME_FORMAT,
        GST_TIME_ARGS (priv->out_offset));
    priv->active = active;
    JBUF_SIGNAL_EVENT (priv);
  }
  if (!active) {
    rtp_jitter_buffer_set_buffering (priv->jbuf, TRUE);
  }
  if ((item = rtp_jitter_buffer_peek (priv->jbuf))) {
    /* head buffer timestamp and offset gives our output time */
    last_out = item->dts + priv->ts_offset;
  } else {
    /* use last known time when the buffer is empty */
    last_out = priv->last_out_time;
  }
  JBUF_UNLOCK (priv);

  return last_out;
}

static GstCaps *
gst_rtp_jitter_buffer_getcaps (GstPad * pad, GstCaps * filter)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;
  GstPad *other;
  GstCaps *caps;
  GstCaps *templ;

  jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad));
  priv = jitterbuffer->priv;

  other = (pad == priv->srcpad ? priv->sinkpad : priv->srcpad);

  caps = gst_pad_peer_query_caps (other, filter);

  templ = gst_pad_get_pad_template_caps (pad);
  if (caps == NULL) {
    GST_DEBUG_OBJECT (jitterbuffer, "use template");
    caps = templ;
  } else {
    GstCaps *intersect;

    GST_DEBUG_OBJECT (jitterbuffer, "intersect with template");

    intersect = gst_caps_intersect (caps, templ);
    gst_caps_unref (caps);
    gst_caps_unref (templ);

    caps = intersect;
  }
  gst_object_unref (jitterbuffer);

  return caps;
}

/*
 * Must be called with JBUF_LOCK held
 */

static gboolean
gst_jitter_buffer_sink_parse_caps (GstRtpJitterBuffer * jitterbuffer,
    GstCaps * caps)
{
  GstRtpJitterBufferPrivate *priv;
  GstStructure *caps_struct;
  guint val;
  GstClockTime tval;

  priv = jitterbuffer->priv;

  /* first parse the caps */
  caps_struct = gst_caps_get_structure (caps, 0);

  GST_DEBUG_OBJECT (jitterbuffer, "got caps");

  /* we need a clock-rate to convert the rtp timestamps to GStreamer time and to
   * measure the amount of data in the buffer */
  if (!gst_structure_get_int (caps_struct, "clock-rate", &priv->clock_rate))
    goto error;

  if (priv->clock_rate <= 0)
    goto wrong_rate;

  GST_DEBUG_OBJECT (jitterbuffer, "got clock-rate %d", priv->clock_rate);

  rtp_jitter_buffer_set_clock_rate (priv->jbuf, priv->clock_rate);

  /* The clock base is the RTP timestamp corrsponding to the npt-start value. We
   * can use this to track the amount of time elapsed on the sender. */
  if (gst_structure_get_uint (caps_struct, "clock-base", &val))
    priv->clock_base = val;
  else
    priv->clock_base = -1;

  priv->ext_timestamp = priv->clock_base;

  GST_DEBUG_OBJECT (jitterbuffer, "got clock-base %" G_GINT64_FORMAT,
      priv->clock_base);

  if (gst_structure_get_uint (caps_struct, "seqnum-base", &val)) {
    /* first expected seqnum, only update when we didn't have a previous base. */
    if (priv->next_in_seqnum == -1)
      priv->next_in_seqnum = val;
    if (priv->next_seqnum == -1) {
      priv->next_seqnum = val;
      JBUF_SIGNAL_EVENT (priv);
    }
    priv->seqnum_base = val;
  } else {
    priv->seqnum_base = -1;
  }

  GST_DEBUG_OBJECT (jitterbuffer, "got seqnum-base %d", priv->next_in_seqnum);

  /* the start and stop times. The seqnum-base corresponds to the start time. We
   * will keep track of the seqnums on the output and when we reach the one
   * corresponding to npt-stop, we emit the npt-stop-reached signal */
  if (gst_structure_get_clock_time (caps_struct, "npt-start", &tval))
    priv->npt_start = tval;
  else
    priv->npt_start = 0;

  if (gst_structure_get_clock_time (caps_struct, "npt-stop", &tval))
    priv->npt_stop = tval;
  else
    priv->npt_stop = -1;

  GST_DEBUG_OBJECT (jitterbuffer,
      "npt start/stop: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
      GST_TIME_ARGS (priv->npt_start), GST_TIME_ARGS (priv->npt_stop));

  return TRUE;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "No clock-rate in caps!");
    return FALSE;
  }
wrong_rate:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "Invalid clock-rate %d", priv->clock_rate);
    return FALSE;
  }
}

static void
gst_rtp_jitter_buffer_flush_start (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  JBUF_LOCK (priv);
  /* mark ourselves as flushing */
  priv->srcresult = GST_FLOW_FLUSHING;
  GST_DEBUG_OBJECT (jitterbuffer, "Disabling pop on queue");
  /* this unblocks any waiting pops on the src pad task */
  JBUF_SIGNAL_EVENT (priv);
  JBUF_SIGNAL_QUERY (priv, FALSE);
  JBUF_UNLOCK (priv);
}

static void
gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  JBUF_LOCK (priv);
  GST_DEBUG_OBJECT (jitterbuffer, "Enabling pop on queue");
  /* Mark as non flushing */
  priv->srcresult = GST_FLOW_OK;
  gst_segment_init (&priv->segment, GST_FORMAT_TIME);
  priv->last_popped_seqnum = -1;
  priv->last_out_time = -1;
  priv->next_seqnum = -1;
  priv->seqnum_base = -1;
  priv->ips_rtptime = -1;
  priv->ips_dts = GST_CLOCK_TIME_NONE;
  priv->packet_spacing = 0;
  priv->next_in_seqnum = -1;
  priv->clock_rate = -1;
  priv->last_pt = -1;
  priv->eos = FALSE;
  priv->estimated_eos = -1;
  priv->last_elapsed = 0;
  priv->ext_timestamp = -1;
  priv->avg_jitter = 0;
  priv->last_dts = -1;
  priv->last_rtptime = -1;
  GST_DEBUG_OBJECT (jitterbuffer, "flush and reset jitterbuffer");
  rtp_jitter_buffer_flush (priv->jbuf, (GFunc) free_item, NULL);
  rtp_jitter_buffer_disable_buffering (priv->jbuf, FALSE);
  rtp_jitter_buffer_reset_skew (priv->jbuf);
  remove_all_timers (jitterbuffer);
  g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
  g_queue_clear (&priv->gap_packets);
  JBUF_UNLOCK (priv);
}

static gboolean
gst_rtp_jitter_buffer_src_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean result;
  GstRtpJitterBuffer *jitterbuffer = NULL;

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      if (active) {
        /* allow data processing */
        gst_rtp_jitter_buffer_flush_stop (jitterbuffer);

        /* start pushing out buffers */
        GST_DEBUG_OBJECT (jitterbuffer, "Starting task on srcpad");
        result = gst_pad_start_task (jitterbuffer->priv->srcpad,
            (GstTaskFunction) gst_rtp_jitter_buffer_loop, jitterbuffer, NULL);
      } else {
        /* make sure all data processing stops ASAP */
        gst_rtp_jitter_buffer_flush_start (jitterbuffer);

        /* NOTE this will hardlock if the state change is called from the src pad
         * task thread because we will _join() the thread. */
        GST_DEBUG_OBJECT (jitterbuffer, "Stopping task on srcpad");
        result = gst_pad_stop_task (pad);
      }
      break;
    default:
      result = FALSE;
      break;
  }
  return result;
}

static GstStateChangeReturn
gst_rtp_jitter_buffer_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  jitterbuffer = GST_RTP_JITTER_BUFFER (element);
  priv = jitterbuffer->priv;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      JBUF_LOCK (priv);
      /* reset negotiated values */
      priv->clock_rate = -1;
      priv->clock_base = -1;
      priv->peer_latency = 0;
      priv->last_pt = -1;
      /* block until we go to PLAYING */
      priv->blocked = TRUE;
      priv->timer_running = TRUE;
      priv->timer_thread =
          g_thread_new ("timer", (GThreadFunc) wait_next_timeout, jitterbuffer);
      JBUF_UNLOCK (priv);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      JBUF_LOCK (priv);
      /* unblock to allow streaming in PLAYING */
      priv->blocked = FALSE;
      JBUF_SIGNAL_EVENT (priv);
      JBUF_SIGNAL_TIMER (priv);
      JBUF_UNLOCK (priv);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* we are a live element because we sync to the clock, which we can only
       * do in the PLAYING state */
      if (ret != GST_STATE_CHANGE_FAILURE)
        ret = GST_STATE_CHANGE_NO_PREROLL;
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      JBUF_LOCK (priv);
      /* block to stop streaming when PAUSED */
      priv->blocked = TRUE;
      unschedule_current_timer (jitterbuffer);
      JBUF_UNLOCK (priv);
      if (ret != GST_STATE_CHANGE_FAILURE)
        ret = GST_STATE_CHANGE_NO_PREROLL;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      JBUF_LOCK (priv);
      gst_buffer_replace (&priv->last_sr, NULL);
      priv->timer_running = FALSE;
      unschedule_current_timer (jitterbuffer);
      JBUF_SIGNAL_TIMER (priv);
      JBUF_SIGNAL_QUERY (priv, FALSE);
      JBUF_UNLOCK (priv);
      g_thread_join (priv->timer_thread);
      priv->timer_thread = NULL;
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static gboolean
gst_rtp_jitter_buffer_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean ret = TRUE;
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (parent);
  priv = jitterbuffer->priv;

  GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_LATENCY:
    {
      GstClockTime latency;

      gst_event_parse_latency (event, &latency);

      GST_DEBUG_OBJECT (jitterbuffer,
          "configuring latency of %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));

      JBUF_LOCK (priv);
      /* adjust the overall buffer delay to the total pipeline latency in
       * buffering mode because if downstream consumes too fast (because of
       * large latency or queues, we would start rebuffering again. */
      if (rtp_jitter_buffer_get_mode (priv->jbuf) ==
          RTP_JITTER_BUFFER_MODE_BUFFER) {
        rtp_jitter_buffer_set_delay (priv->jbuf, latency);
      }
      JBUF_UNLOCK (priv);

      ret = gst_pad_push_event (priv->sinkpad, event);
      break;
    }
    default:
      ret = gst_pad_push_event (priv->sinkpad, event);
      break;
  }

  return ret;
}

/* handles and stores the event in the jitterbuffer, must be called with
 * LOCK */
static gboolean
queue_event (GstRtpJitterBuffer * jitterbuffer, GstEvent * event)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  RTPJitterBufferItem *item;
  gboolean head;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps);
      break;
    }
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &priv->segment);

      /* we need time for now */
      if (priv->segment.format != GST_FORMAT_TIME)
        goto newseg_wrong_format;

      GST_DEBUG_OBJECT (jitterbuffer,
          "segment:  %" GST_SEGMENT_FORMAT, &priv->segment);
      break;
    case GST_EVENT_EOS:
      priv->eos = TRUE;
      rtp_jitter_buffer_disable_buffering (priv->jbuf, TRUE);
      break;
    default:
      break;
  }


  GST_DEBUG_OBJECT (jitterbuffer, "adding event");
  item = alloc_item (event, ITEM_TYPE_EVENT, -1, -1, -1, 0, -1);
  rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL);
  if (head)
    JBUF_SIGNAL_EVENT (priv);

  return TRUE;

  /* ERRORS */
newseg_wrong_format:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "received non TIME newsegment");
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_rtp_jitter_buffer_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean ret = TRUE;
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);
  priv = jitterbuffer->priv;

  GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      ret = gst_pad_push_event (priv->srcpad, event);
      gst_rtp_jitter_buffer_flush_start (jitterbuffer);
      /* wait for the loop to go into PAUSED */
      gst_pad_pause_task (priv->srcpad);
      break;
    case GST_EVENT_FLUSH_STOP:
      ret = gst_pad_push_event (priv->srcpad, event);
      ret =
          gst_rtp_jitter_buffer_src_activate_mode (priv->srcpad, parent,
          GST_PAD_MODE_PUSH, TRUE);
      break;
    default:
      if (GST_EVENT_IS_SERIALIZED (event)) {
        /* serialized events go in the queue */
        JBUF_LOCK (priv);
        if (priv->srcresult != GST_FLOW_OK) {
          /* Errors in sticky event pushing are no problem and ignored here
           * as they will cause more meaningful errors during data flow.
           * For EOS events, that are not followed by data flow, we still
           * return FALSE here though.
           */
          if (!GST_EVENT_IS_STICKY (event) ||
              GST_EVENT_TYPE (event) == GST_EVENT_EOS)
            goto out_flow_error;
        }
        /* refuse more events on EOS */
        if (priv->eos)
          goto out_eos;
        ret = queue_event (jitterbuffer, event);
        JBUF_UNLOCK (priv);
      } else {
        /* non-serialized events are forwarded downstream immediately */
        ret = gst_pad_push_event (priv->srcpad, event);
      }
      break;
  }
  return ret;

  /* ERRORS */
out_flow_error:
  {
    GST_DEBUG_OBJECT (jitterbuffer,
        "refusing event, we have a downstream flow error: %s",
        gst_flow_get_name (priv->srcresult));
    JBUF_UNLOCK (priv);
    gst_event_unref (event);
    return FALSE;
  }
out_eos:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "refusing event, we are EOS");
    JBUF_UNLOCK (priv);
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_rtp_jitter_buffer_sink_rtcp_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean ret = TRUE;
  GstRtpJitterBuffer *jitterbuffer;

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);

  GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      gst_event_unref (event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_event_unref (event);
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

/*
 * Must be called with JBUF_LOCK held, will release the LOCK when emiting the
 * signal. The function returns GST_FLOW_ERROR when a parsing error happened and
 * GST_FLOW_FLUSHING when the element is shutting down. On success
 * GST_FLOW_OK is returned.
 */
static GstFlowReturn
gst_rtp_jitter_buffer_get_clock_rate (GstRtpJitterBuffer * jitterbuffer,
    guint8 pt)
{
  GValue ret = { 0 };
  GValue args[2] = { {0}, {0} };
  GstCaps *caps;
  gboolean res;

  g_value_init (&args[0], GST_TYPE_ELEMENT);
  g_value_set_object (&args[0], jitterbuffer);
  g_value_init (&args[1], G_TYPE_UINT);
  g_value_set_uint (&args[1], pt);

  g_value_init (&ret, GST_TYPE_CAPS);
  g_value_set_boxed (&ret, NULL);

  JBUF_UNLOCK (jitterbuffer->priv);
  g_signal_emitv (args, gst_rtp_jitter_buffer_signals[SIGNAL_REQUEST_PT_MAP], 0,
      &ret);
  JBUF_LOCK_CHECK (jitterbuffer->priv, out_flushing);

  g_value_unset (&args[0]);
  g_value_unset (&args[1]);
  caps = (GstCaps *) g_value_dup_boxed (&ret);
  g_value_unset (&ret);
  if (!caps)
    goto no_caps;

  res = gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps);
  gst_caps_unref (caps);

  if (G_UNLIKELY (!res))
    goto parse_failed;

  return GST_FLOW_OK;

  /* ERRORS */
no_caps:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "could not get caps");
    return GST_FLOW_ERROR;
  }
out_flushing:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "we are flushing");
    return GST_FLOW_FLUSHING;
  }
parse_failed:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "parse failed");
    return GST_FLOW_ERROR;
  }
}

/* call with jbuf lock held */
static GstMessage *
check_buffering_percent (GstRtpJitterBuffer * jitterbuffer, gint percent)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstMessage *message = NULL;

  if (percent == -1)
    return NULL;

  /* Post a buffering message */
  if (priv->last_percent != percent) {
    priv->last_percent = percent;
    message =
        gst_message_new_buffering (GST_OBJECT_CAST (jitterbuffer), percent);
    gst_message_set_buffering_stats (message, GST_BUFFERING_LIVE, -1, -1, -1);
  }

  return message;
}

static GstClockTime
apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
{
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  if (timestamp == -1)
    return -1;

  /* apply the timestamp offset, this is used for inter stream sync */
  timestamp += priv->ts_offset;
  /* add the offset, this is used when buffering */
  timestamp += priv->out_offset;

  return timestamp;
}

static TimerData *
find_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type, guint16 seqnum)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  TimerData *timer = NULL;
  gint i, len;

  len = priv->timers->len;
  for (i = 0; i < len; i++) {
    TimerData *test = &g_array_index (priv->timers, TimerData, i);
    if (test->seqnum == seqnum && test->type == type) {
      timer = test;
      break;
    }
  }
  return timer;
}

static void
unschedule_current_timer (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  if (priv->clock_id) {
    GST_DEBUG_OBJECT (jitterbuffer, "unschedule current timer");
    gst_clock_id_unschedule (priv->clock_id);
    priv->clock_id = NULL;
  }
}

static GstClockTime
get_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstClockTime test_timeout;

  if ((test_timeout = timer->timeout) == -1)
    return -1;

  if (timer->type != TIMER_TYPE_EXPECTED) {
    /* add our latency and offset to get output times. */
    test_timeout = apply_offset (jitterbuffer, test_timeout);
    test_timeout += priv->latency_ns;
  }
  return test_timeout;
}

static void
recalculate_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  if (priv->clock_id) {
    GstClockTime timeout = get_timeout (jitterbuffer, timer);

    GST_DEBUG ("%" GST_TIME_FORMAT " <> %" GST_TIME_FORMAT,
        GST_TIME_ARGS (timeout), GST_TIME_ARGS (priv->timer_timeout));

    if (timeout == -1 || timeout < priv->timer_timeout)
      unschedule_current_timer (jitterbuffer);
  }
}

static TimerData *
add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
    guint16 seqnum, guint num, GstClockTime timeout, GstClockTime delay,
    GstClockTime duration)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  TimerData *timer;
  gint len;

  GST_DEBUG_OBJECT (jitterbuffer,
      "add timer %d for seqnum %d to %" GST_TIME_FORMAT ", delay %"
      GST_TIME_FORMAT, type, seqnum, GST_TIME_ARGS (timeout),
      GST_TIME_ARGS (delay));

  len = priv->timers->len;
  g_array_set_size (priv->timers, len + 1);
  timer = &g_array_index (priv->timers, TimerData, len);
  timer->idx = len;
  timer->type = type;
  timer->seqnum = seqnum;
  timer->num = num;
  timer->timeout = timeout + delay;
  timer->duration = duration;
  if (type == TIMER_TYPE_EXPECTED) {
    timer->rtx_base = timeout;
    timer->rtx_delay = delay;
    timer->rtx_retry = 0;
  }
  timer->num_rtx_retry = 0;
  recalculate_timer (jitterbuffer, timer);
  JBUF_SIGNAL_TIMER (priv);

  return timer;
}

static void
reschedule_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    guint16 seqnum, GstClockTime timeout, GstClockTime delay, gboolean reset)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  gboolean seqchange, timechange;
  guint16 oldseq;

  seqchange = timer->seqnum != seqnum;
  timechange = timer->timeout != timeout;

  if (!seqchange && !timechange)
    return;

  oldseq = timer->seqnum;

  GST_DEBUG_OBJECT (jitterbuffer,
      "replace timer for seqnum %d->%d to %" GST_TIME_FORMAT,
      oldseq, seqnum, GST_TIME_ARGS (timeout + delay));

  timer->timeout = timeout + delay;
  timer->seqnum = seqnum;
  if (reset) {
    timer->rtx_base = timeout;
    timer->rtx_delay = delay;
    timer->rtx_retry = 0;
  }
  if (seqchange)
    timer->num_rtx_retry = 0;

  if (priv->clock_id) {
    /* we changed the seqnum and there is a timer currently waiting with this
     * seqnum, unschedule it */
    if (seqchange && priv->timer_seqnum == oldseq)
      unschedule_current_timer (jitterbuffer);
    /* we changed the time, check if it is earlier than what we are waiting
     * for and unschedule if so */
    else if (timechange)
      recalculate_timer (jitterbuffer, timer);
  }
}

static TimerData *
set_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
    guint16 seqnum, GstClockTime timeout)
{
  TimerData *timer;

  /* find the seqnum timer */
  timer = find_timer (jitterbuffer, type, seqnum);
  if (timer == NULL) {
    timer = add_timer (jitterbuffer, type, seqnum, 0, timeout, 0, -1);
  } else {
    reschedule_timer (jitterbuffer, timer, seqnum, timeout, 0, FALSE);
  }
  return timer;
}

static void
remove_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  guint idx;

  if (priv->clock_id && priv->timer_seqnum == timer->seqnum)
    unschedule_current_timer (jitterbuffer);

  idx = timer->idx;
  GST_DEBUG_OBJECT (jitterbuffer, "removed index %d", idx);
  g_array_remove_index_fast (priv->timers, idx);
  timer->idx = idx;
}

static void
remove_all_timers (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GST_DEBUG_OBJECT (jitterbuffer, "removed all timers");
  g_array_set_size (priv->timers, 0);
  unschedule_current_timer (jitterbuffer);
}

/* get the extra delay to wait before sending RTX */
static GstClockTime
get_rtx_delay (GstRtpJitterBufferPrivate * priv)
{
  GstClockTime delay;

  if (priv->rtx_delay == -1) {
    if (priv->avg_jitter == 0 && priv->packet_spacing == 0) {
      delay = DEFAULT_AUTO_RTX_DELAY;
    } else {
      /* jitter is in nanoseconds, maximum of 2x jitter and half the
       * packet spacing is a good margin */
      delay = MAX (priv->avg_jitter * 2, priv->packet_spacing / 2);
    }
  } else {
    delay = priv->rtx_delay * GST_MSECOND;
  }
  if (priv->rtx_min_delay > 0)
    delay = MAX (delay, priv->rtx_min_delay * GST_MSECOND);

  return delay;
}

/* we just received a packet with seqnum and dts.
 *
 * First check for old seqnum that we are still expecting. If the gap with the
 * current seqnum is too big, unschedule the timeouts.
 *
 * If we have a valid packet spacing estimate we can set a timer for when we
 * should receive the next packet.
 * If we don't have a valid estimate, we remove any timer we might have
 * had for this packet.
 */
static void
update_timers (GstRtpJitterBuffer * jitterbuffer, guint16 seqnum,
    GstClockTime dts, gboolean do_next_seqnum)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  TimerData *timer = NULL;
  gint i, len;

  /* go through all timers and unschedule the ones with a large gap, also find
   * the timer for the seqnum */
  len = priv->timers->len;
  for (i = 0; i < len; i++) {
    TimerData *test = &g_array_index (priv->timers, TimerData, i);
    gint gap;

    gap = gst_rtp_buffer_compare_seqnum (test->seqnum, seqnum);

    GST_DEBUG_OBJECT (jitterbuffer, "%d, %d, #%d<->#%d gap %d", i,
        test->type, test->seqnum, seqnum, gap);

    if (gap == 0) {
      GST_DEBUG ("found timer for current seqnum");
      /* the timer for the current seqnum */
      timer = test;
      /* when no retransmission, we can stop now, we only need to find the
       * timer for the current seqnum */
      if (!priv->do_retransmission)
        break;
    } else if (gap > priv->rtx_delay_reorder) {
      /* max gap, we exceeded the max reorder distance and we don't expect the
       * missing packet to be this reordered */
      if (test->num_rtx_retry == 0 && test->type == TIMER_TYPE_EXPECTED)
        reschedule_timer (jitterbuffer, test, test->seqnum, -1, 0, FALSE);
    }
  }

  do_next_seqnum = do_next_seqnum && priv->packet_spacing > 0
      && priv->do_retransmission && priv->rtx_next_seqnum;

  if (timer && timer->type != TIMER_TYPE_DEADLINE) {
    if (timer->num_rtx_retry > 0) {
      GstClockTime rtx_last, delay;

      /* we scheduled a retry for this packet and now we have it */
      priv->num_rtx_success++;
      /* all the previous retry attempts failed */
      priv->num_rtx_failed += timer->num_rtx_retry - 1;
      /* number of retries before receiving the packet */
      if (priv->avg_rtx_num == 0.0)
        priv->avg_rtx_num = timer->num_rtx_retry;
      else
        priv->avg_rtx_num = (timer->num_rtx_retry + 7 * priv->avg_rtx_num) / 8;
      /* calculate the delay between retransmission request and receiving this
       * packet, start with when we scheduled this timeout last */
      rtx_last = timer->rtx_last;
      if (dts != GST_CLOCK_TIME_NONE && dts > rtx_last) {
        /* we have a valid delay if this packet arrived after we scheduled the
         * request */
        delay = dts - rtx_last;
        if (priv->avg_rtx_rtt == 0)
          priv->avg_rtx_rtt = delay;
        else
          priv->avg_rtx_rtt = (delay + 7 * priv->avg_rtx_rtt) / 8;
      } else
        delay = 0;

      GST_LOG_OBJECT (jitterbuffer,
          "RTX success %" G_GUINT64_FORMAT ", failed %" G_GUINT64_FORMAT
          ", requests %" G_GUINT64_FORMAT ", dups %" G_GUINT64_FORMAT
          ", avg-num %g, delay %" GST_TIME_FORMAT ", avg-rtt %" GST_TIME_FORMAT,
          priv->num_rtx_success, priv->num_rtx_failed, priv->num_rtx_requests,
          priv->num_duplicates, priv->avg_rtx_num, GST_TIME_ARGS (delay),
          GST_TIME_ARGS (priv->avg_rtx_rtt));

      /* don't try to estimate the next seqnum because this is a retransmitted
       * packet and it probably did not arrive with the expected packet
       * spacing. */
      do_next_seqnum = FALSE;
    }
  }

  if (do_next_seqnum && dts != GST_CLOCK_TIME_NONE) {
    GstClockTime expected, delay;

    /* calculate expected arrival time of the next seqnum */
    expected = dts + priv->packet_spacing;

    delay = get_rtx_delay (priv);

    /* and update/install timer for next seqnum */
    if (timer) {
      reschedule_timer (jitterbuffer, timer, priv->next_in_seqnum, expected,
          delay, TRUE);
    } else {
      add_timer (jitterbuffer, TIMER_TYPE_EXPECTED, priv->next_in_seqnum, 0,
          expected, delay, priv->packet_spacing);
    }
  } else if (timer && timer->type != TIMER_TYPE_DEADLINE) {
    /* if we had a timer, remove it, we don't know when to expect the next
     * packet. */
    remove_timer (jitterbuffer, timer);
  }
}

static void
calculate_packet_spacing (GstRtpJitterBuffer * jitterbuffer, guint32 rtptime,
    GstClockTime dts)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  /* we need consecutive seqnums with a different
   * rtptime to estimate the packet spacing. */
  if (priv->ips_rtptime != rtptime) {
    /* rtptime changed, check dts diff */
    if (priv->ips_dts != -1 && dts != -1 && dts > priv->ips_dts) {
      GstClockTime new_packet_spacing = dts - priv->ips_dts;
      GstClockTime old_packet_spacing = priv->packet_spacing;

      /* Biased towards bigger packet spacings to prevent
       * too many unneeded retransmission requests for next
       * packets that just arrive a little later than we would
       * expect */
      if (old_packet_spacing > new_packet_spacing)
        priv->packet_spacing =
            (new_packet_spacing + 3 * old_packet_spacing) / 4;
      else if (old_packet_spacing > 0)
        priv->packet_spacing =
            (3 * new_packet_spacing + old_packet_spacing) / 4;
      else
        priv->packet_spacing = new_packet_spacing;

      GST_DEBUG_OBJECT (jitterbuffer,
          "new packet spacing %" GST_TIME_FORMAT
          " old packet spacing %" GST_TIME_FORMAT
          " combined to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (new_packet_spacing),
          GST_TIME_ARGS (old_packet_spacing),
          GST_TIME_ARGS (priv->packet_spacing));
    }
    priv->ips_rtptime = rtptime;
    priv->ips_dts = dts;
  }
}

static void
calculate_expected (GstRtpJitterBuffer * jitterbuffer, guint32 expected,
    guint16 seqnum, GstClockTime dts, gint gap)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstClockTime total_duration, duration, expected_dts;
  TimerType type;

  GST_DEBUG_OBJECT (jitterbuffer,
      "dts %" GST_TIME_FORMAT ", last %" GST_TIME_FORMAT,
      GST_TIME_ARGS (dts), GST_TIME_ARGS (priv->last_in_dts));

  if (dts == GST_CLOCK_TIME_NONE) {
    GST_WARNING_OBJECT (jitterbuffer, "Have no DTS");
    return;
  }

  /* the total duration spanned by the missing packets */
  if (dts >= priv->last_in_dts)
    total_duration = dts - priv->last_in_dts;
  else
    total_duration = 0;

  /* interpolate between the current time and the last time based on
   * number of packets we are missing, this is the estimated duration
   * for the missing packet based on equidistant packet spacing. */
  duration = total_duration / (gap + 1);

  GST_DEBUG_OBJECT (jitterbuffer, "duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (duration));

  if (total_duration > priv->latency_ns) {
    GstClockTime gap_time;
    guint lost_packets;

    if (duration > 0) {
      GstClockTime gap_dur = gap * duration;
      if (gap_dur > priv->latency_ns)
        gap_time = gap_dur - priv->latency_ns;
      else
        gap_time = 0;
      lost_packets = gap_time / duration;
    } else {
      gap_time = total_duration - priv->latency_ns;
      lost_packets = gap;
    }

    /* too many lost packets, some of the missing packets are already
     * too late and we can generate lost packet events for them. */
    GST_DEBUG_OBJECT (jitterbuffer,
        "lost packets (%d, #%d->#%d) duration too large %" GST_TIME_FORMAT
        " > %" GST_TIME_FORMAT ", consider %u lost (%" GST_TIME_FORMAT ")",
        gap, expected, seqnum, GST_TIME_ARGS (total_duration),
        GST_TIME_ARGS (priv->latency_ns), lost_packets,
        GST_TIME_ARGS (gap_time));

    /* this timer will fire immediately and the lost event will be pushed from
     * the timer thread */
    if (lost_packets > 0) {
      add_timer (jitterbuffer, TIMER_TYPE_LOST, expected, lost_packets,
          priv->last_in_dts + duration, 0, gap_time);
      expected += lost_packets;
      priv->last_in_dts += gap_time;
    }
  }

  expected_dts = priv->last_in_dts + duration;

  if (priv->do_retransmission) {
    TimerData *timer;

    type = TIMER_TYPE_EXPECTED;
    /* if we had a timer for the first missing packet, update it. */
    if ((timer = find_timer (jitterbuffer, type, expected))) {
      GstClockTime timeout = timer->timeout;

      timer->duration = duration;
      if (timeout > (expected_dts + timer->rtx_retry)) {
        GstClockTime delay = timeout - expected_dts - timer->rtx_retry;
        reschedule_timer (jitterbuffer, timer, timer->seqnum, expected_dts,
            delay, TRUE);
      }
      expected++;
      expected_dts += duration;
    }
  } else {
    type = TIMER_TYPE_LOST;
  }

  while (gst_rtp_buffer_compare_seqnum (expected, seqnum) > 0) {
    add_timer (jitterbuffer, type, expected, 0, expected_dts, 0, duration);
    expected_dts += duration;
    expected++;
  }
}

static void
calculate_jitter (GstRtpJitterBuffer * jitterbuffer, GstClockTime dts,
    guint rtptime)
{
  gint32 rtpdiff;
  GstClockTimeDiff dtsdiff, rtpdiffns, diff;
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;

  if (G_UNLIKELY (dts == GST_CLOCK_TIME_NONE) || priv->clock_rate <= 0)
    goto no_time;

  if (priv->last_dts != -1)
    dtsdiff = dts - priv->last_dts;
  else
    dtsdiff = 0;

  if (priv->last_rtptime != -1)
    rtpdiff = rtptime - (guint32) priv->last_rtptime;
  else
    rtpdiff = 0;

  priv->last_dts = dts;
  priv->last_rtptime = rtptime;

  if (rtpdiff > 0)
    rtpdiffns =
        gst_util_uint64_scale_int (rtpdiff, GST_SECOND, priv->clock_rate);
  else
    rtpdiffns =
        -gst_util_uint64_scale_int (-rtpdiff, GST_SECOND, priv->clock_rate);

  diff = ABS (dtsdiff - rtpdiffns);

  /* jitter is stored in nanoseconds */
  priv->avg_jitter = (diff + (15 * priv->avg_jitter)) >> 4;

  GST_LOG_OBJECT (jitterbuffer,
      "dtsdiff %" GST_TIME_FORMAT " rtptime %" GST_TIME_FORMAT
      ", clock-rate %d, diff %" GST_TIME_FORMAT ", jitter: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (dtsdiff), GST_TIME_ARGS (rtpdiffns), priv->clock_rate,
      GST_TIME_ARGS (diff), GST_TIME_ARGS (priv->avg_jitter));

  return;

  /* ERRORS */
no_time:
  {
    GST_DEBUG_OBJECT (jitterbuffer,
        "no dts or no clock-rate, can't calculate jitter");
    return;
  }
}

static gint
compare_buffer_seqnum (GstBuffer * a, GstBuffer * b, gpointer user_data)
{
  GstRTPBuffer rtp_a = GST_RTP_BUFFER_INIT;
  GstRTPBuffer rtp_b = GST_RTP_BUFFER_INIT;
  guint seq_a, seq_b;

  gst_rtp_buffer_map (a, GST_MAP_READ, &rtp_a);
  seq_a = gst_rtp_buffer_get_seq (&rtp_a);
  gst_rtp_buffer_unmap (&rtp_a);

  gst_rtp_buffer_map (b, GST_MAP_READ, &rtp_b);
  seq_b = gst_rtp_buffer_get_seq (&rtp_b);
  gst_rtp_buffer_unmap (&rtp_b);

  return gst_rtp_buffer_compare_seqnum (seq_b, seq_a);
}

static gboolean
handle_big_gap_buffer (GstRtpJitterBuffer * jitterbuffer, gboolean future,
    GstBuffer * buffer, guint8 pt, guint16 seqnum, gint gap)
{
  GstRtpJitterBufferPrivate *priv;
  guint gap_packets_length;
  gboolean reset = FALSE;

  priv = jitterbuffer->priv;

  if ((gap_packets_length = g_queue_get_length (&priv->gap_packets)) > 0) {
    GList *l;
    guint32 prev_gap_seq = -1;
    gboolean all_consecutive = TRUE;

    g_queue_insert_sorted (&priv->gap_packets, buffer,
        (GCompareDataFunc) compare_buffer_seqnum, NULL);

    for (l = priv->gap_packets.head; l; l = l->next) {
      GstBuffer *gap_buffer = l->data;
      GstRTPBuffer gap_rtp = GST_RTP_BUFFER_INIT;
      guint32 gap_seq;

      gst_rtp_buffer_map (gap_buffer, GST_MAP_READ, &gap_rtp);

      all_consecutive = (gst_rtp_buffer_get_payload_type (&gap_rtp) == pt);

      gap_seq = gst_rtp_buffer_get_seq (&gap_rtp);
      if (prev_gap_seq == -1)
        prev_gap_seq = gap_seq;
      else if (gst_rtp_buffer_compare_seqnum (gap_seq, prev_gap_seq) != -1)
        all_consecutive = FALSE;
      else
        prev_gap_seq = gap_seq;

      gst_rtp_buffer_unmap (&gap_rtp);
      if (!all_consecutive)
        break;
    }

    if (all_consecutive && gap_packets_length > 3) {
      GST_DEBUG_OBJECT (jitterbuffer,
          "buffer too %s %d < %d, got 5 consecutive ones - reset",
          (future ? "new" : "old"), gap,
          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER));
      reset = TRUE;
    } else if (!all_consecutive) {
      g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
      g_queue_clear (&priv->gap_packets);
      GST_DEBUG_OBJECT (jitterbuffer,
          "buffer too %s %d < %d, got no 5 consecutive ones - dropping",
          (future ? "new" : "old"), gap,
          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER));
      buffer = NULL;
    } else {
      GST_DEBUG_OBJECT (jitterbuffer,
          "buffer too %s %d < %d, got %u consecutive ones - waiting",
          (future ? "new" : "old"), gap,
          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER),
          gap_packets_length + 1);
      buffer = NULL;
    }
  } else {
    GST_DEBUG_OBJECT (jitterbuffer,
        "buffer too %s %d < %d, first one - waiting", (future ? "new" : "old"),
        gap, -RTP_MAX_MISORDER);
    g_queue_push_tail (&priv->gap_packets, buffer);
    buffer = NULL;
  }

  return reset;
}

static GstClockTime
get_current_running_time (GstRtpJitterBuffer * jitterbuffer)
{
  GstClock *clock = gst_element_get_clock (GST_ELEMENT_CAST (jitterbuffer));
  GstClockTime running_time = GST_CLOCK_TIME_NONE;

  if (clock) {
    GstClockTime base_time =
        gst_element_get_base_time (GST_ELEMENT_CAST (jitterbuffer));
    GstClockTime clock_time = gst_clock_get_time (clock);

    if (clock_time > base_time)
      running_time = clock_time - base_time;
    else
      running_time = 0;

    gst_object_unref (clock);
  }

  return running_time;
}

static GstFlowReturn
gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;
  guint16 seqnum;
  guint32 expected, rtptime;
  GstFlowReturn ret = GST_FLOW_OK;
  GstClockTime dts, pts;
  guint64 latency_ts;
  gboolean head;
  gint percent = -1;
  guint8 pt;
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  gboolean do_next_seqnum = FALSE;
  RTPJitterBufferItem *item;
  GstMessage *msg = NULL;
  gboolean estimated_dts = FALSE;

  jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (parent);

  priv = jitterbuffer->priv;

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

  pt = gst_rtp_buffer_get_payload_type (&rtp);
  seqnum = gst_rtp_buffer_get_seq (&rtp);
  rtptime = gst_rtp_buffer_get_timestamp (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  /* make sure we have PTS and DTS set */
  pts = GST_BUFFER_PTS (buffer);
  dts = GST_BUFFER_DTS (buffer);
  if (dts == -1)
    dts = pts;
  else if (pts == -1)
    pts = dts;

  if (dts == -1) {
    /* If we have no DTS here, i.e. no capture time, get one from the
     * clock now to have something to calculate with in the future. */
    dts = get_current_running_time (jitterbuffer);
    pts = dts;

    /* Remember that we estimated the DTS if we are running already
     * and this is not our first packet (or first packet after a reset).
     * If it's the first packet, we somehow must generate a timestamp for
     * everything, otherwise we can't calculate any times
     */
    estimated_dts = (priv->next_in_seqnum != -1);
  } else {
    /* take the DTS of the buffer. This is the time when the packet was
     * received and is used to calculate jitter and clock skew. We will adjust
     * this DTS with the smoothed value after processing it in the
     * jitterbuffer and assign it as the PTS. */
    /* bring to running time */
    dts = gst_segment_to_running_time (&priv->segment, GST_FORMAT_TIME, dts);
  }

  GST_DEBUG_OBJECT (jitterbuffer,
      "Received packet #%d at time %" GST_TIME_FORMAT ", discont %d", seqnum,
      GST_TIME_ARGS (dts), GST_BUFFER_IS_DISCONT (buffer));

  JBUF_LOCK_CHECK (priv, out_flushing);

  if (G_UNLIKELY (priv->last_pt != pt)) {
    GstCaps *caps;

    GST_DEBUG_OBJECT (jitterbuffer, "pt changed from %u to %u", priv->last_pt,
        pt);

    priv->last_pt = pt;
    /* reset clock-rate so that we get a new one */
    priv->clock_rate = -1;

    /* Try to get the clock-rate from the caps first if we can. If there are no
     * caps we must fire the signal to get the clock-rate. */
    if ((caps = gst_pad_get_current_caps (pad))) {
      gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps);
      gst_caps_unref (caps);
    }
  }

  if (G_UNLIKELY (priv->clock_rate == -1)) {
    /* no clock rate given on the caps, try to get one with the signal */
    if (gst_rtp_jitter_buffer_get_clock_rate (jitterbuffer,
            pt) == GST_FLOW_FLUSHING)
      goto out_flushing;

    if (G_UNLIKELY (priv->clock_rate == -1))
      goto no_clock_rate;
  }

  /* don't accept more data on EOS */
  if (G_UNLIKELY (priv->eos))
    goto have_eos;

  calculate_jitter (jitterbuffer, dts, rtptime);

  if (priv->seqnum_base != -1) {
    gint gap;

    gap = gst_rtp_buffer_compare_seqnum (priv->seqnum_base, seqnum);

    if (gap < 0) {
      GST_DEBUG_OBJECT (jitterbuffer,
          "packet seqnum #%d before seqnum-base #%d", seqnum,
          priv->seqnum_base);
      gst_buffer_unref (buffer);
      ret = GST_FLOW_OK;
      goto finished;
    } else if (gap > 16384) {
      /* From now on don't compare against the seqnum base anymore as
       * at some point in the future we will wrap around and also that
       * much reordering is very unlikely */
      priv->seqnum_base = -1;
    }
  }

  expected = priv->next_in_seqnum;

  /* now check against our expected seqnum */
  if (G_LIKELY (expected != -1)) {
    gint gap;

    /* now calculate gap */
    gap = gst_rtp_buffer_compare_seqnum (expected, seqnum);

    GST_DEBUG_OBJECT (jitterbuffer, "expected #%d, got #%d, gap of %d",
        expected, seqnum, gap);

    if (G_LIKELY (gap == 0)) {
      /* packet is expected */
      calculate_packet_spacing (jitterbuffer, rtptime, dts);
      do_next_seqnum = TRUE;
    } else {
      gboolean reset = FALSE;

      if (gap < 0) {
        /* we received an old packet */
        if (G_UNLIKELY (gap != -1 && gap < -RTP_MAX_MISORDER)) {
          reset =
              handle_big_gap_buffer (jitterbuffer, FALSE, buffer, pt, seqnum,
              gap);
          buffer = NULL;
        } else {
          GST_DEBUG_OBJECT (jitterbuffer, "old packet received");
        }
      } else {
        /* new packet, we are missing some packets */
        if (G_UNLIKELY (priv->timers->len >= RTP_MAX_DROPOUT)) {
          /* If we have timers for more than RTP_MAX_DROPOUT packets
           * pending this means that we have a huge gap overall. We can
           * reset the jitterbuffer at this point because there's
           * just too much data missing to be able to do anything
           * sensible with the past data. Just try again from the
           * next packet */
          GST_WARNING_OBJECT (jitterbuffer,
              "%d pending timers > %d - resetting", priv->timers->len,
              RTP_MAX_DROPOUT);
          reset = TRUE;
          gst_buffer_unref (buffer);
          buffer = NULL;
        } else if (G_UNLIKELY (gap >= RTP_MAX_DROPOUT)) {
          reset =
              handle_big_gap_buffer (jitterbuffer, TRUE, buffer, pt, seqnum,
              gap);
          buffer = NULL;
        } else {
          GST_DEBUG_OBJECT (jitterbuffer, "%d missing packets", gap);
          /* fill in the gap with EXPECTED timers */
          calculate_expected (jitterbuffer, expected, seqnum, dts, gap);

          do_next_seqnum = TRUE;
        }
      }
      if (G_UNLIKELY (reset)) {
        GList *events = NULL, *l;
        GList *buffers;

        GST_DEBUG_OBJECT (jitterbuffer, "flush and reset jitterbuffer");
        rtp_jitter_buffer_flush (priv->jbuf,
            (GFunc) free_item_and_retain_events, &events);
        rtp_jitter_buffer_reset_skew (priv->jbuf);
        remove_all_timers (jitterbuffer);
        priv->discont = TRUE;
        priv->last_popped_seqnum = -1;
        priv->next_seqnum = seqnum;

        priv->last_in_seqnum = -1;
        priv->last_in_dts = -1;
        priv->next_in_seqnum = -1;

        /* Insert all sticky events again in order, otherwise we would
         * potentially loose STREAM_START, CAPS or SEGMENT events
         */
        events = g_list_reverse (events);
        for (l = events; l; l = l->next) {
          RTPJitterBufferItem *item;

          item = alloc_item (l->data, ITEM_TYPE_EVENT, -1, -1, -1, 0, -1);
          rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL);
        }
        g_list_free (events);

        JBUF_SIGNAL_EVENT (priv);

        /* reset spacing estimation when gap */
        priv->ips_rtptime = -1;
        priv->ips_dts = GST_CLOCK_TIME_NONE;

        buffers = g_list_copy (priv->gap_packets.head);
        g_queue_clear (&priv->gap_packets);

        priv->ips_rtptime = -1;
        priv->ips_dts = GST_CLOCK_TIME_NONE;
        JBUF_UNLOCK (jitterbuffer->priv);

        for (l = buffers; l; l = l->next) {
          ret = gst_rtp_jitter_buffer_chain (pad, parent, l->data);
          l->data = NULL;
          if (ret != GST_FLOW_OK)
            break;
        }
        for (; l; l = l->next)
          gst_buffer_unref (l->data);
        g_list_free (buffers);

        return ret;
      }
      /* reset spacing estimation when gap */
      priv->ips_rtptime = -1;
      priv->ips_dts = GST_CLOCK_TIME_NONE;
    }
  } else {
    GST_DEBUG_OBJECT (jitterbuffer, "First buffer #%d", seqnum);

    /* we don't know what the next_in_seqnum should be, wait for the last
     * possible moment to push this buffer, maybe we get an earlier seqnum
     * while we wait */
    set_timer (jitterbuffer, TIMER_TYPE_DEADLINE, seqnum, dts);
    do_next_seqnum = TRUE;
    /* take rtptime and dts to calculate packet spacing */
    priv->ips_rtptime = rtptime;
    priv->ips_dts = dts;
  }

  /* We had no huge gap, let's drop all the gap packets */
  if (buffer != NULL) {
    GST_DEBUG_OBJECT (jitterbuffer, "Clearing gap packets");
    g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
    g_queue_clear (&priv->gap_packets);
  } else {
    GST_DEBUG_OBJECT (jitterbuffer,
        "Had big gap, waiting for more consecutive packets");
    JBUF_UNLOCK (jitterbuffer->priv);
    return GST_FLOW_OK;
  }

  if (do_next_seqnum) {
    priv->last_in_seqnum = seqnum;
    priv->last_in_dts = dts;
    priv->next_in_seqnum = (seqnum + 1) & 0xffff;
  }

  /* let's check if this buffer is too late, we can only accept packets with
   * bigger seqnum than the one we last pushed. */
  if (G_LIKELY (priv->last_popped_seqnum != -1)) {
    gint gap;

    gap = gst_rtp_buffer_compare_seqnum (priv->last_popped_seqnum, seqnum);

    /* priv->last_popped_seqnum >= seqnum, we're too late. */
    if (G_UNLIKELY (gap <= 0))
      goto too_late;
  }

  /* let's drop oldest packet if the queue is already full and drop-on-latency
   * is set. We can only do this when there actually is a latency. When no
   * latency is set, we just pump it in the queue and let the other end push it
   * out as fast as possible. */
  if (priv->latency_ms && priv->drop_on_latency) {
    latency_ts =
        gst_util_uint64_scale_int (priv->latency_ms, priv->clock_rate, 1000);

    if (G_UNLIKELY (rtp_jitter_buffer_get_ts_diff (priv->jbuf) >= latency_ts)) {
      RTPJitterBufferItem *old_item;

      old_item = rtp_jitter_buffer_peek (priv->jbuf);

      if (IS_DROPABLE (old_item)) {
        old_item = rtp_jitter_buffer_pop (priv->jbuf, &percent);
        GST_DEBUG_OBJECT (jitterbuffer, "Queue full, dropping old packet %p",
            old_item);
        priv->next_seqnum = (old_item->seqnum + 1) & 0xffff;
        free_item (old_item);
      }
      /* we might have removed some head buffers, signal the pushing thread to
       * see if it can push now */
      JBUF_SIGNAL_EVENT (priv);
    }
  }

  /* If we estimated the DTS, don't consider it in the clock skew calculations
   * later. The code above always sets dts to pts or the other way around if
   * any of those is valid in the buffer, so we know that if we estimated the
   * dts that both are unknown */
  if (estimated_dts)
    item =
        alloc_item (buffer, ITEM_TYPE_BUFFER, GST_CLOCK_TIME_NONE,
        GST_CLOCK_TIME_NONE, seqnum, 1, rtptime);
  else
    item = alloc_item (buffer, ITEM_TYPE_BUFFER, dts, pts, seqnum, 1, rtptime);

  /* now insert the packet into the queue in sorted order. This function returns
   * FALSE if a packet with the same seqnum was already in the queue, meaning we
   * have a duplicate. */
  if (G_UNLIKELY (!rtp_jitter_buffer_insert (priv->jbuf, item,
              &head, &percent)))
    goto duplicate;

  /* update timers */
  update_timers (jitterbuffer, seqnum, dts, do_next_seqnum);

  /* we had an unhandled SR, handle it now */
  if (priv->last_sr)
    do_handle_sync (jitterbuffer);

  if (G_UNLIKELY (head)) {
    /* signal addition of new buffer when the _loop is waiting. */
    if (G_LIKELY (priv->active))
      JBUF_SIGNAL_EVENT (priv);

    /* let's unschedule and unblock any waiting buffers. We only want to do this
     * when the head buffer changed */
    if (G_UNLIKELY (priv->clock_id)) {
      GST_DEBUG_OBJECT (jitterbuffer, "Unscheduling waiting new buffer");
      unschedule_current_timer (jitterbuffer);
    }
  }

  GST_DEBUG_OBJECT (jitterbuffer,
      "Pushed packet #%d, now %d packets, head: %d, " "percent %d", seqnum,
      rtp_jitter_buffer_num_packets (priv->jbuf), head, percent);

  msg = check_buffering_percent (jitterbuffer, percent);

finished:
  JBUF_UNLOCK (priv);

  if (msg)
    gst_element_post_message (GST_ELEMENT_CAST (jitterbuffer), msg);

  return ret;

  /* ERRORS */
invalid_buffer:
  {
    /* this is not fatal but should be filtered earlier */
    GST_ELEMENT_WARNING (jitterbuffer, STREAM, DECODE, (NULL),
        ("Received invalid RTP payload, dropping"));
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
no_clock_rate:
  {
    GST_WARNING_OBJECT (jitterbuffer,
        "No clock-rate in caps!, dropping buffer");
    gst_buffer_unref (buffer);
    goto finished;
  }
out_flushing:
  {
    ret = priv->srcresult;
    GST_DEBUG_OBJECT (jitterbuffer, "flushing %s", gst_flow_get_name (ret));
    gst_buffer_unref (buffer);
    goto finished;
  }
have_eos:
  {
    ret = GST_FLOW_EOS;
    GST_WARNING_OBJECT (jitterbuffer, "we are EOS, refusing buffer");
    gst_buffer_unref (buffer);
    goto finished;
  }
too_late:
  {
    GST_WARNING_OBJECT (jitterbuffer, "Packet #%d too late as #%d was already"
        " popped, dropping", seqnum, priv->last_popped_seqnum);
    priv->num_late++;
    gst_buffer_unref (buffer);
    goto finished;
  }
duplicate:
  {
    GST_WARNING_OBJECT (jitterbuffer, "Duplicate packet #%d detected, dropping",
        seqnum);
    priv->num_duplicates++;
    free_item (item);
    goto finished;
  }
}

static GstClockTime
compute_elapsed (GstRtpJitterBuffer * jitterbuffer, RTPJitterBufferItem * item)
{
  guint64 ext_time, elapsed;
  guint32 rtp_time;
  GstRtpJitterBufferPrivate *priv;

  priv = jitterbuffer->priv;
  rtp_time = item->rtptime;

  GST_LOG_OBJECT (jitterbuffer, "rtp %" G_GUINT32_FORMAT ", ext %"
      G_GUINT64_FORMAT, rtp_time, priv->ext_timestamp);

  ext_time = priv->ext_timestamp;
  ext_time = gst_rtp_buffer_ext_timestamp (&ext_time, rtp_time);
  if (ext_time < priv->ext_timestamp) {
    ext_time = priv->ext_timestamp;
  } else {
    priv->ext_timestamp = ext_time;
  }

  if (ext_time > priv->clock_base)
    elapsed = ext_time - priv->clock_base;
  else
    elapsed = 0;

  elapsed = gst_util_uint64_scale_int (elapsed, GST_SECOND, priv->clock_rate);
  return elapsed;
}

static void
update_estimated_eos (GstRtpJitterBuffer * jitterbuffer,
    RTPJitterBufferItem * item)
{
  guint64 total, elapsed, left, estimated;
  GstClockTime out_time;
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  if (priv->npt_stop == -1 || priv->ext_timestamp == -1
      || priv->clock_base == -1 || priv->clock_rate <= 0)
    return;

  /* compute the elapsed time */
  elapsed = compute_elapsed (jitterbuffer, item);

  /* do nothing if elapsed time doesn't increment */
  if (priv->last_elapsed && elapsed <= priv->last_elapsed)
    return;

  priv->last_elapsed = elapsed;

  /* this is the total time we need to play */
  total = priv->npt_stop - priv->npt_start;
  GST_LOG_OBJECT (jitterbuffer, "total %" GST_TIME_FORMAT,
      GST_TIME_ARGS (total));

  /* this is how much time there is left */
  if (total > elapsed)
    left = total - elapsed;
  else
    left = 0;

  /* if we have less time left that the size of the buffer, we will not
   * be able to keep it filled, disabled buffering then */
  if (left < rtp_jitter_buffer_get_delay (priv->jbuf)) {
    GST_DEBUG_OBJECT (jitterbuffer, "left %" GST_TIME_FORMAT
        ", disable buffering close to EOS", GST_TIME_ARGS (left));
    rtp_jitter_buffer_disable_buffering (priv->jbuf, TRUE);
  }

  /* this is the current time as running-time */
  out_time = item->dts;

  if (elapsed > 0)
    estimated = gst_util_uint64_scale (out_time, total, elapsed);
  else {
    /* if there is almost nothing left,
     * we may never advance enough to end up in the above case */
    if (total < GST_SECOND)
      estimated = GST_SECOND;
    else
      estimated = -1;
  }
  GST_LOG_OBJECT (jitterbuffer, "elapsed %" GST_TIME_FORMAT ", estimated %"
      GST_TIME_FORMAT, GST_TIME_ARGS (elapsed), GST_TIME_ARGS (estimated));

  if (estimated != -1 && priv->estimated_eos != estimated) {
    set_timer (jitterbuffer, TIMER_TYPE_EOS, -1, estimated);
    priv->estimated_eos = estimated;
  }
}

/* take a buffer from the queue and push it */
static GstFlowReturn
pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint seqnum)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstFlowReturn result = GST_FLOW_OK;
  RTPJitterBufferItem *item;
  GstBuffer *outbuf = NULL;
  GstEvent *outevent = NULL;
  GstQuery *outquery = NULL;
  GstClockTime dts, pts;
  gint percent = -1;
  gboolean do_push = TRUE;
  guint type;
  GstMessage *msg;

  /* when we get here we are ready to pop and push the buffer */
  item = rtp_jitter_buffer_pop (priv->jbuf, &percent);
  type = item->type;

  switch (type) {
    case ITEM_TYPE_BUFFER:

      /* we need to make writable to change the flags and timestamps */
      outbuf = gst_buffer_make_writable (item->data);

      if (G_UNLIKELY (priv->discont)) {
        /* set DISCONT flag when we missed a packet. We pushed the buffer writable
         * into the jitterbuffer so we can modify now. */
        GST_DEBUG_OBJECT (jitterbuffer, "mark output buffer discont");
        GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
        priv->discont = FALSE;
      }
      if (G_UNLIKELY (priv->ts_discont)) {
        GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_RESYNC);
        priv->ts_discont = FALSE;
      }

      dts =
          gst_segment_to_position (&priv->segment, GST_FORMAT_TIME, item->dts);
      pts =
          gst_segment_to_position (&priv->segment, GST_FORMAT_TIME, item->pts);

      /* apply timestamp with offset to buffer now */
      GST_BUFFER_DTS (outbuf) = apply_offset (jitterbuffer, dts);
      GST_BUFFER_PTS (outbuf) = apply_offset (jitterbuffer, pts);

      /* update the elapsed time when we need to check against the npt stop time. */
      update_estimated_eos (jitterbuffer, item);

      priv->last_out_time = GST_BUFFER_PTS (outbuf);
      break;
    case ITEM_TYPE_LOST:
      priv->discont = TRUE;
      if (!priv->do_lost)
        do_push = FALSE;
      /* FALLTHROUGH */
    case ITEM_TYPE_EVENT:
      outevent = item->data;
      break;
    case ITEM_TYPE_QUERY:
      outquery = item->data;
      break;
  }

  /* now we are ready to push the buffer. Save the seqnum and release the lock
   * so the other end can push stuff in the queue again. */
  if (seqnum != -1) {
    priv->last_popped_seqnum = seqnum;
    priv->next_seqnum = (seqnum + item->count) & 0xffff;
  }
  msg = check_buffering_percent (jitterbuffer, percent);
  JBUF_UNLOCK (priv);

  item->data = NULL;
  free_item (item);

  if (msg)
    gst_element_post_message (GST_ELEMENT_CAST (jitterbuffer), msg);

  switch (type) {
    case ITEM_TYPE_BUFFER:
      /* push buffer */
      GST_DEBUG_OBJECT (jitterbuffer,
          "Pushing buffer %d, dts %" GST_TIME_FORMAT ", pts %" GST_TIME_FORMAT,
          seqnum, GST_TIME_ARGS (GST_BUFFER_DTS (outbuf)),
          GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)));
      result = gst_pad_push (priv->srcpad, outbuf);

      JBUF_LOCK_CHECK (priv, out_flushing);
      break;
    case ITEM_TYPE_LOST:
    case ITEM_TYPE_EVENT:
      /* We got not enough consecutive packets with a huge gap, we can
       * as well just drop them here now on EOS */
      if (GST_EVENT_TYPE (outevent) == GST_EVENT_EOS) {
        GST_DEBUG_OBJECT (jitterbuffer, "Clearing gap packets on EOS");
        g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
        g_queue_clear (&priv->gap_packets);
      }

      GST_DEBUG_OBJECT (jitterbuffer, "%sPushing event %" GST_PTR_FORMAT
          ", seqnum %d", do_push ? "" : "NOT ", outevent, seqnum);

      if (do_push)
        gst_pad_push_event (priv->srcpad, outevent);
      else
        gst_event_unref (outevent);

      result = GST_FLOW_OK;

      JBUF_LOCK_CHECK (priv, out_flushing);
      break;
    case ITEM_TYPE_QUERY:
    {
      gboolean res;

      res = gst_pad_peer_query (priv->srcpad, outquery);

      JBUF_LOCK_CHECK (priv, out_flushing);
      result = GST_FLOW_OK;
      GST_LOG_OBJECT (jitterbuffer, "did query %p, return %d", outquery, res);
      JBUF_SIGNAL_QUERY (priv, res);
      break;
    }
  }
  return result;

  /* ERRORS */
out_flushing:
  {
    return priv->srcresult;
  }
}

#define GST_FLOW_WAIT GST_FLOW_CUSTOM_SUCCESS

/* Peek a buffer and compare the seqnum to the expected seqnum.
 * If all is fine, the buffer is pushed.
 * If something is wrong, we wait for some event
 */
static GstFlowReturn
handle_next_buffer (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstFlowReturn result;
  RTPJitterBufferItem *item;
  guint seqnum;
  guint32 next_seqnum;

  /* only push buffers when PLAYING and active and not buffering */
  if (priv->blocked || !priv->active ||
      rtp_jitter_buffer_is_buffering (priv->jbuf)) {
    return GST_FLOW_WAIT;
  }

  /* peek a buffer, we're just looking at the sequence number.
   * If all is fine, we'll pop and push it. If the sequence number is wrong we
   * wait for a timeout or something to change.
   * The peeked buffer is valid for as long as we hold the jitterbuffer lock. */
  item = rtp_jitter_buffer_peek (priv->jbuf);
  if (item == NULL) {
    goto wait;
  }

  /* get the seqnum and the next expected seqnum */
  seqnum = item->seqnum;
  if (seqnum == -1) {
    return pop_and_push_next (jitterbuffer, seqnum);
  }

  next_seqnum = priv->next_seqnum;

  /* get the gap between this and the previous packet. If we don't know the
   * previous packet seqnum assume no gap. */
  if (G_UNLIKELY (next_seqnum == -1)) {
    GST_DEBUG_OBJECT (jitterbuffer, "First buffer #%d", seqnum);
    /* we don't know what the next_seqnum should be, the chain function should
     * have scheduled a DEADLINE timer that will increment next_seqnum when it
     * fires, so wait for that */
    result = GST_FLOW_WAIT;
  } else {
    gint gap = gst_rtp_buffer_compare_seqnum (next_seqnum, seqnum);

    if (G_LIKELY (gap == 0)) {
      /* no missing packet, pop and push */
      result = pop_and_push_next (jitterbuffer, seqnum);
    } else if (G_UNLIKELY (gap < 0)) {
      /* if we have a packet that we already pushed or considered dropped, pop it
       * off and get the next packet */
      GST_DEBUG_OBJECT (jitterbuffer, "Old packet #%d, next #%d dropping",
          seqnum, next_seqnum);
      item = rtp_jitter_buffer_pop (priv->jbuf, NULL);
      free_item (item);
      result = GST_FLOW_OK;
    } else {
      /* the chain function has scheduled timers to request retransmission or
       * when to consider the packet lost, wait for that */
      GST_DEBUG_OBJECT (jitterbuffer,
          "Sequence number GAP detected: expected %d instead of %d (%d missing)",
          next_seqnum, seqnum, gap);
      result = GST_FLOW_WAIT;
    }
  }

  return result;

wait:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "no buffer, going to wait");
    if (priv->eos) {
      return GST_FLOW_EOS;
    } else {
      return GST_FLOW_WAIT;
    }
  }
}

static GstClockTime
get_rtx_retry_timeout (GstRtpJitterBufferPrivate * priv)
{
  GstClockTime rtx_retry_timeout;
  GstClockTime rtx_min_retry_timeout;

  if (priv->rtx_retry_timeout == -1) {
    if (priv->avg_rtx_rtt == 0)
      rtx_retry_timeout = DEFAULT_AUTO_RTX_TIMEOUT;
    else
      /* we want to ask for a retransmission after we waited for a
       * complete RTT and the additional jitter */
      rtx_retry_timeout = priv->avg_rtx_rtt + priv->avg_jitter * 2;
  } else {
    rtx_retry_timeout = priv->rtx_retry_timeout * GST_MSECOND;
  }
  /* make sure we don't retry too often. On very low latency networks,
   * the RTT and jitter can be very low. */
  if (priv->rtx_min_retry_timeout == -1) {
    rtx_min_retry_timeout = priv->packet_spacing;
  } else {
    rtx_min_retry_timeout = priv->rtx_min_retry_timeout * GST_MSECOND;
  }
  rtx_retry_timeout = MAX (rtx_retry_timeout, rtx_min_retry_timeout);

  return rtx_retry_timeout;
}

static GstClockTime
get_rtx_retry_period (GstRtpJitterBufferPrivate * priv,
    GstClockTime rtx_retry_timeout)
{
  GstClockTime rtx_retry_period;

  if (priv->rtx_retry_period == -1) {
    /* we retry up to the configured jitterbuffer size but leaving some
     * room for the retransmission to arrive in time */
    if (rtx_retry_timeout > priv->latency_ns) {
      rtx_retry_period = 0;
    } else {
      rtx_retry_period = priv->latency_ns - rtx_retry_timeout;
    }
  } else {
    rtx_retry_period = priv->rtx_retry_period * GST_MSECOND;
  }
  return rtx_retry_period;
}

/* the timeout for when we expected a packet expired */
static gboolean
do_expected_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    GstClockTime now)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstEvent *event;
  guint delay, delay_ms, avg_rtx_rtt_ms;
  guint rtx_retry_timeout_ms, rtx_retry_period_ms;
  GstClockTime rtx_retry_period;
  GstClockTime rtx_retry_timeout;
  GstClock *clock;

  GST_DEBUG_OBJECT (jitterbuffer, "expected %d didn't arrive, now %"
      GST_TIME_FORMAT, timer->seqnum, GST_TIME_ARGS (now));

  rtx_retry_timeout = get_rtx_retry_timeout (priv);
  rtx_retry_period = get_rtx_retry_period (priv, rtx_retry_timeout);

  GST_DEBUG_OBJECT (jitterbuffer, "timeout %" GST_TIME_FORMAT ", period %"
      GST_TIME_FORMAT, GST_TIME_ARGS (rtx_retry_timeout),
      GST_TIME_ARGS (rtx_retry_period));

  delay = timer->rtx_delay + timer->rtx_retry;

  delay_ms = GST_TIME_AS_MSECONDS (delay);
  rtx_retry_timeout_ms = GST_TIME_AS_MSECONDS (rtx_retry_timeout);
  rtx_retry_period_ms = GST_TIME_AS_MSECONDS (rtx_retry_period);
  avg_rtx_rtt_ms = GST_TIME_AS_MSECONDS (priv->avg_rtx_rtt);

  event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
      gst_structure_new ("GstRTPRetransmissionRequest",
          "seqnum", G_TYPE_UINT, (guint) timer->seqnum,
          "running-time", G_TYPE_UINT64, timer->rtx_base,
          "delay", G_TYPE_UINT, delay_ms,
          "retry", G_TYPE_UINT, timer->num_rtx_retry,
          "frequency", G_TYPE_UINT, rtx_retry_timeout_ms,
          "period", G_TYPE_UINT, rtx_retry_period_ms,
          "deadline", G_TYPE_UINT, priv->latency_ms,
          "packet-spacing", G_TYPE_UINT64, priv->packet_spacing,
          "avg-rtt", G_TYPE_UINT, avg_rtx_rtt_ms, NULL));

  priv->num_rtx_requests++;
  timer->num_rtx_retry++;

  GST_OBJECT_LOCK (jitterbuffer);
  if ((clock = GST_ELEMENT_CLOCK (jitterbuffer))) {
    timer->rtx_last = gst_clock_get_time (clock);
    timer->rtx_last -= GST_ELEMENT_CAST (jitterbuffer)->base_time;
  } else {
    timer->rtx_last = now;
  }
  GST_OBJECT_UNLOCK (jitterbuffer);

  /* calculate the timeout for the next retransmission attempt */
  timer->rtx_retry += rtx_retry_timeout;
  GST_DEBUG_OBJECT (jitterbuffer, "base %" GST_TIME_FORMAT ", delay %"
      GST_TIME_FORMAT ", retry %" GST_TIME_FORMAT ", num_retry %u",
      GST_TIME_ARGS (timer->rtx_base), GST_TIME_ARGS (timer->rtx_delay),
      GST_TIME_ARGS (timer->rtx_retry), timer->num_rtx_retry);
  if ((priv->rtx_max_retries != -1
          && timer->num_rtx_retry >= priv->rtx_max_retries)
      || (timer->rtx_retry + timer->rtx_delay > rtx_retry_period)) {
    GST_DEBUG_OBJECT (jitterbuffer, "reschedule as LOST timer");
    /* too many retransmission request, we now convert the timer
     * to a lost timer, leave the num_rtx_retry as it is for stats */
    timer->type = TIMER_TYPE_LOST;
    timer->rtx_delay = 0;
    timer->rtx_retry = 0;
  }
  reschedule_timer (jitterbuffer, timer, timer->seqnum,
      timer->rtx_base + timer->rtx_retry, timer->rtx_delay, FALSE);

  JBUF_UNLOCK (priv);
  gst_pad_push_event (priv->sinkpad, event);
  JBUF_LOCK (priv);

  return FALSE;
}

/* a packet is lost */
static gboolean
do_lost_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    GstClockTime now)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstClockTime duration, timestamp;
  guint seqnum, lost_packets, num_rtx_retry, next_in_seqnum;
  gboolean head;
  GstEvent *event;
  RTPJitterBufferItem *item;

  seqnum = timer->seqnum;
  timestamp = apply_offset (jitterbuffer, timer->timeout);
  duration = timer->duration;
  if (duration == GST_CLOCK_TIME_NONE && priv->packet_spacing > 0)
    duration = priv->packet_spacing;
  lost_packets = MAX (timer->num, 1);
  num_rtx_retry = timer->num_rtx_retry;

  /* we had a gap and thus we lost some packets. Create an event for this.  */
  if (lost_packets > 1)
    GST_DEBUG_OBJECT (jitterbuffer, "Packets #%d -> #%d lost", seqnum,
        seqnum + lost_packets - 1);
  else
    GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", seqnum);

  priv->num_late += lost_packets;
  priv->num_rtx_failed += num_rtx_retry;

  next_in_seqnum = (seqnum + lost_packets) & 0xffff;

  /* we now only accept seqnum bigger than this */
  if (gst_rtp_buffer_compare_seqnum (priv->next_in_seqnum, next_in_seqnum) > 0)
    priv->next_in_seqnum = next_in_seqnum;

  /* create paket lost event */
  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
      gst_structure_new ("GstRTPPacketLost",
          "seqnum", G_TYPE_UINT, (guint) seqnum,
          "timestamp", G_TYPE_UINT64, timestamp,
          "duration", G_TYPE_UINT64, duration,
          "retry", G_TYPE_UINT, num_rtx_retry, NULL));

  item = alloc_item (event, ITEM_TYPE_LOST, -1, -1, seqnum, lost_packets, -1);
  rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL);

  /* remove timer now */
  remove_timer (jitterbuffer, timer);
  if (head)
    JBUF_SIGNAL_EVENT (priv);

  return TRUE;
}

static gboolean
do_eos_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    GstClockTime now)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  GST_INFO_OBJECT (jitterbuffer, "got the NPT timeout");
  remove_timer (jitterbuffer, timer);
  if (!priv->eos) {
    /* there was no EOS in the buffer, put one in there now */
    queue_event (jitterbuffer, gst_event_new_eos ());
  }
  JBUF_SIGNAL_EVENT (priv);

  return TRUE;
}

static gboolean
do_deadline_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    GstClockTime now)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;

  GST_INFO_OBJECT (jitterbuffer, "got deadline timeout");

  /* timer seqnum might have been obsoleted by caps seqnum-base,
   * only mess with current ongoing seqnum if still unknown */
  if (priv->next_seqnum == -1)
    priv->next_seqnum = timer->seqnum;
  remove_timer (jitterbuffer, timer);
  JBUF_SIGNAL_EVENT (priv);

  return TRUE;
}

static gboolean
do_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
    GstClockTime now)
{
  gboolean removed = FALSE;

  switch (timer->type) {
    case TIMER_TYPE_EXPECTED:
      removed = do_expected_timeout (jitterbuffer, timer, now);
      break;
    case TIMER_TYPE_LOST:
      removed = do_lost_timeout (jitterbuffer, timer, now);
      break;
    case TIMER_TYPE_DEADLINE:
      removed = do_deadline_timeout (jitterbuffer, timer, now);
      break;
    case TIMER_TYPE_EOS:
      removed = do_eos_timeout (jitterbuffer, timer, now);
      break;
  }
  return removed;
}

/* called when we need to wait for the next timeout.
 *
 * We loop over the array of recorded timeouts and wait for the earliest one.
 * When it timed out, do the logic associated with the timer.
 *
 * If there are no timers, we wait on a gcond until something new happens.
 */
static void
wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
  GstClockTime now = 0;

  JBUF_LOCK (priv);
  while (priv->timer_running) {
    TimerData *timer = NULL;
    GstClockTime timer_timeout = -1;
    gint i, len;

    /* If we have a clock, update "now" now with the very latest running time
     * we have. It is used below when timeouts are triggered to calculate
     * any next possible timeout. If we only update it after waiting for the
     * clock, we would give a too old time to the timeout functions.
     */
    GST_OBJECT_LOCK (jitterbuffer);
    if (GST_ELEMENT_CLOCK (jitterbuffer)) {
      now =
          gst_clock_get_time (GST_ELEMENT_CLOCK (jitterbuffer)) -
          GST_ELEMENT_CAST (jitterbuffer)->base_time;
    }
    GST_OBJECT_UNLOCK (jitterbuffer);

    GST_DEBUG_OBJECT (jitterbuffer, "now %" GST_TIME_FORMAT,
        GST_TIME_ARGS (now));

    len = priv->timers->len;
    for (i = 0; i < len; i++) {
      TimerData *test = &g_array_index (priv->timers, TimerData, i);
      GstClockTime test_timeout = get_timeout (jitterbuffer, test);
      gboolean save_best = FALSE;

      GST_DEBUG_OBJECT (jitterbuffer, "%d, %d, %d, %" GST_TIME_FORMAT,
          i, test->type, test->seqnum, GST_TIME_ARGS (test_timeout));

      /* find the smallest timeout */
      if (timer == NULL) {
        save_best = TRUE;
      } else if (timer_timeout == -1) {
        /* we already have an immediate timeout, the new timer must be an
         * immediate timer with smaller seqnum to become the best */
        if (test_timeout == -1
            && (gst_rtp_buffer_compare_seqnum (test->seqnum,
                    timer->seqnum) > 0))
          save_best = TRUE;
      } else if (test_timeout == -1) {
        /* first immediate timer */
        save_best = TRUE;
      } else if (test_timeout < timer_timeout) {
        /* earlier timer */
        save_best = TRUE;
      } else if (test_timeout == timer_timeout
          && (gst_rtp_buffer_compare_seqnum (test->seqnum,
                  timer->seqnum) > 0)) {
        /* same timer, smaller seqnum */
        save_best = TRUE;
      }
      if (save_best) {
        GST_DEBUG_OBJECT (jitterbuffer, "new best %d", i);
        timer = test;
        timer_timeout = test_timeout;
      }
    }
    if (timer && !priv->blocked) {
      GstClock *clock;
      GstClockTime sync_time;
      GstClockID id;
      GstClockReturn ret;
      GstClockTimeDiff clock_jitter;

      if (timer_timeout == -1 || timer_timeout <= now) {
        do_timeout (jitterbuffer, timer, now);
        /* check here, do_timeout could have released the lock */
        if (!priv->timer_running)
          break;
        continue;
      }

      GST_OBJECT_LOCK (jitterbuffer);
      clock = GST_ELEMENT_CLOCK (jitterbuffer);
      if (!clock) {
        GST_OBJECT_UNLOCK (jitterbuffer);
        /* let's just push if there is no clock */
        GST_DEBUG_OBJECT (jitterbuffer, "No clock, timeout right away");
        now = timer_timeout;
        continue;
      }

      /* prepare for sync against clock */
      sync_time = timer_timeout + GST_ELEMENT_CAST (jitterbuffer)->base_time;
      /* add latency of peer to get input time */
      sync_time += priv->peer_latency;

      GST_DEBUG_OBJECT (jitterbuffer, "sync to timestamp %" GST_TIME_FORMAT
          " with sync time %" GST_TIME_FORMAT,
          GST_TIME_ARGS (timer_timeout), GST_TIME_ARGS (sync_time));

      /* create an entry for the clock */
      id = priv->clock_id = gst_clock_new_single_shot_id (clock, sync_time);
      priv->timer_timeout = timer_timeout;
      priv->timer_seqnum = timer->seqnum;
      GST_OBJECT_UNLOCK (jitterbuffer);

      /* release the lock so that the other end can push stuff or unlock */
      JBUF_UNLOCK (priv);

      ret = gst_clock_id_wait (id, &clock_jitter);

      JBUF_LOCK (priv);
      if (!priv->timer_running) {
        gst_clock_id_unref (id);
        priv->clock_id = NULL;
        break;
      }

      if (ret != GST_CLOCK_UNSCHEDULED) {
        GST_DEBUG_OBJECT (jitterbuffer, "sync done, %d, #%d, %" G_GINT64_FORMAT,
            ret, priv->timer_seqnum, clock_jitter);
      } else {
        GST_DEBUG_OBJECT (jitterbuffer, "sync unscheduled");
      }
      /* and free the entry */
      gst_clock_id_unref (id);
      priv->clock_id = NULL;
    } else {
      /* no timers, wait for activity */
      JBUF_WAIT_TIMER (priv);
    }
  }
  JBUF_UNLOCK (priv);

  GST_DEBUG_OBJECT (jitterbuffer, "we are stopping");
  return;
}

/*
 * This funcion implements the main pushing loop on the source pad.
 *
 * It first tries to push as many buffers as possible. If there is a seqnum
 * mismatch, we wait for the next timeouts.
 */
static void
gst_rtp_jitter_buffer_loop (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;
  GstFlowReturn result = GST_FLOW_OK;

  priv = jitterbuffer->priv;

  JBUF_LOCK_CHECK (priv, flushing);
  do {
    result = handle_next_buffer (jitterbuffer);
    if (G_LIKELY (result == GST_FLOW_WAIT)) {
      /* now wait for the next event */
      JBUF_WAIT_EVENT (priv, flushing);
      result = GST_FLOW_OK;
    }
  } while (result == GST_FLOW_OK);
  /* store result for upstream */
  priv->srcresult = result;
  /* if we get here we need to pause */
  goto pause;

  /* ERRORS */
flushing:
  {
    result = priv->srcresult;
    goto pause;
  }
pause:
  {
    GstEvent *event;

    JBUF_SIGNAL_QUERY (priv, FALSE);
    JBUF_UNLOCK (priv);

    GST_DEBUG_OBJECT (jitterbuffer, "pausing task, reason %s",
        gst_flow_get_name (result));
    gst_pad_pause_task (priv->srcpad);
    if (result == GST_FLOW_EOS) {
      event = gst_event_new_eos ();
      gst_pad_push_event (priv->srcpad, event);
    }
    return;
  }
}

/* collect the info from the lastest RTCP packet and the jitterbuffer sync, do
 * some sanity checks and then emit the handle-sync signal with the parameters.
 * This function must be called with the LOCK */
static void
do_handle_sync (GstRtpJitterBuffer * jitterbuffer)
{
  GstRtpJitterBufferPrivate *priv;
  guint64 base_rtptime, base_time;
  guint32 clock_rate;
  guint64 last_rtptime;
  guint64 clock_base;
  guint64 ext_rtptime, diff;
  gboolean valid = TRUE, keep = FALSE;

  priv = jitterbuffer->priv;

  /* get the last values from the jitterbuffer */
  rtp_jitter_buffer_get_sync (priv->jbuf, &base_rtptime, &base_time,
      &clock_rate, &last_rtptime);

  clock_base = priv->clock_base;
  ext_rtptime = priv->ext_rtptime;

  GST_DEBUG_OBJECT (jitterbuffer, "ext SR %" G_GUINT64_FORMAT ", base %"
      G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT
      ", clock-base %" G_GUINT64_FORMAT ", last-rtptime %" G_GUINT64_FORMAT,
      ext_rtptime, base_rtptime, clock_rate, clock_base, last_rtptime);

  if (base_rtptime == -1 || clock_rate == -1 || base_time == -1) {
    /* we keep this SR packet for later. When we get a valid RTP packet the
     * above values will be set and we can try to use the SR packet */
    GST_DEBUG_OBJECT (jitterbuffer, "keeping for later, no RTP values");
    keep = TRUE;
  } else {
    /* we can't accept anything that happened before we did the last resync */
    if (base_rtptime > ext_rtptime) {
      GST_DEBUG_OBJECT (jitterbuffer, "dropping, older than base time");
      valid = FALSE;
    } else {
      /* the SR RTP timestamp must be something close to what we last observed
       * in the jitterbuffer */
      if (ext_rtptime > last_rtptime) {
        /* check how far ahead it is to our RTP timestamps */
        diff = ext_rtptime - last_rtptime;
        /* if bigger than 1 second, we drop it */
        if (diff > clock_rate) {
          GST_DEBUG_OBJECT (jitterbuffer, "too far ahead");
          /* should drop this, but some RTSP servers end up with bogus
           * way too ahead RTCP packet when repeated PAUSE/PLAY,
           * so still trigger rptbin sync but invalidate RTCP data
           * (sync might use other methods) */
          ext_rtptime = -1;
        }
        GST_DEBUG_OBJECT (jitterbuffer, "ext last %" G_GUINT64_FORMAT ", diff %"
            G_GUINT64_FORMAT, last_rtptime, diff);
      }
    }
  }

  if (keep) {
    GST_DEBUG_OBJECT (jitterbuffer, "keeping RTCP packet for later");
  } else if (valid) {
    GstStructure *s;

    s = gst_structure_new ("application/x-rtp-sync",
        "base-rtptime", G_TYPE_UINT64, base_rtptime,
        "base-time", G_TYPE_UINT64, base_time,
        "clock-rate", G_TYPE_UINT, clock_rate,
        "clock-base", G_TYPE_UINT64, clock_base,
        "sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime,
        "sr-buffer", GST_TYPE_BUFFER, priv->last_sr, NULL);

    GST_DEBUG_OBJECT (jitterbuffer, "signaling sync");
    gst_buffer_replace (&priv->last_sr, NULL);
    JBUF_UNLOCK (priv);
    g_signal_emit (jitterbuffer,
        gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC], 0, s);
    JBUF_LOCK (priv);
    gst_structure_free (s);
  } else {
    GST_DEBUG_OBJECT (jitterbuffer, "dropping RTCP packet");
    gst_buffer_replace (&priv->last_sr, NULL);
  }
}

static GstFlowReturn
gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 ssrc;
  GstRTCPPacket packet;
  guint64 ext_rtptime;
  guint32 rtptime;
  GstRTCPBuffer rtcp = { NULL, };

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);

  if (G_UNLIKELY (!gst_rtcp_buffer_validate_reduced (buffer)))
    goto invalid_buffer;

  priv = jitterbuffer->priv;

  gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp);

  if (!gst_rtcp_buffer_get_first_packet (&rtcp, &packet))
    goto empty_buffer;

  /* first packet must be SR or RR or else the validate would have failed */
  switch (gst_rtcp_packet_get_type (&packet)) {
    case GST_RTCP_TYPE_SR:
      gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, NULL, &rtptime,
          NULL, NULL);
      break;
    default:
      goto ignore_buffer;
  }
  gst_rtcp_buffer_unmap (&rtcp);

  GST_DEBUG_OBJECT (jitterbuffer, "received RTCP of SSRC %08x", ssrc);

  JBUF_LOCK (priv);
  /* convert the RTP timestamp to our extended timestamp, using the same offset
   * we used in the jitterbuffer */
  ext_rtptime = priv->jbuf->ext_rtptime;
  ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);

  priv->ext_rtptime = ext_rtptime;
  gst_buffer_replace (&priv->last_sr, buffer);

  do_handle_sync (jitterbuffer);
  JBUF_UNLOCK (priv);

done:
  gst_buffer_unref (buffer);

  return ret;

invalid_buffer:
  {
    /* this is not fatal but should be filtered earlier */
    GST_ELEMENT_WARNING (jitterbuffer, STREAM, DECODE, (NULL),
        ("Received invalid RTCP payload, dropping"));
    ret = GST_FLOW_OK;
    goto done;
  }
empty_buffer:
  {
    /* this is not fatal but should be filtered earlier */
    GST_ELEMENT_WARNING (jitterbuffer, STREAM, DECODE, (NULL),
        ("Received empty RTCP payload, dropping"));
    gst_rtcp_buffer_unmap (&rtcp);
    ret = GST_FLOW_OK;
    goto done;
  }
ignore_buffer:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "ignoring RTCP packet");
    gst_rtcp_buffer_unmap (&rtcp);
    ret = GST_FLOW_OK;
    goto done;
  }
}

static gboolean
gst_rtp_jitter_buffer_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean res = FALSE;
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);
  priv = jitterbuffer->priv;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_rtp_jitter_buffer_getcaps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      if (GST_QUERY_IS_SERIALIZED (query)) {
        RTPJitterBufferItem *item;
        gboolean head;

        JBUF_LOCK_CHECK (priv, out_flushing);
        if (rtp_jitter_buffer_get_mode (priv->jbuf) !=
            RTP_JITTER_BUFFER_MODE_BUFFER) {
          GST_DEBUG_OBJECT (jitterbuffer, "adding serialized query");
          item = alloc_item (query, ITEM_TYPE_QUERY, -1, -1, -1, 0, -1);
          rtp_jitter_buffer_insert (priv->jbuf, item, &head, NULL);
          if (head)
            JBUF_SIGNAL_EVENT (priv);
          JBUF_WAIT_QUERY (priv, out_flushing);
          res = priv->last_query;
        } else {
          GST_DEBUG_OBJECT (jitterbuffer, "refusing query, we are buffering");
          res = FALSE;
        }
        JBUF_UNLOCK (priv);
      } else {
        res = gst_pad_query_default (pad, parent, query);
      }
      break;
  }
  return res;
  /* ERRORS */
out_flushing:
  {
    GST_DEBUG_OBJECT (jitterbuffer, "we are flushing");
    JBUF_UNLOCK (priv);
    return FALSE;
  }

}

static gboolean
gst_rtp_jitter_buffer_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;
  gboolean res = FALSE;

  jitterbuffer = GST_RTP_JITTER_BUFFER (parent);
  priv = jitterbuffer->priv;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
    {
      /* We need to send the query upstream and add the returned latency to our
       * own */
      GstClockTime min_latency, max_latency;
      gboolean us_live;
      GstClockTime our_latency;

      if ((res = gst_pad_peer_query (priv->sinkpad, query))) {
        gst_query_parse_latency (query, &us_live, &min_latency, &max_latency);

        GST_DEBUG_OBJECT (jitterbuffer, "Peer latency: min %"
            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

        /* store this so that we can safely sync on the peer buffers. */
        JBUF_LOCK (priv);
        priv->peer_latency = min_latency;
        our_latency = priv->latency_ns;
        JBUF_UNLOCK (priv);

        GST_DEBUG_OBJECT (jitterbuffer, "Our latency: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (our_latency));

        /* we add some latency but can buffer an infinite amount of time */
        min_latency += our_latency;
        max_latency = -1;

        GST_DEBUG_OBJECT (jitterbuffer, "Calculated total latency : min %"
            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

        gst_query_set_latency (query, TRUE, min_latency, max_latency);
      }
      break;
    }
    case GST_QUERY_POSITION:
    {
      GstClockTime start, last_out;
      GstFormat fmt;

      gst_query_parse_position (query, &fmt, NULL);
      if (fmt != GST_FORMAT_TIME) {
        res = gst_pad_query_default (pad, parent, query);
        break;
      }

      JBUF_LOCK (priv);
      start = priv->npt_start;
      last_out = priv->last_out_time;
      JBUF_UNLOCK (priv);

      GST_DEBUG_OBJECT (jitterbuffer, "npt start %" GST_TIME_FORMAT
          ", last out %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
          GST_TIME_ARGS (last_out));

      if (GST_CLOCK_TIME_IS_VALID (start) && GST_CLOCK_TIME_IS_VALID (last_out)) {
        /* bring 0-based outgoing time to stream time */
        gst_query_set_position (query, GST_FORMAT_TIME, start + last_out);
        res = TRUE;
      } else {
        res = gst_pad_query_default (pad, parent, query);
      }
      break;
    }
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_rtp_jitter_buffer_getcaps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

static void
gst_rtp_jitter_buffer_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER (object);
  priv = jitterbuffer->priv;

  switch (prop_id) {
    case PROP_LATENCY:
    {
      guint new_latency, old_latency;

      new_latency = g_value_get_uint (value);

      JBUF_LOCK (priv);
      old_latency = priv->latency_ms;
      priv->latency_ms = new_latency;
      priv->latency_ns = priv->latency_ms * GST_MSECOND;
      rtp_jitter_buffer_set_delay (priv->jbuf, priv->latency_ns);
      JBUF_UNLOCK (priv);

      /* post message if latency changed, this will inform the parent pipeline
       * that a latency reconfiguration is possible/needed. */
      if (new_latency != old_latency) {
        GST_DEBUG_OBJECT (jitterbuffer, "latency changed to: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (new_latency * GST_MSECOND));

        gst_element_post_message (GST_ELEMENT_CAST (jitterbuffer),
            gst_message_new_latency (GST_OBJECT_CAST (jitterbuffer)));
      }
      break;
    }
    case PROP_DROP_ON_LATENCY:
      JBUF_LOCK (priv);
      priv->drop_on_latency = g_value_get_boolean (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_TS_OFFSET:
      JBUF_LOCK (priv);
      priv->ts_offset = g_value_get_int64 (value);
      priv->ts_discont = TRUE;
      JBUF_UNLOCK (priv);
      break;
    case PROP_DO_LOST:
      JBUF_LOCK (priv);
      priv->do_lost = g_value_get_boolean (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_MODE:
      JBUF_LOCK (priv);
      rtp_jitter_buffer_set_mode (priv->jbuf, g_value_get_enum (value));
      JBUF_UNLOCK (priv);
      break;
    case PROP_DO_RETRANSMISSION:
      JBUF_LOCK (priv);
      priv->do_retransmission = g_value_get_boolean (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_NEXT_SEQNUM:
      JBUF_LOCK (priv);
      priv->rtx_next_seqnum = g_value_get_boolean (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_DELAY:
      JBUF_LOCK (priv);
      priv->rtx_delay = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MIN_DELAY:
      JBUF_LOCK (priv);
      priv->rtx_min_delay = g_value_get_uint (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_DELAY_REORDER:
      JBUF_LOCK (priv);
      priv->rtx_delay_reorder = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_RETRY_TIMEOUT:
      JBUF_LOCK (priv);
      priv->rtx_retry_timeout = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MIN_RETRY_TIMEOUT:
      JBUF_LOCK (priv);
      priv->rtx_min_retry_timeout = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_RETRY_PERIOD:
      JBUF_LOCK (priv);
      priv->rtx_retry_period = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MAX_RETRIES:
      JBUF_LOCK (priv);
      priv->rtx_max_retries = g_value_get_int (value);
      JBUF_UNLOCK (priv);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_jitter_buffer_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstRtpJitterBuffer *jitterbuffer;
  GstRtpJitterBufferPrivate *priv;

  jitterbuffer = GST_RTP_JITTER_BUFFER (object);
  priv = jitterbuffer->priv;

  switch (prop_id) {
    case PROP_LATENCY:
      JBUF_LOCK (priv);
      g_value_set_uint (value, priv->latency_ms);
      JBUF_UNLOCK (priv);
      break;
    case PROP_DROP_ON_LATENCY:
      JBUF_LOCK (priv);
      g_value_set_boolean (value, priv->drop_on_latency);
      JBUF_UNLOCK (priv);
      break;
    case PROP_TS_OFFSET:
      JBUF_LOCK (priv);
      g_value_set_int64 (value, priv->ts_offset);
      JBUF_UNLOCK (priv);
      break;
    case PROP_DO_LOST:
      JBUF_LOCK (priv);
      g_value_set_boolean (value, priv->do_lost);
      JBUF_UNLOCK (priv);
      break;
    case PROP_MODE:
      JBUF_LOCK (priv);
      g_value_set_enum (value, rtp_jitter_buffer_get_mode (priv->jbuf));
      JBUF_UNLOCK (priv);
      break;
    case PROP_PERCENT:
    {
      gint percent;

      JBUF_LOCK (priv);
      if (priv->srcresult != GST_FLOW_OK)
        percent = 100;
      else
        percent = rtp_jitter_buffer_get_percent (priv->jbuf);

      g_value_set_int (value, percent);
      JBUF_UNLOCK (priv);
      break;
    }
    case PROP_DO_RETRANSMISSION:
      JBUF_LOCK (priv);
      g_value_set_boolean (value, priv->do_retransmission);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_NEXT_SEQNUM:
      JBUF_LOCK (priv);
      g_value_set_boolean (value, priv->rtx_next_seqnum);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_DELAY:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_delay);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MIN_DELAY:
      JBUF_LOCK (priv);
      g_value_set_uint (value, priv->rtx_min_delay);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_DELAY_REORDER:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_delay_reorder);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_RETRY_TIMEOUT:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_retry_timeout);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MIN_RETRY_TIMEOUT:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_min_retry_timeout);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_RETRY_PERIOD:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_retry_period);
      JBUF_UNLOCK (priv);
      break;
    case PROP_RTX_MAX_RETRIES:
      JBUF_LOCK (priv);
      g_value_set_int (value, priv->rtx_max_retries);
      JBUF_UNLOCK (priv);
      break;
    case PROP_STATS:
      g_value_take_boxed (value,
          gst_rtp_jitter_buffer_create_stats (jitterbuffer));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStructure *
gst_rtp_jitter_buffer_create_stats (GstRtpJitterBuffer * jbuf)
{
  GstStructure *s;

  JBUF_LOCK (jbuf->priv);
  s = gst_structure_new ("application/x-rtp-jitterbuffer-stats",
      "rtx-count", G_TYPE_UINT64, jbuf->priv->num_rtx_requests,
      "rtx-success-count", G_TYPE_UINT64, jbuf->priv->num_rtx_success,
      "rtx-per-packet", G_TYPE_DOUBLE, jbuf->priv->avg_rtx_num,
      "rtx-rtt", G_TYPE_UINT64, jbuf->priv->avg_rtx_rtt, NULL);
  JBUF_UNLOCK (jbuf->priv);

  return s;
}
