guint sync_interval;
/* Reference for GstReferenceTimestampMeta */
- GstCaps *rfc7273_ref;
+ GstCaps *reference_timestamp_caps;
/* RTP header extension ID for RFC6051 64-bit NTP timestamps */
guint8 ntp64_ext_id;
/* the latency of the upstream peer, we have to take this into account when
* synchronizing the buffers. */
GstClockTime peer_latency;
- guint64 ext_rtptime;
+ guint64 last_sr_ext_rtptime;
GstBuffer *last_sr;
guint32 last_sr_ssrc;
GstClockTime last_sr_ntpnstime;
+ GstClockTime last_known_ntpnstime;
+ guint64 last_known_ext_rtptime;
+
/* some accounting */
guint64 num_pushed;
guint64 num_lost;
/**
* GstRtpJitterBuffer:add-reference-timestamp-meta:
*
- * When syncing to a RFC7273 clock, add #GstReferenceTimestampMeta
+ * When syncing to a RFC7273 clock or after clock synchronization via RTCP or
+ * inband NTP-64 header extensions has happened, add #GstReferenceTimestampMeta
* to buffers with the original reconstructed reference clock timestamp.
*
* Since: 1.22
g_param_spec_boolean ("add-reference-timestamp-meta",
"Add Reference Timestamp Meta",
"Add Reference Timestamp Meta to buffers with the original clock timestamp "
- "before any adjustments when syncing to an RFC7273 clock.",
+ "before any adjustments when syncing to an RFC7273 clock or after clock "
+ "synchronization via RTCP or inband NTP-64 header extensions has happened.",
DEFAULT_ADD_REFERENCE_TIMESTAMP_META,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
priv->last_pts = -1;
priv->last_rtptime = -1;
priv->last_ntpnstime = -1;
+ priv->last_known_ext_rtptime = -1;
+ priv->last_known_ntpnstime = -1;
priv->avg_jitter = 0;
priv->last_drop_msg_timestamp = GST_CLOCK_TIME_NONE;
priv->num_too_late = 0;
ts_meta_ref = gst_caps_new_simple ("timestamp/x-ptp",
"version", G_TYPE_STRING, "IEEE1588-2008",
"domain", G_TYPE_INT, domain, NULL);
+ } else if (!g_strcmp0 (ts_refclk, "local")) {
+ ts_meta_ref = gst_caps_new_empty_simple ("timestamp/x-ntp");
} else {
GST_FIXME_OBJECT (jitterbuffer, "Unsupported timestamp reference clock");
}
rtp_jitter_buffer_set_media_clock (priv->jbuf, clock, clock_offset);
} else {
rtp_jitter_buffer_set_media_clock (priv->jbuf, NULL, -1);
+ ts_meta_ref = gst_caps_new_empty_simple ("timestamp/x-ntp");
}
- gst_caps_take (&priv->rfc7273_ref, ts_meta_ref);
+ gst_caps_take (&priv->reference_timestamp_caps, ts_meta_ref);
_get_cname_ssrc_mappings (jitterbuffer, caps_struct);
priv->ntp64_ext_id =
priv->last_dts = -1;
priv->last_rtptime = -1;
priv->last_ntpnstime = -1;
+ priv->last_known_ext_rtptime = -1;
+ priv->last_known_ntpnstime = -1;
priv->last_in_pts = 0;
priv->equidistant = 0;
priv->segment_seqnum = GST_SEQNUM_INVALID;
JBUF_UNLOCK (priv);
g_thread_join (priv->timer_thread);
priv->timer_thread = NULL;
- gst_clear_caps (&priv->rfc7273_ref);
+ gst_clear_caps (&priv->reference_timestamp_caps);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
/* reset clock-rate so that we get a new one */
priv->clock_rate = -1;
+ priv->last_known_ext_rtptime = -1;
+ priv->last_known_ntpnstime = -1;
+
/* Try to get the clock-rate from the caps first if we can. If there are no
* caps we must fire the signal to get the clock-rate. */
if ((caps = gst_pad_get_current_caps (pad))) {
goto no_clock_rate;
gst_rtp_packet_rate_ctx_reset (&priv->packet_rate_ctx, priv->clock_rate);
+ priv->last_known_ext_rtptime = -1;
+ priv->last_known_ntpnstime = -1;
}
if (G_UNLIKELY (priv->last_ssrc != ssrc)) {
GST_DEBUG_OBJECT (jitterbuffer, "SSRC changed from %u to %u",
priv->last_ssrc, ssrc);
priv->last_ssrc = ssrc;
+ priv->last_known_ext_rtptime = -1;
+ priv->last_known_ntpnstime = -1;
}
/* don't accept more data on EOS */
priv->next_in_seqnum = (seqnum + 1) & 0xffff;
}
+ if (inband_ntp_time != GST_CLOCK_TIME_NONE) {
+ guint64 ext_rtptime;
+
+ ext_rtptime = priv->jbuf->ext_rtptime;
+ ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
+
+ priv->last_known_ext_rtptime = ext_rtptime;
+ priv->last_known_ntpnstime = inband_ntp_time;
+ }
+
if (is_rtx)
timer->num_rtx_received++;
JBUF_SIGNAL_EVENT (priv);
}
}
- // ntp_time will only be set in case of RFC7273 sync
+ // If we can calculate a NTP time based solely on the Sender Report, or
+ // inband NTP header extension do that so that we can still add a reference
+ // timestamp meta to the buffer
+ if (!GST_CLOCK_TIME_IS_VALID (ntp_time) &&
+ GST_CLOCK_TIME_IS_VALID (priv->last_known_ntpnstime) &&
+ priv->last_known_ext_rtptime != -1) {
+ guint64 ext_time = priv->last_known_ext_rtptime;
+
+ ext_time = gst_rtp_buffer_ext_timestamp (&ext_time, rtptime);
+
+ ntp_time =
+ priv->last_known_ntpnstime + gst_util_uint64_scale (ext_time -
+ priv->last_known_ext_rtptime, GST_SECOND, priv->clock_rate);
+ }
+
if (priv->add_reference_timestamp_meta && GST_CLOCK_TIME_IS_VALID (ntp_time)
- && priv->rfc7273_ref != NULL) {
+ && priv->reference_timestamp_caps != NULL) {
buffer = gst_buffer_make_writable (buffer);
+ GST_TRACE_OBJECT (jitterbuffer,
+ "adding NTP time reference meta: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (ntp_time));
+
gst_buffer_add_reference_timestamp_meta (buffer,
- priv->rfc7273_ref, ntp_time, GST_CLOCK_TIME_NONE);
+ priv->reference_timestamp_caps, ntp_time, GST_CLOCK_TIME_NONE);
}
/* If we estimated the DTS, don't consider it in the clock skew calculations
&clock_rate, &last_rtptime);
clock_base = priv->clock_base;
- ext_rtptime = priv->ext_rtptime;
+ ext_rtptime = priv->last_sr_ext_rtptime;
GST_DEBUG_OBJECT (jitterbuffer,
"ext SR %" G_GUINT64_FORMAT ", NTP %" G_GUINT64_FORMAT ", base %"
ext_rtptime = priv->jbuf->ext_rtptime;
ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
- priv->ext_rtptime = ext_rtptime;
+ priv->last_sr_ext_rtptime = ext_rtptime;
priv->last_sr_ssrc = ssrc;
priv->last_sr_ntpnstime = ntpnstime;
+ priv->last_known_ext_rtptime = ext_rtptime;
+ priv->last_known_ntpnstime = ntpnstime;
+
if (priv->last_ntpnstime != GST_CLOCK_TIME_NONE
&& ntpnstime - priv->last_ntpnstime < priv->sync_interval * GST_MSECOND) {
gst_buffer_replace (&priv->last_sr, NULL);