diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2008-09-05 13:52:34 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2008-09-05 13:52:34 +0000 |
commit | a35d1dde421be0655eb36fed9f415a25f5fa00e0 (patch) | |
tree | c0bfaa3e8fccfad821f2175dc419987caf0c2636 /gst/rtpmanager/gstrtpbin.c | |
parent | 64cd01e7e8a143e523466c911f7bb2e148508c3b (diff) | |
download | gst-plugins-bad-a35d1dde421be0655eb36fed9f415a25f5fa00e0.tar.gz gst-plugins-bad-a35d1dde421be0655eb36fed9f415a25f5fa00e0.tar.bz2 gst-plugins-bad-a35d1dde421be0655eb36fed9f415a25f5fa00e0.zip |
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.c | 60 |
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); |