mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
rtpjitterbuffer: stop buffering and emit EOS at the end of a stream
When using RTP_JITTER_BUFFER_MODE_BUFFER, make sure that the ringbuffer doesn't get stuck buffering forever when there isn't enough data left to fill the buffer.
This commit is contained in:
parent
d516fc5fd8
commit
4b6cb93025
2 changed files with 64 additions and 25 deletions
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 47683c1bbe3be3c8b2468039aa4cd860bbe03e6c
|
Subproject commit 4d67bd6f51003ea5c7e7ae75f53ce95acc4c4175
|
|
@ -1090,7 +1090,7 @@ gst_rtp_jitter_buffer_sink_event (GstPad * pad, GstEvent * event)
|
||||||
* we are flushing */
|
* we are flushing */
|
||||||
ret = priv->srcresult == GST_FLOW_OK;
|
ret = priv->srcresult == GST_FLOW_OK;
|
||||||
if (ret && !priv->eos) {
|
if (ret && !priv->eos) {
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "queuing EOS");
|
GST_INFO_OBJECT (jitterbuffer, "queuing EOS");
|
||||||
priv->eos = TRUE;
|
priv->eos = TRUE;
|
||||||
JBUF_SIGNAL (priv);
|
JBUF_SIGNAL (priv);
|
||||||
} else if (priv->eos) {
|
} else if (priv->eos) {
|
||||||
|
@ -1485,7 +1485,7 @@ eos_reached (GstClock * clock, GstClockTime time, GstClockID id,
|
||||||
|
|
||||||
JBUF_LOCK_CHECK (priv, flushing);
|
JBUF_LOCK_CHECK (priv, flushing);
|
||||||
if (priv->waiting) {
|
if (priv->waiting) {
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "got the NPT timeout");
|
GST_INFO_OBJECT (jitterbuffer, "got the NPT timeout");
|
||||||
priv->reached_npt_stop = TRUE;
|
priv->reached_npt_stop = TRUE;
|
||||||
JBUF_SIGNAL (priv);
|
JBUF_SIGNAL (priv);
|
||||||
}
|
}
|
||||||
|
@ -1500,6 +1500,33 @@ flushing:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static GstClockTime
|
||||||
|
compute_elapsed (GstRtpJitterBuffer * jitterbuffer, GstBuffer * outbuf)
|
||||||
|
{
|
||||||
|
guint64 ext_time, elapsed, estimated;
|
||||||
|
guint32 rtp_time;
|
||||||
|
GstRtpJitterBufferPrivate *priv;
|
||||||
|
|
||||||
|
priv = jitterbuffer->priv;
|
||||||
|
rtp_time = gst_rtp_buffer_get_timestamp (outbuf);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (jitterbuffer, "rtp %" G_GUINT32_FORMAT ", ext %"
|
||||||
|
G_GUINT64_FORMAT, rtp_time, priv->ext_timestamp);
|
||||||
|
|
||||||
|
if (rtp_time < priv->ext_timestamp) {
|
||||||
|
ext_time = priv->ext_timestamp;
|
||||||
|
} else {
|
||||||
|
ext_time = gst_rtp_buffer_ext_timestamp (&priv->ext_timestamp, rtp_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext_time > priv->clock_base)
|
||||||
|
elapsed = ext_time - priv->clock_base;
|
||||||
|
else
|
||||||
|
elapsed = 0;
|
||||||
|
|
||||||
|
elapsed = gst_util_uint64_scale_int (elapsed, GST_SECOND, priv->clock_rate);
|
||||||
|
return elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This funcion will push out buffers on the source pad.
|
* This funcion will push out buffers on the source pad.
|
||||||
|
@ -1535,8 +1562,37 @@ again:
|
||||||
if (G_LIKELY (!priv->blocked)) {
|
if (G_LIKELY (!priv->blocked)) {
|
||||||
/* we're buffering but not EOS, wait. */
|
/* we're buffering but not EOS, wait. */
|
||||||
if (!priv->eos && (!priv->active
|
if (!priv->eos && (!priv->active
|
||||||
|| rtp_jitter_buffer_is_buffering (priv->jbuf)))
|
|| rtp_jitter_buffer_is_buffering (priv->jbuf))) {
|
||||||
goto do_wait;
|
GstClockTime elapsed, delay, left;
|
||||||
|
|
||||||
|
if (priv->estimated_eos == -1)
|
||||||
|
goto do_wait;
|
||||||
|
|
||||||
|
outbuf = rtp_jitter_buffer_peek (priv->jbuf);
|
||||||
|
if (outbuf != NULL) {
|
||||||
|
elapsed = compute_elapsed (jitterbuffer, outbuf);
|
||||||
|
if (GST_BUFFER_DURATION_IS_VALID (outbuf))
|
||||||
|
elapsed += GST_BUFFER_DURATION (outbuf);
|
||||||
|
} else {
|
||||||
|
GST_INFO_OBJECT (jitterbuffer, "no buffer, using last_elapsed");
|
||||||
|
elapsed = priv->last_elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay = rtp_jitter_buffer_get_delay (priv->jbuf);
|
||||||
|
|
||||||
|
if (priv->estimated_eos > elapsed)
|
||||||
|
left = priv->estimated_eos - elapsed;
|
||||||
|
else
|
||||||
|
left = 0;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (jitterbuffer, "buffering, elapsed %" GST_TIME_FORMAT
|
||||||
|
" estimated_eos %" GST_TIME_FORMAT " left %" GST_TIME_FORMAT
|
||||||
|
" delay %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (elapsed), GST_TIME_ARGS (priv->estimated_eos),
|
||||||
|
GST_TIME_ARGS (left), GST_TIME_ARGS (delay));
|
||||||
|
if (left > delay)
|
||||||
|
goto do_wait;
|
||||||
|
}
|
||||||
/* if we have a packet, we can exit the loop and grab it */
|
/* if we have a packet, we can exit the loop and grab it */
|
||||||
if (rtp_jitter_buffer_num_packets (priv->jbuf) > 0)
|
if (rtp_jitter_buffer_num_packets (priv->jbuf) > 0)
|
||||||
break;
|
break;
|
||||||
|
@ -1551,7 +1607,7 @@ again:
|
||||||
GST_OBJECT_LOCK (jitterbuffer);
|
GST_OBJECT_LOCK (jitterbuffer);
|
||||||
clock = GST_ELEMENT_CLOCK (jitterbuffer);
|
clock = GST_ELEMENT_CLOCK (jitterbuffer);
|
||||||
if (clock) {
|
if (clock) {
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "scheduling timeout");
|
GST_INFO_OBJECT (jitterbuffer, "scheduling timeout");
|
||||||
id = gst_clock_new_single_shot_id (clock, sync_time);
|
id = gst_clock_new_single_shot_id (clock, sync_time);
|
||||||
gst_clock_id_wait_async (id, (GstClockCallback) eos_reached,
|
gst_clock_id_wait_async (id, (GstClockCallback) eos_reached,
|
||||||
jitterbuffer);
|
jitterbuffer);
|
||||||
|
@ -1768,26 +1824,9 @@ push_buffer:
|
||||||
/* update the elapsed time when we need to check against the npt stop time. */
|
/* update the elapsed time when we need to check against the npt stop time. */
|
||||||
if (priv->npt_stop != -1 && priv->ext_timestamp != -1
|
if (priv->npt_stop != -1 && priv->ext_timestamp != -1
|
||||||
&& priv->clock_base != -1 && priv->clock_rate > 0) {
|
&& priv->clock_base != -1 && priv->clock_rate > 0) {
|
||||||
guint64 ext_time, elapsed, estimated;
|
guint64 elapsed, estimated;
|
||||||
guint32 rtp_time;
|
|
||||||
|
|
||||||
rtp_time = gst_rtp_buffer_get_timestamp (outbuf);
|
elapsed = compute_elapsed (jitterbuffer, outbuf);
|
||||||
|
|
||||||
GST_LOG_OBJECT (jitterbuffer, "rtp %" G_GUINT32_FORMAT ", ext %"
|
|
||||||
G_GUINT64_FORMAT, rtp_time, priv->ext_timestamp);
|
|
||||||
|
|
||||||
if (rtp_time < priv->ext_timestamp) {
|
|
||||||
ext_time = priv->ext_timestamp;
|
|
||||||
} else {
|
|
||||||
ext_time = gst_rtp_buffer_ext_timestamp (&priv->ext_timestamp, rtp_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ext_time > priv->clock_base)
|
|
||||||
elapsed = ext_time - priv->clock_base;
|
|
||||||
else
|
|
||||||
elapsed = 0;
|
|
||||||
|
|
||||||
elapsed = gst_util_uint64_scale_int (elapsed, GST_SECOND, priv->clock_rate);
|
|
||||||
|
|
||||||
if (elapsed > priv->last_elapsed) {
|
if (elapsed > priv->last_elapsed) {
|
||||||
guint64 left;
|
guint64 left;
|
||||||
|
|
Loading…
Reference in a new issue