Commit 9f3345fc authored by Wim Taymans's avatar Wim Taymans

rtpjitterbuffer: schedule lost event differently

Schedule the lost event by placing it inside the jitterbuffer with the seqnum
that was lost so that the pushing thread can interleave and push it properly.
parent f40d6689
......@@ -1724,6 +1724,7 @@ send_lost_event (GstRtpJitterBuffer * jitterbuffer, guint seqnum,
gboolean late)
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
guint next_seqnum;
/* we had a gap and thus we lost some packets. Create an event for this. */
if (lost_packets > 1)
......@@ -1733,10 +1734,12 @@ send_lost_event (GstRtpJitterBuffer * jitterbuffer, guint seqnum,
GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", seqnum);
priv->num_late += lost_packets;
priv->discont = TRUE;
next_seqnum = seqnum + lost_packets - 1;
if (priv->do_lost) {
GstEvent *event;
RTPJitterBufferItem *item;
/* create paket lost event */
event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
......@@ -1745,14 +1748,15 @@ send_lost_event (GstRtpJitterBuffer * jitterbuffer, guint seqnum,
"timestamp", G_TYPE_UINT64, timestamp,
"duration", G_TYPE_UINT64, duration,
"late", G_TYPE_BOOLEAN, late, NULL));
JBUF_UNLOCK (priv);
gst_pad_push_event (priv->srcpad, event);
JBUF_LOCK (priv);
item = alloc_item (event, ITEM_TYPE_LOST, -1, -1, next_seqnum, -1);
rtp_jitter_buffer_insert (priv->jbuf, item, NULL, NULL);
}
/* update our expected next packet but make sure the seqnum increases */
if (seqnum + lost_packets > priv->next_seqnum) {
priv->next_seqnum = (seqnum + lost_packets) & 0xffff;
priv->last_popped_seqnum = seqnum;
if (seqnum == priv->next_seqnum) {
GST_DEBUG_OBJECT (jitterbuffer, "lost seqnum %d == %d next_seqnum -> %d",
seqnum, priv->next_seqnum, next_seqnum);
priv->next_seqnum = next_seqnum & 0xffff;
priv->last_popped_seqnum = next_seqnum;
priv->last_out_time = timestamp;
}
}
......@@ -2199,17 +2203,21 @@ pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint16 seqnum)
GstFlowReturn result;
RTPJitterBufferItem *item;
GstBuffer *outbuf;
GstEvent *outevent;
GstClockTime dts, pts;
gint percent = -1;
gboolean is_buffer;
/* when we get here we are ready to pop and push the buffer */
item = rtp_jitter_buffer_pop (priv->jbuf, &percent);
is_buffer = GST_IS_BUFFER (item->data);
if (is_buffer) {
check_buffering_percent (jitterbuffer, &percent);
/* we need to make writable to change the flags and timestamps */
outbuf = gst_buffer_make_writable (item->data);
item->data = NULL;
if (G_UNLIKELY (priv->discont)) {
/* set DISCONT flag when we missed a packet. We pushed the buffer writable
......@@ -2233,26 +2241,38 @@ pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint16 seqnum)
/* 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);
} else {
outevent = item->data;
if (item->type == ITEM_TYPE_LOST)
priv->discont = TRUE;
}
/* 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. */
priv->last_popped_seqnum = seqnum;
priv->last_out_time = GST_BUFFER_PTS (outbuf);
priv->next_seqnum = (seqnum + 1) & 0xffff;
JBUF_UNLOCK (priv);
item->data = NULL;
free_item (item);
if (is_buffer) {
/* push buffer */
if (percent != -1)
post_buffering_percent (jitterbuffer, percent);
/* 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);
} else {
GST_DEBUG_OBJECT (jitterbuffer, "Pushing event %d", seqnum);
gst_pad_push_event (priv->srcpad, outevent);
result = GST_FLOW_OK;
}
JBUF_LOCK_CHECK (priv, out_flushing);
return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment