mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-30 07:42:32 +00:00
jitterbuffer: refactor handle sync code
Move the code that combines the last SR packet and the current jitterbuffer sync values into a sync structure, into its own function. We want to reuse this bit later.
This commit is contained in:
parent
87f7d6b9bf
commit
af055d9574
1 changed files with 91 additions and 64 deletions
|
@ -179,6 +179,8 @@ struct _GstRtpJitterBufferPrivate
|
||||||
/* 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. */
|
||||||
GstClockTime peer_latency;
|
GstClockTime peer_latency;
|
||||||
|
guint64 ext_rtptime;
|
||||||
|
GstBuffer *last_sr;
|
||||||
|
|
||||||
/* some accounting */
|
/* some accounting */
|
||||||
guint64 num_late;
|
guint64 num_late;
|
||||||
|
@ -976,6 +978,7 @@ gst_rtp_jitter_buffer_change_state (GstElement * element,
|
||||||
ret = GST_STATE_CHANGE_NO_PREROLL;
|
ret = GST_STATE_CHANGE_NO_PREROLL;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
gst_buffer_replace (&priv->last_sr, NULL);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
break;
|
break;
|
||||||
|
@ -1983,6 +1986,90 @@ pause:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* collect the info form the lastest RTCP packet and the jittebuffer sync, do
|
||||||
|
* some sanity checks and then emit the handle-sync signal with the parameters.
|
||||||
|
* This function must be called with the LOCK */
|
||||||
|
static void
|
||||||
|
do_handle_sync (GstRtpJitterBuffer * jitterbuffer)
|
||||||
|
{
|
||||||
|
GstRtpJitterBufferPrivate *priv;
|
||||||
|
guint64 base_rtptime, base_time;
|
||||||
|
guint32 clock_rate;
|
||||||
|
guint64 last_rtptime;
|
||||||
|
guint64 clock_base;
|
||||||
|
guint64 ext_rtptime, diff;
|
||||||
|
gboolean drop = FALSE;
|
||||||
|
|
||||||
|
priv = jitterbuffer->priv;
|
||||||
|
|
||||||
|
if (priv->last_sr == NULL) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "dropping, no SR RTCP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the last values from the jitterbuffer */
|
||||||
|
rtp_jitter_buffer_get_sync (priv->jbuf, &base_rtptime, &base_time,
|
||||||
|
&clock_rate, &last_rtptime);
|
||||||
|
|
||||||
|
clock_base = priv->clock_base;
|
||||||
|
ext_rtptime = priv->ext_rtptime;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "ext SR %" G_GUINT64_FORMAT ", base %"
|
||||||
|
G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT
|
||||||
|
", clock-base %" G_GUINT64_FORMAT ", last-rtptime %" G_GUINT64_FORMAT,
|
||||||
|
ext_rtptime, base_rtptime, clock_rate, clock_base, last_rtptime);
|
||||||
|
|
||||||
|
if (base_rtptime == -1 || clock_rate == -1 || base_time == -1) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "dropping, no RTP values");
|
||||||
|
drop = TRUE;
|
||||||
|
} else {
|
||||||
|
/* we can't accept anything that happened before we did the last resync */
|
||||||
|
if (base_rtptime > ext_rtptime) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "dropping, older than base time");
|
||||||
|
drop = TRUE;
|
||||||
|
} else {
|
||||||
|
/* the SR RTP timestamp must be something close to what we last observed
|
||||||
|
* in the jitterbuffer */
|
||||||
|
if (ext_rtptime > last_rtptime) {
|
||||||
|
/* check how far ahead it is to our RTP timestamps */
|
||||||
|
diff = ext_rtptime - last_rtptime;
|
||||||
|
/* if bigger than 1 second, we drop it */
|
||||||
|
if (diff > clock_rate) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "too far ahead");
|
||||||
|
/* should drop this, but some RTSP servers end up with bogus
|
||||||
|
* way too ahead RTCP packet when repeated PAUSE/PLAY,
|
||||||
|
* so still trigger rptbin sync but invalidate RTCP data
|
||||||
|
* (sync might use other methods) */
|
||||||
|
ext_rtptime = -1;
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "ext last %" G_GUINT64_FORMAT ", diff %"
|
||||||
|
G_GUINT64_FORMAT, last_rtptime, diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drop) {
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
|
s = gst_structure_new ("application/x-rtp-sync",
|
||||||
|
"base-rtptime", G_TYPE_UINT64, base_rtptime,
|
||||||
|
"base-time", G_TYPE_UINT64, base_time,
|
||||||
|
"clock-rate", G_TYPE_UINT, clock_rate,
|
||||||
|
"clock-base", G_TYPE_UINT64, clock_base,
|
||||||
|
"sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime,
|
||||||
|
"sr-buffer", GST_TYPE_BUFFER, priv->last_sr, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "signaling sync");
|
||||||
|
JBUF_UNLOCK (priv);
|
||||||
|
g_signal_emit (jitterbuffer,
|
||||||
|
gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC], 0, s);
|
||||||
|
JBUF_LOCK (priv);
|
||||||
|
gst_structure_free (s);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "dropping RTCP packet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent,
|
gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
|
@ -1990,16 +2077,11 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent,
|
||||||
GstRtpJitterBuffer *jitterbuffer;
|
GstRtpJitterBuffer *jitterbuffer;
|
||||||
GstRtpJitterBufferPrivate *priv;
|
GstRtpJitterBufferPrivate *priv;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
guint64 base_rtptime, base_time;
|
|
||||||
guint32 clock_rate;
|
|
||||||
guint64 last_rtptime;
|
|
||||||
guint32 ssrc;
|
guint32 ssrc;
|
||||||
GstRTCPPacket packet;
|
GstRTCPPacket packet;
|
||||||
guint64 ext_rtptime, diff;
|
guint64 ext_rtptime;
|
||||||
guint32 rtptime;
|
guint32 rtptime;
|
||||||
gboolean drop = FALSE;
|
|
||||||
GstRTCPBuffer rtcp = { NULL, };
|
GstRTCPBuffer rtcp = { NULL, };
|
||||||
guint64 clock_base;
|
|
||||||
|
|
||||||
jitterbuffer = GST_RTP_JITTER_BUFFER (parent);
|
jitterbuffer = GST_RTP_JITTER_BUFFER (parent);
|
||||||
|
|
||||||
|
@ -2032,67 +2114,12 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstObject * parent,
|
||||||
ext_rtptime = priv->jbuf->ext_rtptime;
|
ext_rtptime = priv->jbuf->ext_rtptime;
|
||||||
ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
|
ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
|
||||||
|
|
||||||
/* get the last values from the jitterbuffer */
|
priv->ext_rtptime = ext_rtptime;
|
||||||
rtp_jitter_buffer_get_sync (priv->jbuf, &base_rtptime, &base_time,
|
gst_buffer_replace (&priv->last_sr, buffer);
|
||||||
&clock_rate, &last_rtptime);
|
|
||||||
|
|
||||||
clock_base = priv->clock_base;
|
do_handle_sync (jitterbuffer);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "ext SR %" G_GUINT64_FORMAT ", base %"
|
|
||||||
G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT
|
|
||||||
", clock-base %" G_GUINT64_FORMAT,
|
|
||||||
ext_rtptime, base_rtptime, clock_rate, clock_base);
|
|
||||||
|
|
||||||
if (base_rtptime == -1 || clock_rate == -1 || base_time == -1) {
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "dropping, no RTP values");
|
|
||||||
drop = TRUE;
|
|
||||||
} else {
|
|
||||||
/* we can't accept anything that happened before we did the last resync */
|
|
||||||
if (base_rtptime > ext_rtptime) {
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "dropping, older than base time");
|
|
||||||
drop = TRUE;
|
|
||||||
} else {
|
|
||||||
/* the SR RTP timestamp must be something close to what we last observed
|
|
||||||
* in the jitterbuffer */
|
|
||||||
if (ext_rtptime > last_rtptime) {
|
|
||||||
/* check how far ahead it is to our RTP timestamps */
|
|
||||||
diff = ext_rtptime - last_rtptime;
|
|
||||||
/* if bigger than 1 second, we drop it */
|
|
||||||
if (diff > clock_rate) {
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "too far ahead");
|
|
||||||
/* should drop this, but some RTSP servers end up with bogus
|
|
||||||
* way too ahead RTCP packet when repeated PAUSE/PLAY,
|
|
||||||
* so still trigger rptbin sync but invalidate RTCP data
|
|
||||||
* (sync might use other methods) */
|
|
||||||
ext_rtptime = -1;
|
|
||||||
}
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "ext last %" G_GUINT64_FORMAT ", diff %"
|
|
||||||
G_GUINT64_FORMAT, last_rtptime, diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JBUF_UNLOCK (priv);
|
JBUF_UNLOCK (priv);
|
||||||
|
|
||||||
if (!drop) {
|
|
||||||
GstStructure *s;
|
|
||||||
|
|
||||||
s = gst_structure_new ("application/x-rtp-sync",
|
|
||||||
"base-rtptime", G_TYPE_UINT64, base_rtptime,
|
|
||||||
"base-time", G_TYPE_UINT64, base_time,
|
|
||||||
"clock-rate", G_TYPE_UINT, clock_rate,
|
|
||||||
"clock-base", G_TYPE_UINT64, clock_base,
|
|
||||||
"sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime,
|
|
||||||
"sr-buffer", GST_TYPE_BUFFER, buffer, NULL);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "signaling sync");
|
|
||||||
g_signal_emit (jitterbuffer,
|
|
||||||
gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC], 0, s);
|
|
||||||
gst_structure_free (s);
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (jitterbuffer, "dropping RTCP packet");
|
|
||||||
ret = GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue