rtpbin: Handle ntp-sync=true before everything else

This simplifies the code as it's a much simpler case than the normal
inter-stream synchronization, and interleaving it with that only
reduces readability of the code.

Also improve some debug output in this code path.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6543>
This commit is contained in:
Sebastian Dröge 2024-04-17 13:30:42 +03:00 committed by GStreamer Marge Bot
parent 4b0e75a094
commit 4421c3de75

View File

@ -1481,6 +1481,88 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
return; return;
} }
/* In case of NTP sync we can directly calculate the offset for this stream
* here and return immediately */
if (bin->ntp_sync) {
GstClockTime rtp_running_time, diff_rtp;
GstClockTime local_running_time, local_ntpnstime;
gint64 ntpdiff, rtdiff;
GST_DEBUG_OBJECT (bin, "Doing NTP sync");
if (!GST_CLOCK_TIME_IS_VALID (extrtptime)
|| !GST_CLOCK_TIME_IS_VALID (ntpnstime)
|| extrtptime < base_rtptime) {
GST_DEBUG_OBJECT (bin, "invalidated sync data, bailing out");
return;
}
/* 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
* buffers so we will calculate what running_time corresponds to the RTP
* timestamp in the SR packet. */
diff_rtp = extrtptime - base_rtptime;
GST_DEBUG_OBJECT (bin,
"base RTP time %" G_GUINT64_FORMAT ", SR RTP time %" G_GUINT64_FORMAT
", RTP time difference %" G_GUINT64_FORMAT ", clock-rate %d",
base_rtptime, extrtptime, diff_rtp, clock_rate);
/* calculate local RTP time in GStreamer timestamp units, we essentially
* perform the same conversion that a jitterbuffer would use to convert an
* rtp timestamp into a corresponding gstreamer timestamp. Note that the
* base_time also contains the drift between sender and receiver. */
rtp_running_time =
gst_util_uint64_scale_int (diff_rtp, GST_SECOND, clock_rate);
rtp_running_time += base_time;
GST_DEBUG_OBJECT (bin,
"RTP running time %" GST_TIME_FORMAT ", SR NTP time %" GST_TIME_FORMAT,
GST_TIME_ARGS (rtp_running_time), GST_TIME_ARGS (ntpnstime));
/* For NTP sync we need to first get a snapshot of running_time and NTP
* time. We know at what running_time we play a certain RTP time, we also
* calculated when we would play the RTP time in the SR packet. Now we need
* to know how the running_time and the NTP time relate to each other. */
get_current_times (bin, &local_running_time, &local_ntpnstime);
/* see how far away the NTP time is. This is the difference between the
* current NTP time and the NTP time in the last SR packet. */
ntpdiff = local_ntpnstime - ntpnstime;
/* see how far away the running_time is. This is the difference between the
* current running_time and the running_time of the RTP timestamp in the
* last SR packet. */
rtdiff = local_running_time - rtp_running_time;
GST_DEBUG_OBJECT (bin,
"local NTP time %" G_GUINT64_FORMAT ", SR NTP time %" G_GUINT64_FORMAT,
local_ntpnstime, ntpnstime);
GST_DEBUG_OBJECT (bin,
"local running time %" G_GUINT64_FORMAT ", SR RTP running time %"
G_GUINT64_FORMAT, local_running_time, rtp_running_time);
GST_DEBUG_OBJECT (bin,
"NTP diff %" G_GINT64_FORMAT ", RT diff %" G_GINT64_FORMAT, ntpdiff,
rtdiff);
/* combine to get the final diff to apply to the running_time */
stream->rt_delta = rtdiff - ntpdiff;
GST_DEBUG_OBJECT (bin,
"Calculated ts-offset %" GST_STIME_FORMAT " for SSRC %08x",
GST_STIME_ARGS (stream->rt_delta), stream->ssrc);
stream_set_ts_offset (bin, stream, stream->rt_delta, bin->max_ts_offset,
bin->min_ts_offset, FALSE);
gst_rtp_bin_send_sync_event (stream);
return;
}
/* For all other cases (not RFC7273 and not NTP sync) we have to look how
* all streams of a client relate to each other */
GstRtpBinClient *client; GstRtpBinClient *client;
gboolean created; gboolean created;
GSList *walk; GSList *walk;
@ -1548,43 +1630,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
"SR RTP running time %" G_GUINT64_FORMAT ", SR NTP %" G_GUINT64_FORMAT, "SR RTP running time %" G_GUINT64_FORMAT ", SR NTP %" G_GUINT64_FORMAT,
running_time, ntpnstime); running_time, ntpnstime);
/* 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 or we're doing NTP sync. */
if (bin->ntp_sync) {
gint64 ntpdiff, rtdiff;
guint64 local_ntpnstime;
GstClockTime local_running_time;
/* For NTP sync we need to first get a snapshot of running_time and NTP
* time. We know at what running_time we play a certain RTP time, we also
* calculated when we would play the RTP time in the SR packet. Now we need
* to know how the running_time and the NTP time relate to each other. */
get_current_times (bin, &local_running_time, &local_ntpnstime);
/* see how far away the NTP time is. This is the difference between the
* current NTP time and the NTP time in the last SR packet. */
ntpdiff = local_ntpnstime - ntpnstime;
/* see how far away the running_time is. This is the difference between the
* current running_time and the running_time of the RTP timestamp in the
* last SR packet. */
rtdiff = local_running_time - running_time;
GST_DEBUG_OBJECT (bin,
"local NTP time %" G_GUINT64_FORMAT ", SR NTP time %" G_GUINT64_FORMAT,
local_ntpnstime, ntpnstime);
GST_DEBUG_OBJECT (bin,
"local running time %" G_GUINT64_FORMAT ", SR RTP running time %"
G_GUINT64_FORMAT, local_running_time, running_time);
GST_DEBUG_OBJECT (bin,
"NTP diff %" G_GINT64_FORMAT ", RT diff %" G_GINT64_FORMAT, ntpdiff,
rtdiff);
/* combine to get the final diff to apply to the running_time */
stream->rt_delta = rtdiff - ntpdiff;
stream_set_ts_offset (bin, stream, stream->rt_delta, bin->max_ts_offset,
bin->min_ts_offset, FALSE);
} else {
gint64 min, rtp_min, clock_base; gint64 min, rtp_min, clock_base;
gboolean all_sync, use_rtp; gboolean all_sync, use_rtp;
gboolean rtcp_sync = g_atomic_int_get (&bin->rtcp_sync); gboolean rtcp_sync = g_atomic_int_get (&bin->rtcp_sync);
@ -1736,7 +1782,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
stream_set_ts_offset (bin, ostream, ts_offset, bin->max_ts_offset, stream_set_ts_offset (bin, ostream, ts_offset, bin->max_ts_offset,
bin->min_ts_offset, TRUE); bin->min_ts_offset, TRUE);
} }
}
gst_rtp_bin_send_sync_event (stream); gst_rtp_bin_send_sync_event (stream);
return; return;