rtpbin: add use-pipeline-clock property

With this property RTCP SR NTP times can be based
on the system clock (maybe synced with ntpd) or the
current pipeline clock.

https://bugzilla.gnome.org/show_bug.cgi?id=627796
This commit is contained in:
Thijs Vermeir 2010-08-26 10:58:26 +02:00 committed by Wim Taymans
parent 3bae70ceea
commit 51020549f0
3 changed files with 53 additions and 7 deletions

View file

@ -238,6 +238,7 @@ enum
#define DEFAULT_IGNORE_PT FALSE #define DEFAULT_IGNORE_PT FALSE
#define DEFAULT_AUTOREMOVE FALSE #define DEFAULT_AUTOREMOVE FALSE
#define DEFAULT_BUFFER_MODE RTP_JITTER_BUFFER_MODE_SLAVE #define DEFAULT_BUFFER_MODE RTP_JITTER_BUFFER_MODE_SLAVE
#define DEFAULT_USE_PIPELINE_CLOCK FALSE
enum enum
{ {
@ -248,6 +249,7 @@ enum
PROP_IGNORE_PT, PROP_IGNORE_PT,
PROP_AUTOREMOVE, PROP_AUTOREMOVE,
PROP_BUFFER_MODE, PROP_BUFFER_MODE,
PROP_USE_PIPELINE_CLOCK,
PROP_LAST PROP_LAST
}; };
@ -529,7 +531,8 @@ create_session (GstRtpBin * rtpbin, gint id)
/* configure SDES items */ /* configure SDES items */
GST_OBJECT_LOCK (rtpbin); GST_OBJECT_LOCK (rtpbin);
g_object_set (session, "sdes", rtpbin->sdes, NULL); g_object_set (session, "sdes", rtpbin->sdes, "use-pipeline-clock",
rtpbin->use_pipeline_clock, NULL);
GST_OBJECT_UNLOCK (rtpbin); GST_OBJECT_UNLOCK (rtpbin);
/* provide clock_rate to the session manager when needed */ /* provide clock_rate to the session manager when needed */
@ -1530,7 +1533,6 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
"Send an event downstream when a packet is lost", DEFAULT_DO_LOST, "Send an event downstream when a packet is lost", DEFAULT_DO_LOST,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_AUTOREMOVE, g_object_class_install_property (gobject_class, PROP_AUTOREMOVE,
g_param_spec_boolean ("autoremove", "Auto Remove", g_param_spec_boolean ("autoremove", "Auto Remove",
"Automatically remove timed out sources", DEFAULT_AUTOREMOVE, "Automatically remove timed out sources", DEFAULT_AUTOREMOVE,
@ -1540,6 +1542,12 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
g_param_spec_boolean ("ignore_pt", "Ignore PT", g_param_spec_boolean ("ignore_pt", "Ignore PT",
"Do not demultiplex based on PT values", DEFAULT_IGNORE_PT, "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
"Use the pipeline clock to set the NTP time in the RTCP SR messages",
DEFAULT_AUTOREMOVE, G_PARAM_READWRITE));
/** /**
* GstRtpBin::buffer-mode: * GstRtpBin::buffer-mode:
* *
@ -1582,6 +1590,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass)
rtpbin->ignore_pt = DEFAULT_IGNORE_PT; rtpbin->ignore_pt = DEFAULT_IGNORE_PT;
rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE; rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE;
rtpbin->buffer_mode = DEFAULT_BUFFER_MODE; rtpbin->buffer_mode = DEFAULT_BUFFER_MODE;
rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
/* some default SDES entries */ /* some default SDES entries */
str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ());
@ -1695,6 +1704,19 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
case PROP_AUTOREMOVE: case PROP_AUTOREMOVE:
rtpbin->priv->autoremove = g_value_get_boolean (value); rtpbin->priv->autoremove = g_value_get_boolean (value);
break; break;
case PROP_USE_PIPELINE_CLOCK:
{
GSList *sessions;
GST_RTP_BIN_LOCK (rtpbin);
rtpbin->use_pipeline_clock = g_value_get_boolean (value);
for (sessions = rtpbin->sessions; sessions;
sessions = g_slist_next (sessions)) {
g_object_set (G_OBJECT (sessions->data), "use-pipeline-clock",
rtpbin->use_pipeline_clock, NULL);
}
GST_RTP_BIN_UNLOCK (rtpbin);
}
break;
case PROP_BUFFER_MODE: case PROP_BUFFER_MODE:
GST_RTP_BIN_LOCK (rtpbin); GST_RTP_BIN_LOCK (rtpbin);
rtpbin->buffer_mode = g_value_get_enum (value); rtpbin->buffer_mode = g_value_get_enum (value);
@ -1739,6 +1761,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
case PROP_BUFFER_MODE: case PROP_BUFFER_MODE:
g_value_set_enum (value, rtpbin->buffer_mode); g_value_set_enum (value, rtpbin->buffer_mode);
break; break;
case PROP_USE_PIPELINE_CLOCK:
g_value_set_boolean (value, rtpbin->use_pipeline_clock);
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;

View file

@ -51,6 +51,7 @@ struct _GstRtpBin {
gboolean ignore_pt; gboolean ignore_pt;
RTPJitterBufferMode buffer_mode; RTPJitterBufferMode buffer_mode;
gboolean buffering; gboolean buffering;
gboolean use_pipeline_clock;
GstClockTime buffer_start; GstClockTime buffer_start;
/* a list of session */ /* a list of session */
GSList *sessions; GSList *sessions;

View file

@ -198,6 +198,7 @@ enum
#define DEFAULT_SDES NULL #define DEFAULT_SDES NULL
#define DEFAULT_NUM_SOURCES 0 #define DEFAULT_NUM_SOURCES 0
#define DEFAULT_NUM_ACTIVE_SOURCES 0 #define DEFAULT_NUM_ACTIVE_SOURCES 0
#define DEFAULT_USE_PIPELINE_CLOCK FALSE
enum enum
{ {
@ -211,6 +212,7 @@ enum
PROP_NUM_SOURCES, PROP_NUM_SOURCES,
PROP_NUM_ACTIVE_SOURCES, PROP_NUM_ACTIVE_SOURCES,
PROP_INTERNAL_SESSION, PROP_INTERNAL_SESSION,
PROP_USE_PIPELINE_CLOCK,
PROP_LAST PROP_LAST
}; };
@ -238,6 +240,7 @@ struct _GstRtpSessionPrivate
/* NTP base time */ /* NTP base time */
guint64 ntpnsbase; guint64 ntpnsbase;
gboolean use_pipeline_clock;
}; };
/* callbacks to handle actions from the session manager */ /* callbacks to handle actions from the session manager */
@ -572,6 +575,11 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
"The internal RTPSession object", RTP_TYPE_SESSION, "The internal RTPSession object", RTP_TYPE_SESSION,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
"Use the pipeline clock to set the NTP time in the RTCP SR messages",
DEFAULT_USE_PIPELINE_CLOCK, G_PARAM_READWRITE));
gstelement_class->change_state = gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
gstelement_class->request_new_pad = gstelement_class->request_new_pad =
@ -592,6 +600,7 @@ gst_rtp_session_init (GstRtpSession * rtpsession, GstRtpSessionClass * klass)
rtpsession->priv->lock = g_mutex_new (); rtpsession->priv->lock = g_mutex_new ();
rtpsession->priv->sysclock = gst_system_clock_obtain (); rtpsession->priv->sysclock = gst_system_clock_obtain ();
rtpsession->priv->session = rtp_session_new (); rtpsession->priv->session = rtp_session_new ();
rtpsession->priv->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
/* configure callbacks */ /* configure callbacks */
rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession); rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession);
@ -682,6 +691,9 @@ gst_rtp_session_set_property (GObject * object, guint prop_id,
case PROP_SDES: case PROP_SDES:
rtp_session_set_sdes_struct (priv->session, g_value_get_boxed (value)); rtp_session_set_sdes_struct (priv->session, g_value_get_boxed (value));
break; break;
case PROP_USE_PIPELINE_CLOCK:
priv->use_pipeline_clock = g_value_get_boolean (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;
@ -731,6 +743,9 @@ gst_rtp_session_get_property (GObject * object, guint prop_id,
case PROP_INTERNAL_SESSION: case PROP_INTERNAL_SESSION:
g_value_set_object (value, priv->session); g_value_set_object (value, priv->session);
break; break;
case PROP_USE_PIPELINE_CLOCK:
g_value_set_boolean (value, priv->use_pipeline_clock);
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;
@ -744,7 +759,6 @@ get_current_times (GstRtpSession * rtpsession, GstClockTime * running_time,
guint64 ntpns; guint64 ntpns;
GstClock *clock; GstClock *clock;
GstClockTime base_time, rt; GstClockTime base_time, rt;
GTimeVal current;
GST_OBJECT_LOCK (rtpsession); GST_OBJECT_LOCK (rtpsession);
if ((clock = GST_ELEMENT_CLOCK (rtpsession))) { if ((clock = GST_ELEMENT_CLOCK (rtpsession))) {
@ -752,9 +766,15 @@ get_current_times (GstRtpSession * rtpsession, GstClockTime * running_time,
gst_object_ref (clock); gst_object_ref (clock);
GST_OBJECT_UNLOCK (rtpsession); GST_OBJECT_UNLOCK (rtpsession);
if (rtpsession->priv->use_pipeline_clock) {
ntpns = gst_clock_get_time (clock);
} else {
GTimeVal current;
/* get current NTP time */ /* get current NTP time */
g_get_current_time (&current); g_get_current_time (&current);
ntpns = GST_TIMEVAL_TO_TIME (current); ntpns = GST_TIMEVAL_TO_TIME (current);
}
/* add constant to convert from 1970 based time to 1900 based time */ /* add constant to convert from 1970 based time to 1900 based time */
ntpns += (2208988800LL * GST_SECOND); ntpns += (2208988800LL * GST_SECOND);