guint64 clock_base_time;
gint clock_rate;
gint64 ts_offset;
- gint last_pt;
};
#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock)
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
gboolean more;
guint64 clock_base;
guint64 clock_base_time;
+ guint clock_rate;
stream = gst_pad_get_element_private (pad);
bin = stream->bin;
* 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
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);
}
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);
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,
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;
* 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);
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;
/* 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
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;
void
gst_rtp_jitter_buffer_get_sync (GstRtpJitterBuffer * buffer, guint64 * rtptime,
- guint64 * timestamp)
+ guint64 * timestamp, guint32 * clock_rate)
{
GstRtpJitterBufferPrivate *priv;
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);
}
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
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);
}
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;
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;
}
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));
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;
}
/* 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 */
jbuf->base_time = time;
jbuf->base_rtptime = gstrtptime;
jbuf->base_extrtp = ext_rtptime;
+ jbuf->clock_rate = clock_rate;
send_diff = 0;
delta = 0;
}
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));
* @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;
}
/* 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];
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__ */
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;
}