summaryrefslogtreecommitdiffstats
path: root/gst/rtpmanager/gstrtpbin.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2008-09-05 13:52:34 +0000
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2009-08-11 02:30:37 +0100
commit85e26f65468b6407ef753220c70695ef87700045 (patch)
treee29d4d0f0f987f8021e2f3cba549a563f6fddd13 /gst/rtpmanager/gstrtpbin.c
parent5c89bb2ab3a15eafcb59581cfc2bf5e477cafc73 (diff)
gst/rtpmanager/gstrtpbin.*: Add signal to notify listeners when a sender becomes a receiver.
Original commit message from CVS: * gst/rtpmanager/gstrtpbin.c: (on_sender_timeout), (create_session), (gst_rtp_bin_associate), (gst_rtp_bin_sync_chain), (gst_rtp_bin_class_init), (gst_rtp_bin_request_new_pad): * gst/rtpmanager/gstrtpbin.h: Add signal to notify listeners when a sender becomes a receiver. Tweak lip-sync code, don't store our own copy of the ts-offset of the jitterbuffer, don't adjust sync if the change is less than 4msec. Get the RTP timestamp <-> GStreamer timestamp relation directly from the jitterbuffer instead of our inaccurate version from the source. * gst/rtpmanager/gstrtpjitterbuffer.c: (gst_rtp_jitter_buffer_chain), (gst_rtp_jitter_buffer_loop), (gst_rtp_jitter_buffer_get_sync): * gst/rtpmanager/gstrtpjitterbuffer.h: Add G_LIKELY macros, use global defines for max packet reorder and dropouts. Reset the jitterbuffer clock skew detection when packets seqnums are changed unexpectedly. * gst/rtpmanager/gstrtpsession.c: (on_sender_timeout), (gst_rtp_session_class_init), (gst_rtp_session_init): * gst/rtpmanager/gstrtpsession.h: Add sender timeout signal. * gst/rtpmanager/rtpjitterbuffer.c: (rtp_jitter_buffer_reset_skew), (calculate_skew), (rtp_jitter_buffer_insert), (rtp_jitter_buffer_get_sync): * gst/rtpmanager/rtpjitterbuffer.h: Add some G_LIKELY macros. Keep track of the extended RTP timestamp so that we can report the RTP timestamp <-> GStreamer timestamp relation for lip-sync. Remove server timestamp gap detection code, the server can sometimes make a huge gap in timestamps (talk spurts,...) see #549774. Detect timetamp weirdness instead by observing the sender/receiver timestamp relation and resync if it changes more than 1 second. Add method to report about the current rtp <-> gst timestamp relation which is needed for lip-sync. * gst/rtpmanager/rtpsession.c: (rtp_session_class_init), (on_sender_timeout), (check_collision), (rtp_session_process_sr), (session_cleanup): * gst/rtpmanager/rtpsession.h: Add sender timeout signal. Remove inaccurate rtp <-> gst timestamp relation code, the jitterbuffer can now do an accurate reporting about this. * gst/rtpmanager/rtpsource.c: (rtp_source_init), (rtp_source_update_caps), (calculate_jitter), (rtp_source_process_rtp): * gst/rtpmanager/rtpsource.h: Remove inaccurate rtp <-> gst timestamp relation code. * gst/rtpmanager/rtpstats.h: Define global max-reorder and max-dropout constants for use in various subsystems.
Diffstat (limited to 'gst/rtpmanager/gstrtpbin.c')
-rw-r--r--gst/rtpmanager/gstrtpbin.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c
index 46ef4bb9..7f402c36 100644
--- a/gst/rtpmanager/gstrtpbin.c
+++ b/gst/rtpmanager/gstrtpbin.c
@@ -120,6 +120,7 @@
#include "gstrtpbin-marshal.h"
#include "gstrtpbin.h"
#include "gstrtpsession.h"
+#include "gstrtpjitterbuffer.h"
GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug);
#define GST_CAT_DEFAULT gst_rtp_bin_debug
@@ -236,6 +237,7 @@ enum
SIGNAL_ON_BYE_SSRC,
SIGNAL_ON_BYE_TIMEOUT,
SIGNAL_ON_TIMEOUT,
+ SIGNAL_ON_SENDER_TIMEOUT,
LAST_SIGNAL
};
@@ -323,7 +325,6 @@ struct _GstRtpBinStream
guint64 clock_base_time;
gint clock_rate;
gint64 ts_offset;
- gint64 prev_ts_offset;
gint last_pt;
};
@@ -455,6 +456,13 @@ on_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
sess->id, ssrc);
}
+static void
+on_sender_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
+{
+ g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT], 0,
+ sess->id, ssrc);
+}
+
/* create a session with the given id. Must be called with RTP_BIN_LOCK */
static GstRtpBinSession *
create_session (GstRtpBin * rtpbin, gint id)
@@ -507,6 +515,8 @@ create_session (GstRtpBin * rtpbin, gint id)
g_signal_connect (sess->session, "on-bye-timeout",
(GCallback) on_bye_timeout, sess);
g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
+ g_signal_connect (sess->session, "on-sender-timeout",
+ (GCallback) on_sender_timeout, sess);
/* FIXME, change state only to what's needed */
gst_bin_add (GST_BIN_CAST (rtpbin), session);
@@ -863,32 +873,31 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
/* calculate offsets for each stream */
for (walk = client->streams; walk; walk = g_slist_next (walk)) {
GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
-
- if (ostream->unix_delta == 0)
- continue;
+ gint64 prev_ts_offset;
ostream->ts_offset = ostream->unix_delta - min;
+ g_object_get (ostream->buffer, "ts-offset", &prev_ts_offset, NULL);
+
/* delta changed, see how much */
- if (ostream->prev_ts_offset != ostream->ts_offset) {
+ if (prev_ts_offset != ostream->ts_offset) {
gint64 diff;
- if (ostream->prev_ts_offset > ostream->ts_offset)
- diff = ostream->prev_ts_offset - ostream->ts_offset;
+ if (prev_ts_offset > ostream->ts_offset)
+ diff = prev_ts_offset - ostream->ts_offset;
else
- diff = ostream->ts_offset - ostream->prev_ts_offset;
+ diff = ostream->ts_offset - prev_ts_offset;
GST_DEBUG_OBJECT (bin,
"ts-offset %" G_GUINT64_FORMAT ", prev %" G_GUINT64_FORMAT
- ", diff: %" G_GINT64_FORMAT, ostream->ts_offset,
- ostream->prev_ts_offset, diff);
+ ", diff: %" G_GINT64_FORMAT, ostream->ts_offset, prev_ts_offset,
+ diff);
- /* only change diff when it changed more than 1 millisecond. This
+ /* only change diff when it changed more than 4 milliseconds. This
* compensates for rounding errors in NTP to RTP timestamp
* conversions */
- if (diff > GST_MSECOND && diff < (3 * GST_SECOND)) {
+ if (diff > 4 * GST_MSECOND && diff < (3 * GST_SECOND)) {
g_object_set (ostream->buffer, "ts-offset", ostream->ts_offset, NULL);
- ostream->prev_ts_offset = ostream->ts_offset;
}
}
GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
@@ -937,8 +946,7 @@ gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer)
gboolean have_sr, have_sdes;
gboolean more;
guint64 clock_base;
-
- clock_base = GST_BUFFER_OFFSET (buffer);
+ guint64 clock_base_time;
stream = gst_pad_get_element_private (pad);
bin = stream->bin;
@@ -948,6 +956,12 @@ gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer)
if (!gst_rtcp_buffer_validate (buffer))
goto invalid_rtcp;
+ /* get the last relation between the rtp timestamps and the gstreamer
+ * timestamps. We get this info directly from the jitterbuffer which
+ * constructs gstreamer timestamps from rtp timestamps */
+ gst_rtp_jitter_buffer_get_sync (GST_RTP_JITTER_BUFFER (stream->buffer),
+ &clock_base, &clock_base_time);
+
/* 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
* on the previous one but reset the calculation. */
@@ -1008,7 +1022,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 = GST_BUFFER_OFFSET_END (buffer);
+ stream->clock_base_time = clock_base_time;
/* associate the stream to CNAME */
gst_rtp_bin_associate (bin, stream, len, data);
}
@@ -1328,6 +1342,19 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_timeout),
NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
G_TYPE_UINT, G_TYPE_UINT);
+ /**
+ * GstRtpBin::on-sender-timeout:
+ * @rtpbin: the object which received the signal
+ * @session: the session
+ * @ssrc: the SSRC
+ *
+ * Notify of a sender SSRC that has timed out and became a receiver
+ */
+ gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT] =
+ g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_sender_timeout),
+ NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
+ G_TYPE_UINT, G_TYPE_UINT);
g_object_class_install_property (gobject_class, PROP_SDES_CNAME,
g_param_spec_string ("sdes-cname", "SDES CNAME",
@@ -2332,6 +2359,7 @@ gst_rtp_bin_request_new_pad (GstElement * element,
GstRtpBin *rtpbin;
GstElementClass *klass;
GstPad *result;
+
gchar *pad_name = NULL;
g_return_val_if_fail (templ != NULL, NULL);