mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
rtpbin: added option for setting min_ts_offset in ntp-sync mode
Constantly updating the ts_offset results in audiable glitches when streaming audio using ntp-sync=true. By requiring a minimum offset before updating ts_offset this can be mitigated. Added a parameter which can be used to set min_ts_offset in ntp-sync mode. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1409>
This commit is contained in:
parent
8773ba1104
commit
d5e257afd1
3 changed files with 60 additions and 4 deletions
|
@ -16807,6 +16807,20 @@
|
||||||
"type": "guint64",
|
"type": "guint64",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"min-ts-offset": {
|
||||||
|
"blurb": "The minimum absolute value of the time offset in (nanoseconds). Used to set an lower limit for when a time offset is deemed large enough to be useful for sync corrections.Note, if the ntp-sync parameter is set the default value is changed to 0 (no limit)",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "4000000",
|
||||||
|
"max": "18446744073709551615",
|
||||||
|
"min": "0",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "guint64",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"ntp-sync": {
|
"ntp-sync": {
|
||||||
"blurb": "Synchronize received streams to the NTP clock",
|
"blurb": "Synchronize received streams to the NTP clock",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -260,7 +260,7 @@ G_STMT_START { \
|
||||||
|
|
||||||
/* Minimum time offset to apply. This compensates for rounding errors in NTP to
|
/* Minimum time offset to apply. This compensates for rounding errors in NTP to
|
||||||
* RTP timestamp conversions */
|
* RTP timestamp conversions */
|
||||||
#define MIN_TS_OFFSET (4 * GST_MSECOND)
|
#define MIN_TS_OFFSET_ROUND_OFF_COMP (4 * GST_MSECOND)
|
||||||
|
|
||||||
struct _GstRtpBinPrivate
|
struct _GstRtpBinPrivate
|
||||||
{
|
{
|
||||||
|
@ -353,6 +353,7 @@ enum
|
||||||
#define DEFAULT_MAX_STREAMS G_MAXUINT
|
#define DEFAULT_MAX_STREAMS G_MAXUINT
|
||||||
#define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT G_GUINT64_CONSTANT(0)
|
#define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT G_GUINT64_CONSTANT(0)
|
||||||
#define DEFAULT_MAX_TS_OFFSET G_GINT64_CONSTANT(3000000000)
|
#define DEFAULT_MAX_TS_OFFSET G_GINT64_CONSTANT(3000000000)
|
||||||
|
#define DEFAULT_MIN_TS_OFFSET MIN_TS_OFFSET_ROUND_OFF_COMP
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -380,6 +381,7 @@ enum
|
||||||
PROP_MAX_STREAMS,
|
PROP_MAX_STREAMS,
|
||||||
PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
||||||
PROP_MAX_TS_OFFSET,
|
PROP_MAX_TS_OFFSET,
|
||||||
|
PROP_MIN_TS_OFFSET,
|
||||||
PROP_FEC_DECODERS,
|
PROP_FEC_DECODERS,
|
||||||
PROP_FEC_ENCODERS,
|
PROP_FEC_ENCODERS,
|
||||||
};
|
};
|
||||||
|
@ -1327,7 +1329,7 @@ get_current_times (GstRtpBin * bin, GstClockTime * running_time,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream,
|
stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream,
|
||||||
gint64 ts_offset, gint64 max_ts_offset, gint64 min_ts_offset,
|
gint64 ts_offset, gint64 max_ts_offset, guint64 min_ts_offset,
|
||||||
gboolean allow_positive_ts_offset)
|
gboolean allow_positive_ts_offset)
|
||||||
{
|
{
|
||||||
gint64 prev_ts_offset;
|
gint64 prev_ts_offset;
|
||||||
|
@ -1513,7 +1515,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
stream->rt_delta = rtdiff - ntpdiff;
|
stream->rt_delta = rtdiff - ntpdiff;
|
||||||
|
|
||||||
stream_set_ts_offset (bin, stream, stream->rt_delta, bin->max_ts_offset,
|
stream_set_ts_offset (bin, stream, stream->rt_delta, bin->max_ts_offset,
|
||||||
0, FALSE);
|
bin->min_ts_offset, FALSE);
|
||||||
} else {
|
} else {
|
||||||
gint64 min, rtp_min, clock_base = stream->clock_base;
|
gint64 min, rtp_min, clock_base = stream->clock_base;
|
||||||
gboolean all_sync, use_rtp;
|
gboolean all_sync, use_rtp;
|
||||||
|
@ -1666,7 +1668,7 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
|
||||||
ts_offset = ostream->rt_delta - min;
|
ts_offset = ostream->rt_delta - min;
|
||||||
|
|
||||||
stream_set_ts_offset (bin, ostream, ts_offset, bin->max_ts_offset,
|
stream_set_ts_offset (bin, ostream, ts_offset, bin->max_ts_offset,
|
||||||
MIN_TS_OFFSET, TRUE);
|
bin->min_ts_offset, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst_rtp_bin_send_sync_event (stream);
|
gst_rtp_bin_send_sync_event (stream);
|
||||||
|
@ -2761,6 +2763,28 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
||||||
"changed to 0 (no limit)", 0, G_MAXINT64, DEFAULT_MAX_TS_OFFSET,
|
"changed to 0 (no limit)", 0, G_MAXINT64, DEFAULT_MAX_TS_OFFSET,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstRtpBin:min-ts-offset:
|
||||||
|
*
|
||||||
|
* Used to set an lower limit for when a time offset is deemed large enough
|
||||||
|
* to be useful for sync corrections.
|
||||||
|
*
|
||||||
|
* When streaming for instance audio, even very small ts_offsets cause
|
||||||
|
* audible glitches. This property is used for controlling how sensitive the
|
||||||
|
* adjustments should be to small deviations in ts_offset, occurring for
|
||||||
|
* instance due to jittery network conditions or system load.
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MIN_TS_OFFSET,
|
||||||
|
g_param_spec_uint64 ("min-ts-offset", "Min TS Offset",
|
||||||
|
"The minimum absolute value of the time offset in (nanoseconds). "
|
||||||
|
"Used to set an lower limit for when a time offset is deemed large "
|
||||||
|
"enough to be useful for sync corrections."
|
||||||
|
"Note, if the ntp-sync parameter is set the default value is "
|
||||||
|
"changed to 0 (no limit)", 0, G_MAXUINT64, DEFAULT_MIN_TS_OFFSET,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRtpBin:fec-decoders:
|
* GstRtpBin:fec-decoders:
|
||||||
*
|
*
|
||||||
|
@ -2883,6 +2907,8 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
|
||||||
rtpbin->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
|
rtpbin->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
|
||||||
rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
|
rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
|
||||||
rtpbin->max_ts_offset_is_set = FALSE;
|
rtpbin->max_ts_offset_is_set = FALSE;
|
||||||
|
rtpbin->min_ts_offset = DEFAULT_MIN_TS_OFFSET;
|
||||||
|
rtpbin->min_ts_offset_is_set = FALSE;
|
||||||
|
|
||||||
/* some default SDES entries */
|
/* some default SDES entries */
|
||||||
cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
|
cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
|
||||||
|
@ -3079,6 +3105,13 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
|
||||||
rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
|
rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!rtpbin->min_ts_offset_is_set) {
|
||||||
|
if (rtpbin->ntp_sync) {
|
||||||
|
rtpbin->min_ts_offset = 0;
|
||||||
|
} else {
|
||||||
|
rtpbin->min_ts_offset = DEFAULT_MIN_TS_OFFSET;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_RTCP_SYNC:
|
case PROP_RTCP_SYNC:
|
||||||
g_atomic_int_set (&rtpbin->rtcp_sync, g_value_get_enum (value));
|
g_atomic_int_set (&rtpbin->rtcp_sync, g_value_get_enum (value));
|
||||||
|
@ -3197,6 +3230,10 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
|
||||||
rtpbin->max_ts_offset = g_value_get_int64 (value);
|
rtpbin->max_ts_offset = g_value_get_int64 (value);
|
||||||
rtpbin->max_ts_offset_is_set = TRUE;
|
rtpbin->max_ts_offset_is_set = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case PROP_MIN_TS_OFFSET:
|
||||||
|
rtpbin->min_ts_offset = g_value_get_uint64 (value);
|
||||||
|
rtpbin->min_ts_offset_is_set = TRUE;
|
||||||
|
break;
|
||||||
case PROP_FEC_DECODERS:
|
case PROP_FEC_DECODERS:
|
||||||
gst_rtp_bin_set_fec_decoders_struct (rtpbin, g_value_get_boxed (value));
|
gst_rtp_bin_set_fec_decoders_struct (rtpbin, g_value_get_boxed (value));
|
||||||
break;
|
break;
|
||||||
|
@ -3297,6 +3334,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_MAX_TS_OFFSET:
|
case PROP_MAX_TS_OFFSET:
|
||||||
g_value_set_int64 (value, rtpbin->max_ts_offset);
|
g_value_set_int64 (value, rtpbin->max_ts_offset);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MIN_TS_OFFSET:
|
||||||
|
g_value_set_uint64 (value, rtpbin->min_ts_offset);
|
||||||
|
break;
|
||||||
case PROP_FEC_DECODERS:
|
case PROP_FEC_DECODERS:
|
||||||
g_value_take_boxed (value, gst_rtp_bin_get_fec_decoders_struct (rtpbin));
|
g_value_take_boxed (value, gst_rtp_bin_get_fec_decoders_struct (rtpbin));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -78,6 +78,8 @@ struct _GstRtpBin {
|
||||||
guint64 max_ts_offset_adjustment;
|
guint64 max_ts_offset_adjustment;
|
||||||
gint64 max_ts_offset;
|
gint64 max_ts_offset;
|
||||||
gboolean max_ts_offset_is_set;
|
gboolean max_ts_offset_is_set;
|
||||||
|
guint64 min_ts_offset;
|
||||||
|
gboolean min_ts_offset_is_set;
|
||||||
|
|
||||||
/* a list of session */
|
/* a list of session */
|
||||||
GSList *sessions;
|
GSList *sessions;
|
||||||
|
|
Loading…
Reference in a new issue