+ * rtp_jitter_buffer_alloc_item:
+ * @data: The data stored in this item
+ * @type: User specific item type
+ * @dts: Decoding Timestamp
+ * @pts: Presentation Timestamp
+ * @seqnum: Sequence number
+ * @count: Number of packet this item represent
+ * @rtptime: The RTP specific timestamp
+ * @free_data: A function to free @data (optional)
+ *
+ * Create an item that can then be stored in the jitter buffer.
+ *
+ * Returns: a newly allocated RTPJitterbufferItem
+ */
+static RTPJitterBufferItem *
+rtp_jitter_buffer_alloc_item (gpointer data, guint type, GstClockTime dts,
+ GstClockTime pts, guint seqnum, guint count, guint rtptime,
+ GDestroyNotify free_data)
+{
+ 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;
+ item->free_data = free_data;
+
+ return item;
+}
+
+static inline RTPJitterBufferItem *
+alloc_event_item (GstEvent * event)
+{
+ return rtp_jitter_buffer_alloc_item (event, ITEM_TYPE_EVENT, -1, -1, -1, 0,
+ -1, (GDestroyNotify) gst_mini_object_unref);
+}
+
+/**
+ * rtp_jitter_buffer_append_event:
+ * @jbuf: an #RTPJitterBuffer
+ * @event: an #GstEvent to insert
+
+ * Inserts @event into the packet queue of @jbuf.
+ *
+ * Returns: %TRUE if the event is at the head of the queue
+ */
+gboolean
+rtp_jitter_buffer_append_event (RTPJitterBuffer * jbuf, GstEvent * event)
+{
+ RTPJitterBufferItem *item = alloc_event_item (event);
+ gboolean head;
+ rtp_jitter_buffer_insert (jbuf, item, &head, NULL);
+ return head;
+}
+
+/**
+ * rtp_jitter_buffer_append_query:
+ * @jbuf: an #RTPJitterBuffer
+ * @query: an #GstQuery to insert
+
+ * Inserts @query into the packet queue of @jbuf.
+ *
+ * Returns: %TRUE if the query is at the head of the queue
+ */
+gboolean
+rtp_jitter_buffer_append_query (RTPJitterBuffer * jbuf, GstQuery * query)
+{
+ RTPJitterBufferItem *item =
+ rtp_jitter_buffer_alloc_item (query, ITEM_TYPE_QUERY, -1, -1, -1, 0, -1,
+ NULL);
+ gboolean head;
+ rtp_jitter_buffer_insert (jbuf, item, &head, NULL);
+ return head;
+}
+
+/**
+ * rtp_jitter_buffer_append_lost_event:
+ * @jbuf: an #RTPJitterBuffer
+ * @event: an #GstEvent to insert
+ * @seqnum: Sequence number
+ * @lost_packets: Number of lost packet this item represent
+
+ * Inserts @event into the packet queue of @jbuf.
+ *
+ * Returns: %TRUE if the event is at the head of the queue
+ */
+gboolean
+rtp_jitter_buffer_append_lost_event (RTPJitterBuffer * jbuf, GstEvent * event,
+ guint16 seqnum, guint lost_packets)
+{
+ RTPJitterBufferItem *item = rtp_jitter_buffer_alloc_item (event,
+ ITEM_TYPE_LOST, -1, -1, seqnum, lost_packets, -1,
+ (GDestroyNotify) gst_mini_object_unref);
+ gboolean head;
+
+ if (!rtp_jitter_buffer_insert (jbuf, item, &head, NULL)) {
+ /* Duplicate */
+ rtp_jitter_buffer_free_item (item);
+ head = FALSE;
+ }
+
+ return head;
+}
+
+/**
+ * rtp_jitter_buffer_append_buffer:
+ * @jbuf: an #RTPJitterBuffer
+ * @buf: an #GstBuffer to insert
+ * @seqnum: Sequence number
+ * @duplicate: TRUE when the packet inserted is a duplicate
+ * @percent: the buffering percent after insertion
+ *
+ * Inserts @buf into the packet queue of @jbuf.
+ *
+ * Returns: %TRUE if the buffer is at the head of the queue
+ */
+gboolean
+rtp_jitter_buffer_append_buffer (RTPJitterBuffer * jbuf, GstBuffer * buf,
+ GstClockTime dts, GstClockTime pts, guint16 seqnum, guint rtptime,
+ gboolean * duplicate, gint * percent)
+{
+ RTPJitterBufferItem *item = rtp_jitter_buffer_alloc_item (buf,
+ ITEM_TYPE_BUFFER, dts, pts, seqnum, 1, rtptime,
+ (GDestroyNotify) gst_mini_object_unref);
+ gboolean head;
+ gboolean inserted;
+
+ inserted = rtp_jitter_buffer_insert (jbuf, item, &head, percent);
+ if (!inserted)
+ rtp_jitter_buffer_free_item (item);
+
+ if (duplicate)
+ *duplicate = !inserted;
+
+ return head;
+}
+
+/**