diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index dc48352906..03268788ab 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -246,6 +246,7 @@ enum #define DEFAULT_DO_LOST FALSE #define DEFAULT_IGNORE_PT FALSE #define DEFAULT_AUTOREMOVE FALSE +#define DEFAULT_BUFFER_MODE RTP_JITTER_BUFFER_MODE_SLAVE enum { @@ -255,6 +256,7 @@ enum PROP_DO_LOST, PROP_IGNORE_PT, PROP_AUTOREMOVE, + PROP_BUFFER_MODE, PROP_LAST }; @@ -295,6 +297,7 @@ struct _GstRtpBinStream gulong buffer_handlesync_sig; gulong buffer_ptreq_sig; gulong buffer_ntpstop_sig; + gboolean buffering; /* the PT demuxer of the SSRC */ GstElement *demux; @@ -1175,6 +1178,7 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) /* configure latency and packet lost */ g_object_set (buffer, "latency", rtpbin->latency, NULL); g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL); + g_object_set (buffer, "mode", rtpbin->buffer_mode, NULL); if (!rtpbin->ignore_pt) gst_bin_add (GST_BIN_CAST (rtpbin), demux); @@ -1232,7 +1236,7 @@ free_stream (GstRtpBinStream * stream) gst_element_set_state (stream->demux, GST_STATE_NULL); gst_element_set_state (stream->buffer, GST_STATE_NULL); - /* now remove this signal, we need this while going to NULL because it to + /* now remove this signal, we need this while going to NULL because it to * do some cleanups */ if (stream->demux) g_signal_handler_disconnect (stream->demux, stream->demux_padremoved_sig); @@ -1522,16 +1526,28 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) "Send an event downstream when a packet is lost", DEFAULT_DO_LOST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_IGNORE_PT, - g_param_spec_boolean ("ignore-pt", "Ignore PT", - "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT, - G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_AUTOREMOVE, g_param_spec_boolean ("autoremove", "Auto Remove", "Automatically removed timed out sources", DEFAULT_AUTOREMOVE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_IGNORE_PT, + g_param_spec_boolean ("ignore_pt", "Ignore PT", + "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT, + G_PARAM_READWRITE)); + /** + * GstRtpBin::buffer-mode: + * + * Control the buffering and timestamping mode used by the jitterbuffer. + * + * Since: 0.10.17 + */ + g_object_class_install_property (gobject_class, PROP_BUFFER_MODE, + g_param_spec_enum ("buffer-mode", "Buffer Mode", + "Control the buffering algorithm in use", RTP_TYPE_JITTER_BUFFER_MODE, + DEFAULT_BUFFER_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state); gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad); @@ -1560,6 +1576,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass) rtpbin->do_lost = DEFAULT_DO_LOST; rtpbin->ignore_pt = DEFAULT_IGNORE_PT; rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE; + rtpbin->buffer_mode = DEFAULT_BUFFER_MODE; /* some default SDES entries */ str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); @@ -1672,6 +1689,13 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id, case PROP_AUTOREMOVE: rtpbin->priv->autoremove = g_value_get_boolean (value); break; + case PROP_BUFFER_MODE: + GST_RTP_BIN_LOCK (rtpbin); + rtpbin->buffer_mode = g_value_get_enum (value); + GST_RTP_BIN_UNLOCK (rtpbin); + /* propagate the property down to the jitterbuffer */ + gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "mode", value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1706,6 +1730,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id, case PROP_AUTOREMOVE: g_value_set_boolean (value, rtpbin->priv->autoremove); break; + case PROP_BUFFER_MODE: + g_value_set_enum (value, rtpbin->buffer_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1746,7 +1773,17 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) } GST_RTP_BIN_UNLOCK (rtpbin); } - /* fallthrough to forward the modified message to the parent */ + GST_BIN_CLASS (parent_class)->handle_message (bin, message); + break; + } + case GST_MESSAGE_BUFFERING: + { + gint percent; + + gst_message_parse_buffering (message, &percent); + + GST_BIN_CLASS (parent_class)->handle_message (bin, message); + break; } default: { diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h index a791f9a9bc..44b6b01c16 100644 --- a/gst/rtpmanager/gstrtpbin.h +++ b/gst/rtpmanager/gstrtpbin.h @@ -23,6 +23,7 @@ #include #include "rtpsession.h" +#include "rtpjitterbuffer.h" #define GST_TYPE_RTP_BIN \ (gst_rtp_bin_get_type()) @@ -47,6 +48,7 @@ struct _GstRtpBin { guint latency; gboolean do_lost; gboolean ignore_pt; + RTPJitterBufferMode buffer_mode; /* a list of session */ GSList *sessions; diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index f3b7d7c367..2d7be3d7ed 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -88,26 +88,6 @@ enum LAST_SIGNAL }; -#define RTP_TYPE_JITTER_BUFFER_MODE (rtp_jitter_buffer_mode_get_type()) -static GType -rtp_jitter_buffer_mode_get_type (void) -{ - static GType jitter_buffer_mode_type = 0; - static const GEnumValue jitter_buffer_modes[] = { - {RTP_JITTER_BUFFER_MODE_NONE, "Only use RTP timestamps", "none"}, - {RTP_JITTER_BUFFER_MODE_SLAVE, "Slave receiver to sender clock", "slave"}, - {RTP_JITTER_BUFFER_MODE_BUFFER, "Do low/high watermark buffering", - "buffer"}, - {0, NULL, NULL}, - }; - - if (!jitter_buffer_mode_type) { - jitter_buffer_mode_type = - g_enum_register_static ("RTPJitterBufferMode", jitter_buffer_modes); - } - return jitter_buffer_mode_type; -} - #define DEFAULT_LATENCY_MS 200 #define DEFAULT_DROP_ON_LATENCY FALSE #define DEFAULT_TS_OFFSET 0 diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c index c709c9a60f..8397173ed8 100644 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ b/gst/rtpmanager/rtpjitterbuffer.c @@ -44,6 +44,25 @@ enum /* GObject vmethods */ static void rtp_jitter_buffer_finalize (GObject * object); +GType +rtp_jitter_buffer_mode_get_type (void) +{ + static GType jitter_buffer_mode_type = 0; + static const GEnumValue jitter_buffer_modes[] = { + {RTP_JITTER_BUFFER_MODE_NONE, "Only use RTP timestamps", "none"}, + {RTP_JITTER_BUFFER_MODE_SLAVE, "Slave receiver to sender clock", "slave"}, + {RTP_JITTER_BUFFER_MODE_BUFFER, "Do low/high watermark buffering", + "buffer"}, + {0, NULL, NULL}, + }; + + if (!jitter_buffer_mode_type) { + jitter_buffer_mode_type = + g_enum_register_static ("RTPJitterBufferMode", jitter_buffer_modes); + } + return jitter_buffer_mode_type; +} + /* static guint rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; */ G_DEFINE_TYPE (RTPJitterBuffer, rtp_jitter_buffer, G_TYPE_OBJECT); @@ -243,9 +262,14 @@ update_buffer_level (RTPJitterBuffer * jbuf) } } if (post) { - gint percent = (jbuf->level * 100 / jbuf->delay); + gint percent; - percent = MIN (percent, 100); + if (jbuf->buffering) { + percent = (jbuf->level * 100 / jbuf->delay); + percent = MIN (percent, 100); + } else { + percent = 100; + } if (jbuf->stats_cb) jbuf->stats_cb (jbuf, percent, jbuf->stats_data); diff --git a/gst/rtpmanager/rtpjitterbuffer.h b/gst/rtpmanager/rtpjitterbuffer.h index 4cfd1cc60b..c8f28d348f 100644 --- a/gst/rtpmanager/rtpjitterbuffer.h +++ b/gst/rtpmanager/rtpjitterbuffer.h @@ -55,6 +55,9 @@ typedef enum { RTP_JITTER_BUFFER_MODE_LAST } RTPJitterBufferMode; +#define RTP_TYPE_JITTER_BUFFER_MODE (rtp_jitter_buffer_mode_get_type()) +GType rtp_jitter_buffer_mode_get_type (void); + /** * RTPBufferingStats: * @jbuf: an #RTPJitterBuffer