jitterbuffer: keep track of current timeout

This commit is contained in:
Wim Taymans 2013-08-01 12:01:15 +02:00
parent 7e43dba19b
commit 255b7106f5

View file

@ -179,6 +179,7 @@ struct _GstRtpJitterBufferPrivate
/* for sync */ /* for sync */
GstSegment segment; GstSegment segment;
GstClockID clock_id; GstClockID clock_id;
GstClockTime timer_timeout;
gboolean unscheduled; gboolean unscheduled;
/* the latency of the upstream peer, we have to take this into account when /* the latency of the upstream peer, we have to take this into account when
* synchronizing the buffers. */ * synchronizing the buffers. */
@ -1987,14 +1988,26 @@ wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
GstFlowReturn result = GST_FLOW_OK; GstFlowReturn result = GST_FLOW_OK;
gint i, len; gint i, len;
TimerData *timer = NULL; TimerData *timer = NULL;
GstClockTime timer_timeout = -1;
gint timer_idx;
len = priv->timers->len; len = priv->timers->len;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
TimerData *test = &g_array_index (priv->timers, TimerData, i); TimerData *test = &g_array_index (priv->timers, TimerData, i);
GstClockTime test_timeout;
GST_DEBUG_OBJECT (jitterbuffer, "%d, %d, %" GST_TIME_FORMAT,
i, test->seqnum, GST_TIME_ARGS (test->timeout));
test_timeout = test->timeout;
/* find the smallest timeout */ /* find the smallest timeout */
if (timer == NULL || test->timeout == -1 || test->timeout < timer->timeout) if (timer == NULL || test_timeout == -1 || test_timeout < timer->timeout) {
timer = test; timer = test;
timer_timeout = test_timeout;
/* no timeout set, we can stop searching */
if (test_timeout == -1)
break;
}
} }
if (timer) { if (timer) {
GstClock *clock; GstClock *clock;
@ -2004,7 +2017,7 @@ wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
GstClockTimeDiff clock_jitter; GstClockTimeDiff clock_jitter;
/* no timestamp, timeout immeditately */ /* no timestamp, timeout immeditately */
if (timer->timeout == -1) if (timer_timeout == -1)
goto do_timeout; goto do_timeout;
GST_OBJECT_LOCK (jitterbuffer); GST_OBJECT_LOCK (jitterbuffer);
@ -2017,7 +2030,7 @@ wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
} }
/* prepare for sync against clock */ /* prepare for sync against clock */
sync_time = timer->timeout + GST_ELEMENT_CAST (jitterbuffer)->base_time; sync_time = timer_timeout + GST_ELEMENT_CAST (jitterbuffer)->base_time;
/* add latency of peer to get input time */ /* add latency of peer to get input time */
sync_time += priv->peer_latency; sync_time += priv->peer_latency;
@ -2027,11 +2040,13 @@ wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
GST_DEBUG_OBJECT (jitterbuffer, "sync to timestamp %" GST_TIME_FORMAT GST_DEBUG_OBJECT (jitterbuffer, "sync to timestamp %" GST_TIME_FORMAT
" with sync time %" GST_TIME_FORMAT, " with sync time %" GST_TIME_FORMAT,
GST_TIME_ARGS (timer->timeout), GST_TIME_ARGS (sync_time)); GST_TIME_ARGS (timer_timeout), GST_TIME_ARGS (sync_time));
/* create an entry for the clock */ /* create an entry for the clock */
id = priv->clock_id = gst_clock_new_single_shot_id (clock, sync_time); id = priv->clock_id = gst_clock_new_single_shot_id (clock, sync_time);
priv->unscheduled = FALSE; priv->unscheduled = FALSE;
priv->timer_timeout = timer_timeout;
timer_idx = timer->idx;
GST_OBJECT_UNLOCK (jitterbuffer); GST_OBJECT_UNLOCK (jitterbuffer);
/* release the lock so that the other end can push stuff or unlock */ /* release the lock so that the other end can push stuff or unlock */
@ -2060,6 +2075,9 @@ wait_next_timeout (GstRtpJitterBuffer * jitterbuffer)
GST_DEBUG_OBJECT (jitterbuffer, "Wait got unscheduled"); GST_DEBUG_OBJECT (jitterbuffer, "Wait got unscheduled");
goto done; goto done;
} }
/* we released the lock, the array might have changed */
timer = &g_array_index (priv->timers, TimerData, timer_idx);
do_timeout: do_timeout:
switch (timer->type) { switch (timer->type) {
case TIMER_TYPE_EXPECTED: case TIMER_TYPE_EXPECTED: