mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 05:28:48 +00:00
gst/rtpmanager/gstrtpbin.*: Remove a lot of per stream state that is not needed and pass new info in the method call.
Original commit message from CVS: * gst/rtpmanager/gstrtpbin.c: (get_client), (gst_rtp_bin_reset_sync), (gst_rtp_bin_associate), (gst_rtp_bin_handle_sync), (create_stream), (gst_rtp_bin_class_init), (new_ssrc_pad_found): * gst/rtpmanager/gstrtpbin.h: Remove a lot of per stream state that is not needed and pass new info in the method call. Add signal to reset sync parameters. Avoid parsing the caps to get a clock_base, we get this from the sync signal now.
This commit is contained in:
parent
1f99f89e59
commit
b51514fc26
3 changed files with 80 additions and 66 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2008-11-26 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/rtpmanager/gstrtpbin.c: (get_client),
|
||||||
|
(gst_rtp_bin_reset_sync), (gst_rtp_bin_associate),
|
||||||
|
(gst_rtp_bin_handle_sync), (create_stream),
|
||||||
|
(gst_rtp_bin_class_init), (new_ssrc_pad_found):
|
||||||
|
* gst/rtpmanager/gstrtpbin.h:
|
||||||
|
Remove a lot of per stream state that is not needed and pass new info in
|
||||||
|
the method call.
|
||||||
|
Add signal to reset sync parameters.
|
||||||
|
Avoid parsing the caps to get a clock_base, we get this from the sync
|
||||||
|
signal now.
|
||||||
|
|
||||||
2008-11-26 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-11-26 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/mxf/mxfdemux.c: (gst_mxf_pad_init),
|
* gst/mxf/mxfdemux.c: (gst_mxf_pad_init),
|
||||||
|
|
|
@ -221,6 +221,7 @@ enum
|
||||||
{
|
{
|
||||||
SIGNAL_REQUEST_PT_MAP,
|
SIGNAL_REQUEST_PT_MAP,
|
||||||
SIGNAL_CLEAR_PT_MAP,
|
SIGNAL_CLEAR_PT_MAP,
|
||||||
|
SIGNAL_RESET_SYNC,
|
||||||
SIGNAL_GET_INTERNAL_SESSION,
|
SIGNAL_GET_INTERNAL_SESSION,
|
||||||
|
|
||||||
SIGNAL_ON_NEW_SSRC,
|
SIGNAL_ON_NEW_SSRC,
|
||||||
|
@ -302,22 +303,10 @@ struct _GstRtpBinStream
|
||||||
gulong demux_ptreq_sig;
|
gulong demux_ptreq_sig;
|
||||||
gulong demux_pt_change_sig;
|
gulong demux_pt_change_sig;
|
||||||
|
|
||||||
/* data for the RTCP sync signal */
|
/* if we have calculated a valid unix_delta for this stream */
|
||||||
gboolean have_sync;
|
gboolean have_sync;
|
||||||
guint64 last_unix;
|
|
||||||
guint64 last_extrtptime;
|
|
||||||
|
|
||||||
/* mapping to local RTP and NTP time */
|
/* mapping to local RTP and NTP time */
|
||||||
guint64 local_rtp;
|
|
||||||
guint64 local_unix;
|
|
||||||
gint64 unix_delta;
|
gint64 unix_delta;
|
||||||
|
|
||||||
/* for lip-sync */
|
|
||||||
guint64 last_clock_base;
|
|
||||||
guint64 clock_base;
|
|
||||||
guint64 clock_base_time;
|
|
||||||
gint clock_rate;
|
|
||||||
gint64 ts_offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock)
|
#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock)
|
||||||
|
@ -373,8 +362,6 @@ struct _GstRtpBinClient
|
||||||
/* the streams */
|
/* the streams */
|
||||||
guint nstreams;
|
guint nstreams;
|
||||||
GSList *streams;
|
GSList *streams;
|
||||||
|
|
||||||
gint64 min_delta;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* find a session with the given id. Must be called with RTP_BIN_LOCK */
|
/* find a session with the given id. Must be called with RTP_BIN_LOCK */
|
||||||
|
@ -792,7 +779,6 @@ get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created)
|
||||||
result = g_new0 (GstRtpBinClient, 1);
|
result = g_new0 (GstRtpBinClient, 1);
|
||||||
result->cname = g_strndup ((gchar *) data, len);
|
result->cname = g_strndup ((gchar *) data, len);
|
||||||
result->cname_len = len;
|
result->cname_len = len;
|
||||||
result->min_delta = G_MAXINT64;
|
|
||||||
bin->clients = g_slist_prepend (bin->clients, result);
|
bin->clients = g_slist_prepend (bin->clients, result);
|
||||||
GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result,
|
GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result,
|
||||||
result->cname);
|
result->cname);
|
||||||
|
@ -808,16 +794,43 @@ free_client (GstRtpBinClient * client)
|
||||||
g_free (client);
|
g_free (client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtp_bin_reset_sync (GstRtpBin * rtpbin)
|
||||||
|
{
|
||||||
|
GSList *clients, *streams;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtpbin, "Reset sync on all clients");
|
||||||
|
|
||||||
|
GST_RTP_BIN_LOCK (rtpbin);
|
||||||
|
for (clients = rtpbin->clients; clients; clients = g_slist_next (clients)) {
|
||||||
|
GstRtpBinClient *client = (GstRtpBinClient *) clients->data;
|
||||||
|
|
||||||
|
/* reset sync on all streams for this client */
|
||||||
|
for (streams = client->streams; streams; streams = g_slist_next (streams)) {
|
||||||
|
GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
|
||||||
|
|
||||||
|
/* make use require a new SR packet for this stream before we attempt new
|
||||||
|
* lip-sync */
|
||||||
|
stream->have_sync = FALSE;
|
||||||
|
stream->unix_delta = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_RTP_BIN_UNLOCK (rtpbin);
|
||||||
|
}
|
||||||
|
|
||||||
/* associate a stream to the given CNAME. This will make sure all streams for
|
/* associate a stream to the given CNAME. This will make sure all streams for
|
||||||
* that CNAME are synchronized together.
|
* that CNAME are synchronized together.
|
||||||
* Must be called with GST_RTP_BIN_LOCK */
|
* Must be called with GST_RTP_BIN_LOCK */
|
||||||
static void
|
static void
|
||||||
gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
guint8 * data)
|
guint8 * data, guint64 last_unix, guint64 last_extrtptime,
|
||||||
|
guint64 clock_base, guint64 clock_base_time, guint clock_rate)
|
||||||
{
|
{
|
||||||
GstRtpBinClient *client;
|
GstRtpBinClient *client;
|
||||||
gboolean created;
|
gboolean created;
|
||||||
GSList *walk;
|
GSList *walk;
|
||||||
|
guint64 local_unix;
|
||||||
|
guint64 local_rtp;
|
||||||
|
|
||||||
/* first find or create the CNAME */
|
/* first find or create the CNAME */
|
||||||
client = get_client (bin, len, data, &created);
|
client = get_client (bin, len, data, &created);
|
||||||
|
@ -845,29 +858,28 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
/* take the extended rtptime we found in the SR packet and map it to the
|
/* 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
|
* local rtptime. The local rtp time is used to construct timestamps on the
|
||||||
* buffers. */
|
* buffers. */
|
||||||
stream->local_rtp = stream->last_extrtptime - stream->clock_base;
|
local_rtp = last_extrtptime - clock_base;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bin,
|
GST_DEBUG_OBJECT (bin,
|
||||||
"base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT
|
"base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT
|
||||||
", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", stream->clock_base,
|
", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", clock_base,
|
||||||
stream->last_extrtptime, stream->local_rtp, stream->clock_rate);
|
last_extrtptime, local_rtp, clock_rate);
|
||||||
|
|
||||||
/* calculate local NTP time in gstreamer timestamp, we essentially perform the
|
/* calculate local NTP time in gstreamer timestamp, we essentially perform the
|
||||||
* same conversion that a jitterbuffer would use to convert an rtp timestamp
|
* same conversion that a jitterbuffer would use to convert an rtp timestamp
|
||||||
* into a corresponding gstreamer timestamp. */
|
* into a corresponding gstreamer timestamp. */
|
||||||
stream->local_unix =
|
local_unix = gst_util_uint64_scale_int (local_rtp, GST_SECOND, clock_rate);
|
||||||
gst_util_uint64_scale_int (stream->local_rtp, GST_SECOND,
|
local_unix += clock_base_time;
|
||||||
stream->clock_rate);
|
|
||||||
stream->local_unix += stream->clock_base_time;
|
|
||||||
/* calculate delta between server and receiver. last_unix is created by
|
/* calculate delta between server and receiver. last_unix is created by
|
||||||
* converting the ntptime in the last SR packet to a gstreamer timestamp. This
|
* converting the ntptime in the last SR packet to a gstreamer timestamp. This
|
||||||
* delta expresses the difference to our timeline and the server timeline. */
|
* delta expresses the difference to our timeline and the server timeline. */
|
||||||
stream->unix_delta = stream->last_unix - stream->local_unix;
|
stream->unix_delta = last_unix - local_unix;
|
||||||
|
stream->have_sync = TRUE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bin,
|
GST_DEBUG_OBJECT (bin,
|
||||||
"local UNIX %" G_GUINT64_FORMAT ", remote UNIX %" G_GUINT64_FORMAT
|
"local UNIX %" G_GUINT64_FORMAT ", remote UNIX %" G_GUINT64_FORMAT
|
||||||
", delta %" G_GINT64_FORMAT, stream->local_unix, stream->last_unix,
|
", delta %" G_GINT64_FORMAT, local_unix, last_unix, stream->unix_delta);
|
||||||
stream->unix_delta);
|
|
||||||
|
|
||||||
/* recalc inter stream playout offset, but only if there is more than one
|
/* recalc inter stream playout offset, but only if there is more than one
|
||||||
* stream. */
|
* stream. */
|
||||||
|
@ -900,7 +912,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
/* calculate offsets for each stream */
|
/* calculate offsets for each stream */
|
||||||
for (walk = client->streams; walk; walk = g_slist_next (walk)) {
|
for (walk = client->streams; walk; walk = g_slist_next (walk)) {
|
||||||
GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
|
GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
|
||||||
gint64 prev_ts_offset;
|
gint64 ts_offset, prev_ts_offset;
|
||||||
|
|
||||||
/* ignore streams for which we didn't receive an SR packet yet, we
|
/* ignore streams for which we didn't receive an SR packet yet, we
|
||||||
* can't synchronize them yet. We can however sync other streams just
|
* can't synchronize them yet. We can however sync other streams just
|
||||||
|
@ -910,33 +922,32 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
|
|
||||||
/* calculate offset to our reference stream, this should always give a
|
/* calculate offset to our reference stream, this should always give a
|
||||||
* positive number. */
|
* positive number. */
|
||||||
ostream->ts_offset = ostream->unix_delta - min;
|
ts_offset = ostream->unix_delta - min;
|
||||||
|
|
||||||
g_object_get (ostream->buffer, "ts-offset", &prev_ts_offset, NULL);
|
g_object_get (ostream->buffer, "ts-offset", &prev_ts_offset, NULL);
|
||||||
|
|
||||||
/* delta changed, see how much */
|
/* delta changed, see how much */
|
||||||
if (prev_ts_offset != ostream->ts_offset) {
|
if (prev_ts_offset != ts_offset) {
|
||||||
gint64 diff;
|
gint64 diff;
|
||||||
|
|
||||||
if (prev_ts_offset > ostream->ts_offset)
|
if (prev_ts_offset > ts_offset)
|
||||||
diff = prev_ts_offset - ostream->ts_offset;
|
diff = prev_ts_offset - ts_offset;
|
||||||
else
|
else
|
||||||
diff = ostream->ts_offset - prev_ts_offset;
|
diff = ts_offset - prev_ts_offset;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bin,
|
GST_DEBUG_OBJECT (bin,
|
||||||
"ts-offset %" G_GUINT64_FORMAT ", prev %" G_GUINT64_FORMAT
|
"ts-offset %" G_GUINT64_FORMAT ", prev %" G_GUINT64_FORMAT
|
||||||
", diff: %" G_GINT64_FORMAT, ostream->ts_offset, prev_ts_offset,
|
", diff: %" G_GINT64_FORMAT, ts_offset, prev_ts_offset, diff);
|
||||||
diff);
|
|
||||||
|
|
||||||
/* only change diff when it changed more than 4 milliseconds. This
|
/* only change diff when it changed more than 4 milliseconds. This
|
||||||
* compensates for rounding errors in NTP to RTP timestamp
|
* compensates for rounding errors in NTP to RTP timestamp
|
||||||
* conversions */
|
* conversions */
|
||||||
if (diff > 4 * 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);
|
g_object_set (ostream->buffer, "ts-offset", ts_offset, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
|
GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
|
||||||
ostream->ssrc, ostream->ts_offset);
|
ostream->ssrc, ts_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1032,15 +1043,10 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s,
|
||||||
|
|
||||||
if (type == GST_RTCP_SDES_CNAME) {
|
if (type == GST_RTCP_SDES_CNAME) {
|
||||||
GST_RTP_BIN_LOCK (bin);
|
GST_RTP_BIN_LOCK (bin);
|
||||||
/* store values in the stream */
|
|
||||||
stream->have_sync = TRUE;
|
|
||||||
stream->last_unix = gst_rtcp_ntp_to_unix (ntptime);
|
|
||||||
stream->last_extrtptime = extrtptime;
|
|
||||||
stream->clock_base = clock_base;
|
|
||||||
stream->clock_base_time = clock_base_time;
|
|
||||||
stream->clock_rate = clock_rate;
|
|
||||||
/* associate the stream to CNAME */
|
/* associate the stream to CNAME */
|
||||||
gst_rtp_bin_associate (bin, stream, len, data);
|
gst_rtp_bin_associate (bin, stream, len, data,
|
||||||
|
gst_rtcp_ntp_to_unix (ntptime), extrtptime,
|
||||||
|
clock_base, clock_base_time, clock_rate);
|
||||||
GST_RTP_BIN_UNLOCK (bin);
|
GST_RTP_BIN_UNLOCK (bin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1075,9 +1081,8 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
|
||||||
stream->session = session;
|
stream->session = session;
|
||||||
stream->buffer = buffer;
|
stream->buffer = buffer;
|
||||||
stream->demux = demux;
|
stream->demux = demux;
|
||||||
stream->last_extrtptime = -1;
|
|
||||||
stream->clock_rate = -1;
|
|
||||||
stream->have_sync = FALSE;
|
stream->have_sync = FALSE;
|
||||||
|
stream->unix_delta = 0;
|
||||||
session->streams = g_slist_prepend (session->streams, stream);
|
session->streams = g_slist_prepend (session->streams, stream);
|
||||||
|
|
||||||
/* provide clock_rate to the jitterbuffer when needed */
|
/* provide clock_rate to the jitterbuffer when needed */
|
||||||
|
@ -1222,6 +1227,19 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
|
||||||
clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
|
clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
|
||||||
0, G_TYPE_NONE);
|
0, G_TYPE_NONE);
|
||||||
|
/**
|
||||||
|
* GstRtpBin::reset-sync:
|
||||||
|
* @rtpbin: the object which received the signal
|
||||||
|
*
|
||||||
|
* Reset all currently configured lip-sync parameters and require new SR
|
||||||
|
* packets for all streams before lip-sync is attempted again.
|
||||||
|
*/
|
||||||
|
gst_rtp_bin_signals[SIGNAL_RESET_SYNC] =
|
||||||
|
g_signal_new ("reset-sync", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
|
||||||
|
reset_sync), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
|
||||||
|
0, G_TYPE_NONE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRtpBin::get-internal-session:
|
* GstRtpBin::get-internal-session:
|
||||||
* @rtpbin: the object which received the signal
|
* @rtpbin: the object which received the signal
|
||||||
|
@ -1404,6 +1422,7 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
||||||
gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
|
gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
|
||||||
|
|
||||||
klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
|
klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
|
||||||
|
klass->reset_sync = GST_DEBUG_FUNCPTR (gst_rtp_bin_reset_sync);
|
||||||
klass->get_internal_session =
|
klass->get_internal_session =
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session);
|
GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session);
|
||||||
|
|
||||||
|
@ -1881,7 +1900,6 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
|
||||||
GstRtpBinStream *stream;
|
GstRtpBinStream *stream;
|
||||||
GstPad *sinkpad, *srcpad;
|
GstPad *sinkpad, *srcpad;
|
||||||
gchar *padname;
|
gchar *padname;
|
||||||
GstCaps *caps;
|
|
||||||
|
|
||||||
rtpbin = session->bin;
|
rtpbin = session->bin;
|
||||||
|
|
||||||
|
@ -1897,24 +1915,6 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
|
||||||
if (!stream)
|
if (!stream)
|
||||||
goto no_stream;
|
goto no_stream;
|
||||||
|
|
||||||
/* get the caps of the pad, we need the clock-rate and base_time if any. */
|
|
||||||
if ((caps = gst_pad_get_caps (pad))) {
|
|
||||||
const GstStructure *s;
|
|
||||||
guint val;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpbin, "pad has caps %" GST_PTR_FORMAT, caps);
|
|
||||||
|
|
||||||
s = gst_caps_get_structure (caps, 0);
|
|
||||||
|
|
||||||
stream->last_clock_base = -1;
|
|
||||||
if (gst_structure_get_uint (s, "clock-base", &val))
|
|
||||||
stream->clock_base = val;
|
|
||||||
else
|
|
||||||
stream->clock_base = -1;
|
|
||||||
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get pad and link */
|
/* get pad and link */
|
||||||
GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP");
|
GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP");
|
||||||
padname = g_strdup_printf ("src_%d", ssrc);
|
padname = g_strdup_printf ("src_%d", ssrc);
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct _GstRtpBinClass {
|
||||||
|
|
||||||
/* action signals */
|
/* action signals */
|
||||||
void (*clear_pt_map) (GstRtpBin *rtpbin);
|
void (*clear_pt_map) (GstRtpBin *rtpbin);
|
||||||
|
void (*reset_sync) (GstRtpBin *rtpbin);
|
||||||
RTPSession* (*get_internal_session) (GstRtpBin *rtpbin, guint session_id);
|
RTPSession* (*get_internal_session) (GstRtpBin *rtpbin, guint session_id);
|
||||||
|
|
||||||
/* session manager signals */
|
/* session manager signals */
|
||||||
|
|
Loading…
Reference in a new issue