mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
rtpbin: add option for increasing ts_offset gradually
Instant large changes to ts_offset may cause timestamps to move backwards and also cause visible effects in media playback. The new option max-ts-offset-adjustment lets the application control the rate to apply changes to ts_offset. https://bugzilla.gnome.org/show_bug.cgi?id=784002
This commit is contained in:
parent
a08d7cdef5
commit
23f7739ba4
6 changed files with 156 additions and 6 deletions
|
@ -309,6 +309,7 @@ enum
|
||||||
#define DEFAULT_MAX_MISORDER_TIME 2000
|
#define DEFAULT_MAX_MISORDER_TIME 2000
|
||||||
#define DEFAULT_RFC7273_SYNC FALSE
|
#define DEFAULT_RFC7273_SYNC FALSE
|
||||||
#define DEFAULT_MAX_STREAMS G_MAXUINT
|
#define DEFAULT_MAX_STREAMS G_MAXUINT
|
||||||
|
#define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT 0
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -333,7 +334,8 @@ enum
|
||||||
PROP_MAX_DROPOUT_TIME,
|
PROP_MAX_DROPOUT_TIME,
|
||||||
PROP_MAX_MISORDER_TIME,
|
PROP_MAX_MISORDER_TIME,
|
||||||
PROP_RFC7273_SYNC,
|
PROP_RFC7273_SYNC,
|
||||||
PROP_MAX_STREAMS
|
PROP_MAX_STREAMS,
|
||||||
|
PROP_MAX_TS_OFFSET_ADJUSTMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
|
#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
|
||||||
|
@ -1759,6 +1761,8 @@ create_stream (GstRtpBinSession * session, guint32 ssrc)
|
||||||
g_object_set (buffer, "max-dropout-time", rtpbin->max_dropout_time,
|
g_object_set (buffer, "max-dropout-time", rtpbin->max_dropout_time,
|
||||||
"max-misorder-time", rtpbin->max_misorder_time, NULL);
|
"max-misorder-time", rtpbin->max_misorder_time, NULL);
|
||||||
g_object_set (buffer, "rfc7273-sync", rtpbin->rfc7273_sync, NULL);
|
g_object_set (buffer, "rfc7273-sync", rtpbin->rfc7273_sync, NULL);
|
||||||
|
g_object_set (buffer, "max-ts-offset-adjustment",
|
||||||
|
rtpbin->max_ts_offset_adjustment, NULL);
|
||||||
|
|
||||||
g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0,
|
g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0,
|
||||||
buffer, session->id, ssrc);
|
buffer, session->id, ssrc);
|
||||||
|
@ -2493,6 +2497,22 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
||||||
0, G_MAXUINT, DEFAULT_MAX_STREAMS,
|
0, G_MAXUINT, DEFAULT_MAX_STREAMS,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstRtpBin:max-ts-offset-adjustment:
|
||||||
|
*
|
||||||
|
* Syncing time stamps to NTP time adds a time offset. This parameter
|
||||||
|
* specifies the maximum number of nanoseconds per frame that this time offset
|
||||||
|
* may be adjusted with. This is used to avoid sudden large changes to time
|
||||||
|
* stamps.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
||||||
|
g_param_spec_uint64 ("max-ts-offset-adjustment",
|
||||||
|
"Max Timestamp Offset Adjustment",
|
||||||
|
"The maximum number of nanoseconds per frame that time stamp offsets "
|
||||||
|
"may be adjusted (0 = no limit).", 0, G_MAXUINT64,
|
||||||
|
DEFAULT_MAX_TS_OFFSET_ADJUSTMENT, G_PARAM_READWRITE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
|
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
|
||||||
gstelement_class->request_new_pad =
|
gstelement_class->request_new_pad =
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
|
GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
|
||||||
|
@ -2564,6 +2584,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
|
||||||
rtpbin->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
|
rtpbin->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
|
||||||
rtpbin->rfc7273_sync = DEFAULT_RFC7273_SYNC;
|
rtpbin->rfc7273_sync = DEFAULT_RFC7273_SYNC;
|
||||||
rtpbin->max_streams = DEFAULT_MAX_STREAMS;
|
rtpbin->max_streams = DEFAULT_MAX_STREAMS;
|
||||||
|
rtpbin->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
|
||||||
|
|
||||||
/* 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 ());
|
||||||
|
@ -2788,6 +2809,11 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_MAX_STREAMS:
|
case PROP_MAX_STREAMS:
|
||||||
rtpbin->max_streams = g_value_get_uint (value);
|
rtpbin->max_streams = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
rtpbin->max_ts_offset_adjustment = g_value_get_uint64 (value);
|
||||||
|
gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
|
||||||
|
"max-ts-offset-adjustment", value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -2876,6 +2902,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_MAX_STREAMS:
|
case PROP_MAX_STREAMS:
|
||||||
g_value_set_uint (value, rtpbin->max_streams);
|
g_value_set_uint (value, rtpbin->max_streams);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
g_value_set_uint64 (value, rtpbin->max_ts_offset_adjustment);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct _GstRtpBin {
|
||||||
guint32 max_misorder_time;
|
guint32 max_misorder_time;
|
||||||
gboolean rfc7273_sync;
|
gboolean rfc7273_sync;
|
||||||
guint max_streams;
|
guint max_streams;
|
||||||
|
guint64 max_ts_offset_adjustment;
|
||||||
|
|
||||||
/* a list of session */
|
/* a list of session */
|
||||||
GSList *sessions;
|
GSList *sessions;
|
||||||
|
|
|
@ -131,6 +131,7 @@ enum
|
||||||
#define DEFAULT_LATENCY_MS 200
|
#define DEFAULT_LATENCY_MS 200
|
||||||
#define DEFAULT_DROP_ON_LATENCY FALSE
|
#define DEFAULT_DROP_ON_LATENCY FALSE
|
||||||
#define DEFAULT_TS_OFFSET 0
|
#define DEFAULT_TS_OFFSET 0
|
||||||
|
#define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT 0
|
||||||
#define DEFAULT_DO_LOST FALSE
|
#define DEFAULT_DO_LOST FALSE
|
||||||
#define DEFAULT_MODE RTP_JITTER_BUFFER_MODE_SLAVE
|
#define DEFAULT_MODE RTP_JITTER_BUFFER_MODE_SLAVE
|
||||||
#define DEFAULT_PERCENT 0
|
#define DEFAULT_PERCENT 0
|
||||||
|
@ -160,6 +161,7 @@ enum
|
||||||
PROP_LATENCY,
|
PROP_LATENCY,
|
||||||
PROP_DROP_ON_LATENCY,
|
PROP_DROP_ON_LATENCY,
|
||||||
PROP_TS_OFFSET,
|
PROP_TS_OFFSET,
|
||||||
|
PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
||||||
PROP_DO_LOST,
|
PROP_DO_LOST,
|
||||||
PROP_MODE,
|
PROP_MODE,
|
||||||
PROP_PERCENT,
|
PROP_PERCENT,
|
||||||
|
@ -281,6 +283,7 @@ struct _GstRtpJitterBufferPrivate
|
||||||
guint64 latency_ns;
|
guint64 latency_ns;
|
||||||
gboolean drop_on_latency;
|
gboolean drop_on_latency;
|
||||||
gint64 ts_offset;
|
gint64 ts_offset;
|
||||||
|
guint64 max_ts_offset_adjustment;
|
||||||
gboolean do_lost;
|
gboolean do_lost;
|
||||||
gboolean do_retransmission;
|
gboolean do_retransmission;
|
||||||
gboolean rtx_next_seqnum;
|
gboolean rtx_next_seqnum;
|
||||||
|
@ -337,7 +340,7 @@ struct _GstRtpJitterBufferPrivate
|
||||||
gint last_pt;
|
gint last_pt;
|
||||||
gint32 clock_rate;
|
gint32 clock_rate;
|
||||||
gint64 clock_base;
|
gint64 clock_base;
|
||||||
gint64 prev_ts_offset;
|
gint64 ts_offset_remainder;
|
||||||
|
|
||||||
/* when we are shutting down */
|
/* when we are shutting down */
|
||||||
GstFlowReturn srcresult;
|
GstFlowReturn srcresult;
|
||||||
|
@ -368,6 +371,7 @@ struct _GstRtpJitterBufferPrivate
|
||||||
|
|
||||||
/* for the jitter */
|
/* for the jitter */
|
||||||
GstClockTime last_dts;
|
GstClockTime last_dts;
|
||||||
|
GstClockTime last_pts;
|
||||||
guint64 last_rtptime;
|
guint64 last_rtptime;
|
||||||
GstClockTime avg_jitter;
|
GstClockTime avg_jitter;
|
||||||
};
|
};
|
||||||
|
@ -549,6 +553,20 @@ gst_rtp_jitter_buffer_class_init (GstRtpJitterBufferClass * klass)
|
||||||
G_MAXINT64, DEFAULT_TS_OFFSET,
|
G_MAXINT64, DEFAULT_TS_OFFSET,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstRtpJitterBuffer:max-ts-offset-adjustment:
|
||||||
|
*
|
||||||
|
* The maximum number of nanoseconds per frame that time offset may be
|
||||||
|
* adjusted with. This is used to avoid sudden large changes to time stamps.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
||||||
|
g_param_spec_uint64 ("max-ts-offset-adjustment",
|
||||||
|
"Max Timestamp Offset Adjustment",
|
||||||
|
"The maximum number of nanoseconds per frame that time stamp "
|
||||||
|
"offsets may be adjusted (0 = no limit).", 0, G_MAXUINT64,
|
||||||
|
DEFAULT_MAX_TS_OFFSET_ADJUSTMENT, G_PARAM_READWRITE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRtpJitterBuffer:do-lost:
|
* GstRtpJitterBuffer:do-lost:
|
||||||
*
|
*
|
||||||
|
@ -980,6 +998,8 @@ gst_rtp_jitter_buffer_init (GstRtpJitterBuffer * jitterbuffer)
|
||||||
priv->latency_ms = DEFAULT_LATENCY_MS;
|
priv->latency_ms = DEFAULT_LATENCY_MS;
|
||||||
priv->latency_ns = priv->latency_ms * GST_MSECOND;
|
priv->latency_ns = priv->latency_ms * GST_MSECOND;
|
||||||
priv->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
|
priv->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
|
||||||
|
priv->ts_offset = DEFAULT_TS_OFFSET;
|
||||||
|
priv->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
|
||||||
priv->do_lost = DEFAULT_DO_LOST;
|
priv->do_lost = DEFAULT_DO_LOST;
|
||||||
priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
|
priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
|
||||||
priv->rtx_next_seqnum = DEFAULT_RTX_NEXT_SEQNUM;
|
priv->rtx_next_seqnum = DEFAULT_RTX_NEXT_SEQNUM;
|
||||||
|
@ -997,7 +1017,9 @@ gst_rtp_jitter_buffer_init (GstRtpJitterBuffer * jitterbuffer)
|
||||||
priv->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
|
priv->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
|
||||||
priv->faststart_min_packets = DEFAULT_FASTSTART_MIN_PACKETS;
|
priv->faststart_min_packets = DEFAULT_FASTSTART_MIN_PACKETS;
|
||||||
|
|
||||||
|
priv->ts_offset_remainder = 0;
|
||||||
priv->last_dts = -1;
|
priv->last_dts = -1;
|
||||||
|
priv->last_pts = -1;
|
||||||
priv->last_rtptime = -1;
|
priv->last_rtptime = -1;
|
||||||
priv->avg_jitter = 0;
|
priv->avg_jitter = 0;
|
||||||
priv->timers = g_array_new (FALSE, TRUE, sizeof (TimerData));
|
priv->timers = g_array_new (FALSE, TRUE, sizeof (TimerData));
|
||||||
|
@ -1571,7 +1593,7 @@ gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer)
|
||||||
priv->srcresult = GST_FLOW_OK;
|
priv->srcresult = GST_FLOW_OK;
|
||||||
gst_segment_init (&priv->segment, GST_FORMAT_TIME);
|
gst_segment_init (&priv->segment, GST_FORMAT_TIME);
|
||||||
priv->last_popped_seqnum = -1;
|
priv->last_popped_seqnum = -1;
|
||||||
priv->last_out_time = -1;
|
priv->last_out_time = GST_CLOCK_TIME_NONE;
|
||||||
priv->next_seqnum = -1;
|
priv->next_seqnum = -1;
|
||||||
priv->seqnum_base = -1;
|
priv->seqnum_base = -1;
|
||||||
priv->ips_rtptime = -1;
|
priv->ips_rtptime = -1;
|
||||||
|
@ -1990,6 +2012,32 @@ check_buffering_percent (GstRtpJitterBuffer * jitterbuffer, gint percent)
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_offset (GstRtpJitterBuffer * jitterbuffer)
|
||||||
|
{
|
||||||
|
GstRtpJitterBufferPrivate *priv;
|
||||||
|
|
||||||
|
priv = jitterbuffer->priv;
|
||||||
|
|
||||||
|
if (priv->ts_offset_remainder != 0) {
|
||||||
|
GST_DEBUG ("adjustment %" G_GUINT64_FORMAT " remain %" G_GINT64_FORMAT
|
||||||
|
" off %" G_GINT64_FORMAT, priv->max_ts_offset_adjustment,
|
||||||
|
priv->ts_offset_remainder, priv->ts_offset);
|
||||||
|
if (ABS (priv->ts_offset_remainder) > priv->max_ts_offset_adjustment) {
|
||||||
|
if (priv->ts_offset_remainder > 0) {
|
||||||
|
priv->ts_offset += priv->max_ts_offset_adjustment;
|
||||||
|
priv->ts_offset_remainder -= priv->max_ts_offset_adjustment;
|
||||||
|
} else {
|
||||||
|
priv->ts_offset -= priv->max_ts_offset_adjustment;
|
||||||
|
priv->ts_offset_remainder += priv->max_ts_offset_adjustment;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
priv->ts_offset += priv->ts_offset_remainder;
|
||||||
|
priv->ts_offset_remainder = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstClockTime
|
static GstClockTime
|
||||||
apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
|
apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp)
|
||||||
{
|
{
|
||||||
|
@ -3388,6 +3436,11 @@ pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint seqnum)
|
||||||
gst_segment_position_from_running_time (&priv->segment,
|
gst_segment_position_from_running_time (&priv->segment,
|
||||||
GST_FORMAT_TIME, item->pts);
|
GST_FORMAT_TIME, item->pts);
|
||||||
|
|
||||||
|
/* if this is a new frame, check if ts_offset needs to be updated */
|
||||||
|
if (pts != priv->last_pts) {
|
||||||
|
update_offset (jitterbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
/* apply timestamp with offset to buffer now */
|
/* apply timestamp with offset to buffer now */
|
||||||
GST_BUFFER_DTS (outbuf) = apply_offset (jitterbuffer, dts);
|
GST_BUFFER_DTS (outbuf) = apply_offset (jitterbuffer, dts);
|
||||||
GST_BUFFER_PTS (outbuf) = apply_offset (jitterbuffer, pts);
|
GST_BUFFER_PTS (outbuf) = apply_offset (jitterbuffer, pts);
|
||||||
|
@ -3395,6 +3448,20 @@ pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint seqnum)
|
||||||
/* update the elapsed time when we need to check against the npt stop time. */
|
/* update the elapsed time when we need to check against the npt stop time. */
|
||||||
update_estimated_eos (jitterbuffer, item);
|
update_estimated_eos (jitterbuffer, item);
|
||||||
|
|
||||||
|
/* verify that an offset has not caused time stamps to go backwards, if so
|
||||||
|
* handle by reusing the previous timestamp */
|
||||||
|
if (priv->last_out_time != GST_CLOCK_TIME_NONE &&
|
||||||
|
GST_BUFFER_PTS (outbuf) < priv->last_out_time) {
|
||||||
|
GST_DEBUG_OBJECT (jitterbuffer, "buffer PTS %" GST_TIME_FORMAT
|
||||||
|
" older than preceding PTS %" GST_TIME_FORMAT
|
||||||
|
" adjusting to %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)),
|
||||||
|
GST_TIME_ARGS (priv->last_out_time),
|
||||||
|
GST_TIME_ARGS (priv->last_out_time));
|
||||||
|
GST_BUFFER_PTS (outbuf) = priv->last_out_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->last_pts = pts;
|
||||||
priv->last_out_time = GST_BUFFER_PTS (outbuf);
|
priv->last_out_time = GST_BUFFER_PTS (outbuf);
|
||||||
break;
|
break;
|
||||||
case ITEM_TYPE_LOST:
|
case ITEM_TYPE_LOST:
|
||||||
|
@ -4480,10 +4547,26 @@ gst_rtp_jitter_buffer_set_property (GObject * object,
|
||||||
break;
|
break;
|
||||||
case PROP_TS_OFFSET:
|
case PROP_TS_OFFSET:
|
||||||
JBUF_LOCK (priv);
|
JBUF_LOCK (priv);
|
||||||
priv->ts_offset = g_value_get_int64 (value);
|
if (priv->max_ts_offset_adjustment != 0) {
|
||||||
|
gint64 new_offset = g_value_get_int64 (value);
|
||||||
|
|
||||||
|
if (new_offset > priv->ts_offset) {
|
||||||
|
priv->ts_offset_remainder = new_offset - priv->ts_offset;
|
||||||
|
} else {
|
||||||
|
priv->ts_offset_remainder = -(priv->ts_offset - new_offset);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
priv->ts_offset = g_value_get_int64 (value);
|
||||||
|
priv->ts_offset_remainder = 0;
|
||||||
|
}
|
||||||
priv->ts_discont = TRUE;
|
priv->ts_discont = TRUE;
|
||||||
JBUF_UNLOCK (priv);
|
JBUF_UNLOCK (priv);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
JBUF_LOCK (priv);
|
||||||
|
priv->max_ts_offset_adjustment = g_value_get_uint64 (value);
|
||||||
|
JBUF_UNLOCK (priv);
|
||||||
|
break;
|
||||||
case PROP_DO_LOST:
|
case PROP_DO_LOST:
|
||||||
JBUF_LOCK (priv);
|
JBUF_LOCK (priv);
|
||||||
priv->do_lost = g_value_get_boolean (value);
|
priv->do_lost = g_value_get_boolean (value);
|
||||||
|
@ -4607,6 +4690,11 @@ gst_rtp_jitter_buffer_get_property (GObject * object,
|
||||||
g_value_set_int64 (value, priv->ts_offset);
|
g_value_set_int64 (value, priv->ts_offset);
|
||||||
JBUF_UNLOCK (priv);
|
JBUF_UNLOCK (priv);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
JBUF_LOCK (priv);
|
||||||
|
g_value_set_uint64 (value, priv->max_ts_offset_adjustment);
|
||||||
|
JBUF_UNLOCK (priv);
|
||||||
|
break;
|
||||||
case PROP_DO_LOST:
|
case PROP_DO_LOST:
|
||||||
JBUF_LOCK (priv);
|
JBUF_LOCK (priv);
|
||||||
g_value_set_boolean (value, priv->do_lost);
|
g_value_set_boolean (value, priv->do_lost);
|
||||||
|
|
|
@ -1280,7 +1280,8 @@ rtp_source_send_rtp (RTPSource * src, RTPPacketInfo * pinfo)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
if (src->pt_set && src->pt != pinfo->pt) {
|
if (src->pt_set && src->pt != pinfo->pt) {
|
||||||
GST_WARNING ("Changing pt from %u to %u for SSRC %u", src->pt, pinfo->pt, src->ssrc);
|
GST_WARNING ("Changing pt from %u to %u for SSRC %u", src->pt, pinfo->pt,
|
||||||
|
src->ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
src->pt = pinfo->pt;
|
src->pt = pinfo->pt;
|
||||||
|
|
|
@ -228,6 +228,7 @@ gst_rtsp_src_ntp_time_source_get_type (void)
|
||||||
#define DEFAULT_USER_AGENT "GStreamer/" PACKAGE_VERSION
|
#define DEFAULT_USER_AGENT "GStreamer/" PACKAGE_VERSION
|
||||||
#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
|
#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
|
||||||
#define DEFAULT_RFC7273_SYNC FALSE
|
#define DEFAULT_RFC7273_SYNC FALSE
|
||||||
|
#define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT 0
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -267,7 +268,8 @@ enum
|
||||||
PROP_NTP_TIME_SOURCE,
|
PROP_NTP_TIME_SOURCE,
|
||||||
PROP_USER_AGENT,
|
PROP_USER_AGENT,
|
||||||
PROP_MAX_RTCP_RTP_TIME_DIFF,
|
PROP_MAX_RTCP_RTP_TIME_DIFF,
|
||||||
PROP_RFC7273_SYNC
|
PROP_RFC7273_SYNC,
|
||||||
|
PROP_MAX_TS_OFFSET_ADJUSTMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
|
#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
|
||||||
|
@ -748,6 +750,22 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
|
||||||
"(requires clock and offset to be provided)", DEFAULT_RFC7273_SYNC,
|
"(requires clock and offset to be provided)", DEFAULT_RFC7273_SYNC,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstRTSPSrc:max-ts-offset-adjustment:
|
||||||
|
*
|
||||||
|
* Syncing time stamps to NTP time adds a time offset. This parameter
|
||||||
|
* specifies the maximum number of nanoseconds per frame that this time offset
|
||||||
|
* may be adjusted with. This is used to avoid sudden large changes to time
|
||||||
|
* stamps.
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET_ADJUSTMENT,
|
||||||
|
g_param_spec_uint64 ("max-ts-offset-adjustment",
|
||||||
|
"Max Timestamp Offset Adjustment",
|
||||||
|
"The maximum number of nanoseconds per frame that time stamp offsets "
|
||||||
|
"may be adjusted (0 = no limit).", 0, G_MAXUINT64,
|
||||||
|
DEFAULT_MAX_TS_OFFSET_ADJUSTMENT, G_PARAM_READWRITE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstRTSPSrc::handle-request:
|
* GstRTSPSrc::handle-request:
|
||||||
* @rtspsrc: a #GstRTSPSrc
|
* @rtspsrc: a #GstRTSPSrc
|
||||||
|
@ -896,6 +914,7 @@ gst_rtspsrc_init (GstRTSPSrc * src)
|
||||||
src->user_agent = g_strdup (DEFAULT_USER_AGENT);
|
src->user_agent = g_strdup (DEFAULT_USER_AGENT);
|
||||||
src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
|
src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
|
||||||
src->rfc7273_sync = DEFAULT_RFC7273_SYNC;
|
src->rfc7273_sync = DEFAULT_RFC7273_SYNC;
|
||||||
|
src->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
|
||||||
|
|
||||||
/* get a list of all extensions */
|
/* get a list of all extensions */
|
||||||
src->extensions = gst_rtsp_ext_list_get ();
|
src->extensions = gst_rtsp_ext_list_get ();
|
||||||
|
@ -1186,6 +1205,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
case PROP_RFC7273_SYNC:
|
case PROP_RFC7273_SYNC:
|
||||||
rtspsrc->rfc7273_sync = g_value_get_boolean (value);
|
rtspsrc->rfc7273_sync = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
rtspsrc->max_ts_offset_adjustment = g_value_get_uint64 (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1335,6 +1357,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_RFC7273_SYNC:
|
case PROP_RFC7273_SYNC:
|
||||||
g_value_set_boolean (value, rtspsrc->rfc7273_sync);
|
g_value_set_boolean (value, rtspsrc->rfc7273_sync);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_TS_OFFSET_ADJUSTMENT:
|
||||||
|
g_value_set_uint64 (value, rtspsrc->max_ts_offset_adjustment);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -3166,6 +3191,11 @@ gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream,
|
||||||
src->max_rtcp_rtp_time_diff, NULL);
|
src->max_rtcp_rtp_time_diff, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_object_class_find_property (klass, "max-ts-offset-adjustment")) {
|
||||||
|
g_object_set (src->manager, "max-ts-offset-adjustment",
|
||||||
|
src->max_ts_offset_adjustment, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* buffer mode pauses are handled by adding offsets to buffer times,
|
/* buffer mode pauses are handled by adding offsets to buffer times,
|
||||||
* but some depayloaders may have a hard time syncing output times
|
* but some depayloaders may have a hard time syncing output times
|
||||||
* with such input times, e.g. container ones, most notably ASF */
|
* with such input times, e.g. container ones, most notably ASF */
|
||||||
|
|
|
@ -250,6 +250,7 @@ struct _GstRTSPSrc {
|
||||||
gchar *user_agent;
|
gchar *user_agent;
|
||||||
GstClockTime max_rtcp_rtp_time_diff;
|
GstClockTime max_rtcp_rtp_time_diff;
|
||||||
gboolean rfc7273_sync;
|
gboolean rfc7273_sync;
|
||||||
|
guint64 max_ts_offset_adjustment;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
GstRTSPState state;
|
GstRTSPState state;
|
||||||
|
|
Loading…
Reference in a new issue