{
guint idx;
guint16 seqnum;
+ guint num;
TimerType type;
GstClockTime timeout;
GstClockTime duration;
static TimerData *
add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
- guint16 seqnum, GstClockTime timeout, GstClockTime duration)
+ guint16 seqnum, guint num, GstClockTime timeout, GstClockTime duration)
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
TimerData *timer;
timer->idx = len;
timer->type = type;
timer->seqnum = seqnum;
+ timer->num = num;
timer->timeout = timeout;
timer->duration = duration;
if (type == TIMER_TYPE_EXPECTED) {
/* find the seqnum timer */
timer = find_timer (jitterbuffer, type, seqnum);
if (timer == NULL) {
- timer = add_timer (jitterbuffer, type, seqnum, timeout, -1);
+ timer = add_timer (jitterbuffer, type, seqnum, 0, timeout, -1);
} else {
reschedule_timer (jitterbuffer, timer, seqnum, timeout);
}
if (timer)
reschedule_timer (jitterbuffer, timer, priv->next_in_seqnum, expected);
else
- add_timer (jitterbuffer, TIMER_TYPE_EXPECTED, priv->next_in_seqnum,
+ add_timer (jitterbuffer, TIMER_TYPE_EXPECTED, priv->next_in_seqnum, 0,
expected, 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
}
}
-static GstFlowReturn
+static void
send_lost_event (GstRtpJitterBuffer * jitterbuffer, guint seqnum,
guint lost_packets, GstClockTime timestamp, GstClockTime duration,
gboolean late)
"late", G_TYPE_BOOLEAN, late, NULL));
JBUF_UNLOCK (priv);
gst_pad_push_event (priv->srcpad, event);
- JBUF_LOCK_CHECK (priv, flushing);
- }
- return GST_FLOW_OK;
-
- /* ERRORS */
-flushing:
- {
- GST_DEBUG_OBJECT (jitterbuffer, "we are flushing");
- return GST_FLOW_FLUSHING;
+ JBUF_LOCK (priv);
}
}
-
-static GstFlowReturn
+static void
calculate_expected (GstRtpJitterBuffer * jitterbuffer, guint32 expected,
guint16 seqnum, GstClockTime dts, gint gap)
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
- GstFlowReturn ret = GST_FLOW_OK;
GstClockTime total_duration, duration, expected_dts;
TimerType type;
GST_TIME_ARGS (total_duration), GST_TIME_ARGS (priv->latency_ns),
lost_packets);
- ret =
- send_lost_event (jitterbuffer, expected, lost_packets,
- priv->last_in_dts + duration, gap_time, TRUE);
+ /* this timer will fire immediately and the lost event will be pushed from
+ * the timer thread */
+ add_timer (jitterbuffer, TIMER_TYPE_LOST, expected, lost_packets,
+ priv->last_in_dts + duration, gap_time);
expected += lost_packets;
priv->last_in_dts += gap_time;
}
while (expected < seqnum) {
- add_timer (jitterbuffer, type, expected, expected_dts, duration);
+ add_timer (jitterbuffer, type, expected, 0, expected_dts, duration);
expected_dts += duration;
expected++;
}
- return ret;
}
static GstFlowReturn
} else {
GST_DEBUG_OBJECT (jitterbuffer, "%d missing packets", gap);
/* fill in the gap with EXPECTED timers */
- ret = calculate_expected (jitterbuffer, expected, seqnum, dts, gap);
- if (ret != GST_FLOW_OK)
- goto out_flushing;
+ calculate_expected (jitterbuffer, expected, seqnum, dts, gap);
do_next_seqnum = TRUE;
}
{
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
GstClockTime duration, timestamp;
- guint seqnum;
+ guint seqnum, num;
+ gboolean late;
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;
+ num = MAX (timer->num, 1);
+ late = timer->num > 0;
/* remove timer now */
remove_timer (jitterbuffer, timer);
JBUF_SIGNAL_EVENT (priv);
- send_lost_event (jitterbuffer, seqnum, 1, timestamp, duration, FALSE);
+ send_lost_event (jitterbuffer, seqnum, num, timestamp, duration, late);
return TRUE;
}