From b6d0b1334923ec5d3419e3b3488868c7879b701b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Nov 2008 15:17:52 +0000 Subject: gst/rtpmanager/gstrtpbin.c: Do not try to keep track of the clock-rate ourselves but simply get the value from the ji... Original commit message from CVS: * gst/rtpmanager/gstrtpbin.c: (gst_rtp_bin_associate), (gst_rtp_bin_sync_chain), (create_stream), (new_ssrc_pad_found): Do not try to keep track of the clock-rate ourselves but simply get the value from the jitterbuffer. * gst/rtpmanager/gstrtpjitterbuffer.c: (gst_jitter_buffer_sink_parse_caps), (gst_rtp_jitter_buffer_chain), (gst_rtp_jitter_buffer_get_sync): * gst/rtpmanager/gstrtpjitterbuffer.h: Add some debug info. Pass the clock-rate to the jitterbuffer. Also pass the clock-rate along with the rtp timestamp when getting the sync parameters. * gst/rtpmanager/gstrtpptdemux.c: (gst_rtp_pt_demux_chain): Fix some debug. * gst/rtpmanager/rtpjitterbuffer.c: (rtp_jitter_buffer_reset_skew), (calculate_skew), (rtp_jitter_buffer_get_sync): * gst/rtpmanager/rtpjitterbuffer.h: Keep track of clock-rate changes and return the clock-rate together with the rtp timestamps used for sync. Don't try to construct timestamps when we have no base_time. * gst/rtpmanager/rtpsource.c: (get_clock_rate): Request a new clock-rate when the payload type changes. Reset the jitter calculation when the clock-rate changes. --- gst/rtpmanager/gstrtpbin.c | 54 +++++-------------------------------- gst/rtpmanager/gstrtpjitterbuffer.c | 14 ++++++---- gst/rtpmanager/gstrtpjitterbuffer.h | 3 ++- gst/rtpmanager/gstrtpptdemux.c | 2 +- gst/rtpmanager/rtpjitterbuffer.c | 23 +++++++++++++--- gst/rtpmanager/rtpjitterbuffer.h | 3 ++- gst/rtpmanager/rtpsource.c | 11 +++++--- 7 files changed, 48 insertions(+), 62 deletions(-) (limited to 'gst/rtpmanager') diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 605a73dd..197be528 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -327,7 +327,6 @@ struct _GstRtpBinStream guint64 clock_base_time; gint clock_rate; gint64 ts_offset; - gint last_pt; }; #define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock) @@ -856,29 +855,8 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, if (stream->clock_base == -1) goto no_clock_base; - if (stream->clock_rate <= 0) { - gint pt = -1; - GstCaps *caps = NULL; - GstStructure *s = NULL; - - GST_RTP_SESSION_LOCK (stream->session); - pt = stream->last_pt; - GST_RTP_SESSION_UNLOCK (stream->session); - - if (pt < 0) - goto no_clock_rate; - - caps = get_pt_map (stream->session, pt); - if (!caps) - goto no_clock_rate; - - s = gst_caps_get_structure (caps, 0); - gst_structure_get_int (s, "clock-rate", &stream->clock_rate); - gst_caps_unref (caps); - - if (stream->clock_rate <= 0) - goto no_clock_rate; - } + if (stream->clock_rate <= 0) + goto no_clock_rate; /* take the extended rtptime we found in the SR packet and map it to the * local rtptime. The local rtp time is used to construct timestamps on the @@ -1021,6 +999,7 @@ gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer) gboolean more; guint64 clock_base; guint64 clock_base_time; + guint clock_rate; stream = gst_pad_get_element_private (pad); bin = stream->bin; @@ -1035,7 +1014,7 @@ gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer) * constructs gstreamer timestamps from rtp timestamps and so it know exactly * what the current situation is. */ gst_rtp_jitter_buffer_get_sync (GST_RTP_JITTER_BUFFER (stream->buffer), - &clock_base, &clock_base_time); + &clock_base, &clock_base_time, &clock_rate); /* clock base changes when there is a huge gap in the timestamps or seqnum. * When this happens we don't want to calculate the extended timestamp based @@ -1098,6 +1077,7 @@ gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer) if (type == GST_RTCP_SDES_CNAME) { stream->clock_base = clock_base; stream->clock_base_time = clock_base_time; + stream->clock_rate = clock_rate; /* associate the stream to CNAME */ gst_rtp_bin_associate (bin, stream, len, data); } @@ -1150,7 +1130,7 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) stream->buffer = buffer; stream->demux = demux; stream->last_extrtptime = -1; - stream->last_pt = -1; + stream->clock_rate = -1; stream->have_sync = FALSE; session->streams = g_slist_prepend (session->streams, stream); @@ -1961,15 +1941,6 @@ caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session) GST_RTP_SESSION_UNLOCK (session); } -/* Stores the last payload type received on a particular stream */ -static void -payload_type_change (GstElement * element, guint pt, GstRtpBinStream * stream) -{ - GST_RTP_SESSION_LOCK (stream->session); - stream->last_pt = pt; - GST_RTP_SESSION_UNLOCK (stream->session); -} - /* a new pad (SSRC) was created in @session */ static void new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, @@ -2004,14 +1975,6 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, s = gst_caps_get_structure (caps, 0); - if (!gst_structure_get_int (s, "clock-rate", &stream->clock_rate)) { - stream->clock_rate = -1; - - GST_WARNING_OBJECT (rtpbin, - "Caps have no clock rate %s from pad %s:%s", - gst_caps_to_string (caps), GST_DEBUG_PAD_NAME (pad)); - } - stream->last_clock_base = -1; if (gst_structure_get_uint (s, "clock-base", &val)) stream->clock_base = val; @@ -2048,11 +2011,6 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, * depayloaders. */ stream->demux_ptreq_sig = g_signal_connect (stream->demux, "request-pt-map", (GCallback) pt_map_requested, session); - /* connect to the payload-type-change signal so that we can know which - * PT is the current PT so that the jitterbuffer can be matched to the right - * offset. */ - stream->demux_pt_change_sig = g_signal_connect (stream->demux, - "payload-type-change", (GCallback) payload_type_change, stream); GST_RTP_SESSION_UNLOCK (session); GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index 779ee5de..bd47bde4 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -851,6 +851,9 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstBuffer * buffer) if (G_UNLIKELY (priv->last_pt != pt)) { GstCaps *caps; + GST_DEBUG_OBJECT (jitterbuffer, "pt changed from %u to %u", priv->last_pt, + pt); + priv->last_pt = pt; /* reset clock-rate so that we get a new one */ priv->clock_rate = -1; @@ -865,7 +868,7 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstBuffer * buffer) /* no clock rate given on the caps, try to get one with the signal */ gst_rtp_jitter_buffer_get_clock_rate (jitterbuffer, pt); if (G_UNLIKELY (priv->clock_rate == -1)) - goto not_negotiated; + goto no_clock_rate; } /* take the timestamp of the buffer. This is the time when the packet was @@ -997,9 +1000,10 @@ invalid_buffer: gst_object_unref (jitterbuffer); return GST_FLOW_OK; } -not_negotiated: +no_clock_rate: { - GST_WARNING_OBJECT (jitterbuffer, "No clock-rate in caps!"); + GST_WARNING_OBJECT (jitterbuffer, + "No clock-rate in caps!, dropping buffer"); gst_buffer_unref (buffer); gst_object_unref (jitterbuffer); return GST_FLOW_OK; @@ -1484,7 +1488,7 @@ gst_rtp_jitter_buffer_get_property (GObject * object, void gst_rtp_jitter_buffer_get_sync (GstRtpJitterBuffer * buffer, guint64 * rtptime, - guint64 * timestamp) + guint64 * timestamp, guint32 * clock_rate) { GstRtpJitterBufferPrivate *priv; @@ -1493,6 +1497,6 @@ gst_rtp_jitter_buffer_get_sync (GstRtpJitterBuffer * buffer, guint64 * rtptime, priv = buffer->priv; JBUF_LOCK (priv); - rtp_jitter_buffer_get_sync (priv->jbuf, rtptime, timestamp); + rtp_jitter_buffer_get_sync (priv->jbuf, rtptime, timestamp, clock_rate); JBUF_UNLOCK (priv); } diff --git a/gst/rtpmanager/gstrtpjitterbuffer.h b/gst/rtpmanager/gstrtpjitterbuffer.h index 15185a25..40908eab 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.h +++ b/gst/rtpmanager/gstrtpjitterbuffer.h @@ -80,7 +80,8 @@ struct _GstRtpJitterBufferClass GType gst_rtp_jitter_buffer_get_type (void); void gst_rtp_jitter_buffer_get_sync (GstRtpJitterBuffer *buffer, - guint64 *rtptime, guint64 *timestamp); + guint64 *rtptime, guint64 *timestamp, + guint32 *clock_rate); G_END_DECLS diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index 9f3545ec..6e34705e 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -353,7 +353,7 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) gst_pad_set_active (srcpad, TRUE); gst_element_add_pad (element, srcpad); - GST_DEBUG ("emitting new-payload_type for pt %d", pt); + GST_DEBUG ("emitting new-payload-type for pt %d", pt); g_signal_emit (G_OBJECT (rtpdemux), gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad); } diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c index de3247fd..6cfbab61 100644 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ b/gst/rtpmanager/rtpjitterbuffer.c @@ -105,6 +105,7 @@ rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf) jbuf->base_time = -1; jbuf->base_rtptime = -1; jbuf->base_extrtp = -1; + jbuf->clock_rate = -1; jbuf->ext_rtptime = -1; jbuf->window_pos = 0; jbuf->window_filling = TRUE; @@ -187,6 +188,13 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, gstrtptime = gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, clock_rate); + if (jbuf->clock_rate != -1 && jbuf->clock_rate != clock_rate) { + GST_DEBUG ("Clock rate changed from %" G_GUINT32_FORMAT " to %" + G_GUINT32_FORMAT, jbuf->clock_rate, clock_rate); + jbuf->base_time = -1; + jbuf->base_rtptime = -1; + } + /* first time, lock on to time and gstrtptime */ if (G_UNLIKELY (jbuf->base_time == -1)) { jbuf->base_time = time; @@ -194,6 +202,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, } if (G_UNLIKELY (jbuf->base_rtptime == -1)) { jbuf->base_rtptime = gstrtptime; + jbuf->clock_rate = clock_rate; jbuf->base_extrtp = ext_rtptime; GST_DEBUG ("Taking new base rtptime %" GST_TIME_FORMAT, GST_TIME_ARGS (gstrtptime)); @@ -207,6 +216,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, GST_DEBUG ("backward timestamps at server, taking new base time"); jbuf->base_time = time; jbuf->base_rtptime = gstrtptime; + jbuf->clock_rate = clock_rate; jbuf->base_extrtp = ext_rtptime; send_diff = 0; } @@ -218,7 +228,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, /* we don't have an arrival timestamp so we can't do skew detection. we * should still apply a timestamp based on RTP timestamp and base_time */ - if (time == -1) + if (time == -1 || jbuf->base_time == -1) goto no_skew; /* elapsed time at receiver, includes the jitter */ @@ -240,6 +250,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, jbuf->base_time = time; jbuf->base_rtptime = gstrtptime; jbuf->base_extrtp = ext_rtptime; + jbuf->clock_rate = clock_rate; send_diff = 0; delta = 0; } @@ -320,7 +331,10 @@ calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, no_skew: /* the output time is defined as the base timestamp plus the RTP time * adjusted for the clock skew .*/ - out_time = jbuf->base_time + send_diff + jbuf->skew; + if (jbuf->base_time != -1) + out_time = jbuf->base_time + send_diff + jbuf->skew; + else + out_time = -1; GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT, jbuf->skew, GST_TIME_ARGS (out_time)); @@ -521,16 +535,19 @@ rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf) * @jbuf: an #RTPJitterBuffer * @rtptime: result RTP time * @timestamp: result GStreamer timestamp + * @clock_rate: clock-rate of @rtptime * * Returns the relation between the RTP timestamp and the GStreamer timestamp * used for constructing timestamps. */ void rtp_jitter_buffer_get_sync (RTPJitterBuffer * jbuf, guint64 * rtptime, - guint64 * timestamp) + guint64 * timestamp, guint32 * clock_rate) { if (rtptime) *rtptime = jbuf->base_extrtp; if (timestamp) *timestamp = jbuf->base_time + jbuf->skew; + if (clock_rate) + *clock_rate = jbuf->clock_rate; } diff --git a/gst/rtpmanager/rtpjitterbuffer.h b/gst/rtpmanager/rtpjitterbuffer.h index 62f3f47e..325f8f7b 100644 --- a/gst/rtpmanager/rtpjitterbuffer.h +++ b/gst/rtpmanager/rtpjitterbuffer.h @@ -56,6 +56,7 @@ struct _RTPJitterBuffer { /* for calculating skew */ GstClockTime base_time; GstClockTime base_rtptime; + guint32 clock_rate; GstClockTime base_extrtp; guint64 ext_rtptime; gint64 window[RTP_JITTER_BUFFER_MAX_WINDOW]; @@ -91,7 +92,7 @@ guint rtp_jitter_buffer_num_packets (RTPJitterBuffer *jbuf) guint32 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer *jbuf); void rtp_jitter_buffer_get_sync (RTPJitterBuffer *jbuf, guint64 *rtptime, - guint64 *timestamp); + guint64 *timestamp, guint32 *clock_rate); #endif /* __RTP_JITTER_BUFFER_H__ */ diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index af4d3dcd..102ac063 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -721,18 +721,23 @@ push_packet (RTPSource * src, GstBuffer * buffer) static gint get_clock_rate (RTPSource * src, guint8 payload) { + if (payload != src->payload) { + GST_DEBUG ("new payload %d", payload); + src->payload = payload; + src->clock_rate = -1; + src->stats.transit = -1; + } + if (src->clock_rate == -1) { gint clock_rate = -1; if (src->callbacks.clock_rate) clock_rate = src->callbacks.clock_rate (src, payload, src->user_data); - GST_DEBUG ("new payload %d, got clock-rate %d", payload, clock_rate); + GST_DEBUG ("got clock-rate %d", payload, clock_rate); src->clock_rate = clock_rate; } - src->payload = payload; - return src->clock_rate; } -- cgit v1.2.1