mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
rtpjitterbuffer: keep delay as a separate variable in timer
Keep a separate delay in the timer so that we still know the original timestamp of the packet that this timer refers to. We can then place the correct running-time in the Retransmission event.
This commit is contained in:
parent
d34184dd03
commit
fd6c57cf10
1 changed files with 30 additions and 20 deletions
|
@ -244,6 +244,7 @@ typedef struct
|
||||||
GstClockTime timeout;
|
GstClockTime timeout;
|
||||||
GstClockTime duration;
|
GstClockTime duration;
|
||||||
GstClockTime rtx_base;
|
GstClockTime rtx_base;
|
||||||
|
GstClockTime rtx_delay;
|
||||||
GstClockTime rtx_retry;
|
GstClockTime rtx_retry;
|
||||||
} TimerData;
|
} TimerData;
|
||||||
|
|
||||||
|
@ -1487,7 +1488,8 @@ recalculate_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer)
|
||||||
|
|
||||||
static TimerData *
|
static TimerData *
|
||||||
add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
|
add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
|
||||||
guint16 seqnum, guint num, GstClockTime timeout, GstClockTime duration)
|
guint16 seqnum, guint num, GstClockTime timeout, GstClockTime delay,
|
||||||
|
GstClockTime duration)
|
||||||
{
|
{
|
||||||
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
|
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
|
||||||
TimerData *timer;
|
TimerData *timer;
|
||||||
|
@ -1504,10 +1506,11 @@ add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
|
||||||
timer->type = type;
|
timer->type = type;
|
||||||
timer->seqnum = seqnum;
|
timer->seqnum = seqnum;
|
||||||
timer->num = num;
|
timer->num = num;
|
||||||
timer->timeout = timeout;
|
timer->timeout = timeout + delay;
|
||||||
timer->duration = duration;
|
timer->duration = duration;
|
||||||
if (type == TIMER_TYPE_EXPECTED) {
|
if (type == TIMER_TYPE_EXPECTED) {
|
||||||
timer->rtx_base = timeout;
|
timer->rtx_base = timeout;
|
||||||
|
timer->rtx_delay = delay;
|
||||||
timer->rtx_retry = 0;
|
timer->rtx_retry = 0;
|
||||||
}
|
}
|
||||||
recalculate_timer (jitterbuffer, timer);
|
recalculate_timer (jitterbuffer, timer);
|
||||||
|
@ -1518,7 +1521,7 @@ add_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reschedule_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
|
reschedule_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
|
||||||
guint16 seqnum, GstClockTime timeout)
|
guint16 seqnum, GstClockTime timeout, GstClockTime delay)
|
||||||
{
|
{
|
||||||
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
|
GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
|
||||||
gboolean seqchange, timechange;
|
gboolean seqchange, timechange;
|
||||||
|
@ -1536,10 +1539,11 @@ reschedule_timer (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
|
||||||
"replace timer for seqnum %d->%d to %" GST_TIME_FORMAT,
|
"replace timer for seqnum %d->%d to %" GST_TIME_FORMAT,
|
||||||
oldseq, seqnum, GST_TIME_ARGS (timeout));
|
oldseq, seqnum, GST_TIME_ARGS (timeout));
|
||||||
|
|
||||||
timer->timeout = timeout;
|
timer->timeout = timeout + delay;
|
||||||
timer->seqnum = seqnum;
|
timer->seqnum = seqnum;
|
||||||
if (seqchange && timer->type == TIMER_TYPE_EXPECTED) {
|
if (seqchange && timer->type == TIMER_TYPE_EXPECTED) {
|
||||||
timer->rtx_base = timeout;
|
timer->rtx_base = timeout;
|
||||||
|
timer->rtx_delay = delay;
|
||||||
timer->rtx_retry = 0;
|
timer->rtx_retry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,9 +1568,9 @@ set_timer (GstRtpJitterBuffer * jitterbuffer, TimerType type,
|
||||||
/* find the seqnum timer */
|
/* find the seqnum timer */
|
||||||
timer = find_timer (jitterbuffer, type, seqnum);
|
timer = find_timer (jitterbuffer, type, seqnum);
|
||||||
if (timer == NULL) {
|
if (timer == NULL) {
|
||||||
timer = add_timer (jitterbuffer, type, seqnum, 0, timeout, -1);
|
timer = add_timer (jitterbuffer, type, seqnum, 0, timeout, 0, -1);
|
||||||
} else {
|
} else {
|
||||||
reschedule_timer (jitterbuffer, timer, seqnum, timeout);
|
reschedule_timer (jitterbuffer, timer, seqnum, timeout, 0);
|
||||||
}
|
}
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
@ -1633,21 +1637,24 @@ update_timers (GstRtpJitterBuffer * jitterbuffer, guint16 seqnum,
|
||||||
/* max gap, we exceeded the max reorder distance and we don't expect the
|
/* max gap, we exceeded the max reorder distance and we don't expect the
|
||||||
* missing packet to be this reordered */
|
* missing packet to be this reordered */
|
||||||
if (test->rtx_retry == 0 && test->type == TIMER_TYPE_EXPECTED)
|
if (test->rtx_retry == 0 && test->type == TIMER_TYPE_EXPECTED)
|
||||||
reschedule_timer (jitterbuffer, test, test->seqnum, -1);
|
reschedule_timer (jitterbuffer, test, test->seqnum, -1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->packet_spacing > 0 && do_next_seqnum && priv->do_retransmission) {
|
if (priv->packet_spacing > 0 && do_next_seqnum && priv->do_retransmission) {
|
||||||
GstClockTime expected;
|
GstClockTime expected, delay;
|
||||||
|
|
||||||
/* calculate expected arrival time of the next seqnum */
|
/* calculate expected arrival time of the next seqnum */
|
||||||
expected = dts + priv->packet_spacing + (priv->rtx_delay * GST_MSECOND);
|
expected = dts + priv->packet_spacing;
|
||||||
|
delay = priv->rtx_delay * GST_MSECOND;
|
||||||
|
|
||||||
/* and update/install timer for next seqnum */
|
/* and update/install timer for next seqnum */
|
||||||
if (timer)
|
if (timer)
|
||||||
reschedule_timer (jitterbuffer, timer, priv->next_in_seqnum, expected);
|
reschedule_timer (jitterbuffer, timer, priv->next_in_seqnum, expected,
|
||||||
|
delay);
|
||||||
else
|
else
|
||||||
add_timer (jitterbuffer, TIMER_TYPE_EXPECTED, priv->next_in_seqnum, 0,
|
add_timer (jitterbuffer, TIMER_TYPE_EXPECTED, priv->next_in_seqnum, 0,
|
||||||
expected, priv->packet_spacing);
|
expected, delay, priv->packet_spacing);
|
||||||
} else if (timer && timer->type != TIMER_TYPE_DEADLINE) {
|
} else if (timer && timer->type != TIMER_TYPE_DEADLINE) {
|
||||||
/* if we had a timer, remove it, we don't know when to expect the next
|
/* if we had a timer, remove it, we don't know when to expect the next
|
||||||
* packet. */
|
* packet. */
|
||||||
|
@ -1765,7 +1772,7 @@ calculate_expected (GstRtpJitterBuffer * jitterbuffer, guint32 expected,
|
||||||
/* this timer will fire immediately and the lost event will be pushed from
|
/* this timer will fire immediately and the lost event will be pushed from
|
||||||
* the timer thread */
|
* the timer thread */
|
||||||
add_timer (jitterbuffer, TIMER_TYPE_LOST, expected, lost_packets,
|
add_timer (jitterbuffer, TIMER_TYPE_LOST, expected, lost_packets,
|
||||||
priv->last_in_dts + duration, gap_time);
|
priv->last_in_dts + duration, 0, gap_time);
|
||||||
|
|
||||||
expected += lost_packets;
|
expected += lost_packets;
|
||||||
priv->last_in_dts += gap_time;
|
priv->last_in_dts += gap_time;
|
||||||
|
@ -1783,7 +1790,7 @@ calculate_expected (GstRtpJitterBuffer * jitterbuffer, guint32 expected,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (expected < seqnum) {
|
while (expected < seqnum) {
|
||||||
add_timer (jitterbuffer, type, expected, 0, expected_dts, duration);
|
add_timer (jitterbuffer, type, expected, 0, expected_dts, 0, duration);
|
||||||
expected_dts += duration;
|
expected_dts += duration;
|
||||||
expected++;
|
expected++;
|
||||||
}
|
}
|
||||||
|
@ -2311,11 +2318,12 @@ do_expected_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
|
||||||
gst_structure_new ("GstRTPRetransmissionRequest",
|
gst_structure_new ("GstRTPRetransmissionRequest",
|
||||||
"seqnum", G_TYPE_UINT, (guint) timer->seqnum,
|
"seqnum", G_TYPE_UINT, (guint) timer->seqnum,
|
||||||
"running-time", G_TYPE_UINT64, timer->rtx_base,
|
"running-time", G_TYPE_UINT64, timer->rtx_base,
|
||||||
"delay", G_TYPE_UINT, GST_TIME_AS_MSECONDS (timer->rtx_retry),
|
"delay", G_TYPE_UINT,
|
||||||
"frequency", G_TYPE_UINT, priv->rtx_retry_timeout,
|
GST_TIME_AS_MSECONDS (timer->rtx_delay + timer->rtx_retry),
|
||||||
"period", G_TYPE_UINT, priv->rtx_retry_period,
|
"frequency", G_TYPE_UINT, priv->rtx_retry_timeout, "period",
|
||||||
"deadline", G_TYPE_UINT, priv->latency_ms,
|
G_TYPE_UINT, priv->rtx_retry_period, "deadline", G_TYPE_UINT,
|
||||||
"packet-spacing", G_TYPE_UINT64, priv->packet_spacing, NULL));
|
priv->latency_ms, "packet-spacing", G_TYPE_UINT64,
|
||||||
|
priv->packet_spacing, NULL));
|
||||||
|
|
||||||
JBUF_UNLOCK (priv);
|
JBUF_UNLOCK (priv);
|
||||||
gst_pad_push_event (priv->sinkpad, event);
|
gst_pad_push_event (priv->sinkpad, event);
|
||||||
|
@ -2323,15 +2331,17 @@ do_expected_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
|
||||||
|
|
||||||
/* calculate the timeout for the next retransmission attempt */
|
/* calculate the timeout for the next retransmission attempt */
|
||||||
timer->rtx_retry += (priv->rtx_retry_timeout * GST_MSECOND);
|
timer->rtx_retry += (priv->rtx_retry_timeout * GST_MSECOND);
|
||||||
if (timer->rtx_retry > (priv->rtx_retry_period * GST_MSECOND)) {
|
if (timer->rtx_retry + timer->rtx_delay >
|
||||||
|
(priv->rtx_retry_period * GST_MSECOND)) {
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "reschedule as LOST timer");
|
GST_DEBUG_OBJECT (jitterbuffer, "reschedule as LOST timer");
|
||||||
/* too many retransmission request, we now convert the timer
|
/* too many retransmission request, we now convert the timer
|
||||||
* to a lost timer */
|
* to a lost timer */
|
||||||
timer->type = TIMER_TYPE_LOST;
|
timer->type = TIMER_TYPE_LOST;
|
||||||
|
timer->rtx_delay = 0;
|
||||||
timer->rtx_retry = 0;
|
timer->rtx_retry = 0;
|
||||||
}
|
}
|
||||||
reschedule_timer (jitterbuffer, timer, timer->seqnum,
|
reschedule_timer (jitterbuffer, timer, timer->seqnum,
|
||||||
timer->rtx_base + timer->rtx_retry);
|
timer->rtx_base + timer->rtx_retry, timer->rtx_delay);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue