gst/rtpmanager/: Update comment.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 10 Dec 2007 11:08:11 +0000 (11:08 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Tue, 11 Aug 2009 01:30:32 +0000 (02:30 +0100)
Original commit message from CVS:
* gst/rtpmanager/gstrtpbin.c: (create_session):
* gst/rtpmanager/rtpjitterbuffer.c:
Update comment.
* gst/rtpmanager/gstrtpsession.c: (gst_rtp_session_class_init),
(gst_rtp_session_set_property), (gst_rtp_session_get_property):
Define some GObject properties to set SDES and other configuration.
* gst/rtpmanager/rtpsession.c: (rtp_session_class_init),
(rtp_session_init), (rtp_session_finalize),
(rtp_session_set_property), (rtp_session_get_property),
(on_ssrc_sdes), (rtp_session_set_bandwidth),
(rtp_session_get_bandwidth), (rtp_session_set_rtcp_fraction),
(rtp_session_get_rtcp_fraction), (rtp_session_set_sdes_string),
(rtp_session_get_sdes_string), (obtain_source),
(rtp_session_get_internal_source), (rtp_session_process_sdes),
(rtp_session_send_rtp), (rtp_session_next_timeout), (session_sdes),
(is_rtcp_time):
* gst/rtpmanager/rtpsession.h:
Add signal when new SDES infor has been found for a source.
Create properties for SDES and other info.
Simplify the SDES API.
Add method for getting the internal source object of the session.
* gst/rtpmanager/rtpsource.c: (rtp_source_class_init),
(rtp_source_finalize), (rtp_source_set_property),
(rtp_source_get_property), (rtp_source_set_callbacks),
(rtp_source_get_ssrc), (rtp_source_set_as_csrc),
(rtp_source_is_as_csrc), (rtp_source_is_active),
(rtp_source_is_validated), (rtp_source_is_sender),
(rtp_source_received_bye), (rtp_source_get_bye_reason),
(rtp_source_set_sdes), (rtp_source_set_sdes_string),
(rtp_source_get_sdes), (rtp_source_get_sdes_string),
(rtp_source_get_new_sr), (rtp_source_get_new_rb):
* gst/rtpmanager/rtpsource.h:
Add GObject properties for various things.
Don't leak the bye reason.

gst/rtpmanager/gstrtpbin.c
gst/rtpmanager/gstrtpsession.c
gst/rtpmanager/rtpjitterbuffer.c
gst/rtpmanager/rtpsession.c
gst/rtpmanager/rtpsession.h
gst/rtpmanager/rtpsource.c
gst/rtpmanager/rtpsource.h

index 034d652..2049167 100644 (file)
@@ -455,6 +455,7 @@ create_session (GstRtpBin * rtpbin, gint id)
       (GCallback) on_bye_timeout, sess);
   g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
 
+  /* FIXME, change state only to what's needed */
   gst_bin_add (GST_BIN_CAST (rtpbin), session);
   gst_element_set_state (session, GST_STATE_PLAYING);
   gst_bin_add (GST_BIN_CAST (rtpbin), demux);
index f141274..610bd55 100644 (file)
@@ -215,12 +215,35 @@ enum
   LAST_SIGNAL
 };
 
-#define DEFAULT_NTP_NS_BASE 0
+#define DEFAULT_NTP_NS_BASE          0
+#define DEFAULT_BANDWIDTH            RTP_STATS_BANDWIDTH
+#define DEFAULT_RTCP_FRACTION        RTP_STATS_RTCP_BANDWIDTH
+#define DEFAULT_SDES_CNAME           NULL
+#define DEFAULT_SDES_NAME            NULL
+#define DEFAULT_SDES_EMAIL           NULL
+#define DEFAULT_SDES_PHONE           NULL
+#define DEFAULT_SDES_LOCATION        NULL
+#define DEFAULT_SDES_TOOL            NULL
+#define DEFAULT_SDES_NOTE            NULL
+#define DEFAULT_NUM_SOURCES          0
+#define DEFAULT_NUM_ACTIVE_SOURCES   0
 
 enum
 {
   PROP_0,
-  PROP_NTP_NS_BASE
+  PROP_NTP_NS_BASE,
+  PROP_BANDWIDTH,
+  PROP_RTCP_FRACTION,
+  PROP_SDES_CNAME,
+  PROP_SDES_NAME,
+  PROP_SDES_EMAIL,
+  PROP_SDES_PHONE,
+  PROP_SDES_LOCATION,
+  PROP_SDES_TOOL,
+  PROP_SDES_NOTE,
+  PROP_NUM_SOURCES,
+  PROP_NUM_ACTIVE_SOURCES,
+  PROP_LAST
 };
 
 #define GST_RTP_SESSION_GET_PRIVATE(obj)  \
@@ -378,7 +401,6 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
   gobject_class->set_property = gst_rtp_session_set_property;
   gobject_class->get_property = gst_rtp_session_get_property;
 
-
   /**
    * GstRtpSession::request-pt-map:
    * @sess: the object which received the signal
@@ -489,6 +511,61 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
           "The NTP base time corresponding to running_time 0", 0,
           G_MAXUINT64, DEFAULT_NTP_NS_BASE, G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
+      g_param_spec_double ("bandwidth", "Bandwidth",
+          "The bandwidth of the session",
+          0.0, G_MAXDOUBLE, DEFAULT_BANDWIDTH, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_RTCP_FRACTION,
+      g_param_spec_double ("rtcp-fraction", "RTCP Fraction",
+          "The fraction of the bandwidth used for RTCP",
+          0.0, G_MAXDOUBLE, DEFAULT_RTCP_FRACTION, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_CNAME,
+      g_param_spec_string ("sdes-cname", "SDES CNAME",
+          "The CNAME to put in SDES messages of this session",
+          DEFAULT_SDES_CNAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NAME,
+      g_param_spec_string ("sdes-name", "SDES NAME",
+          "The NAME to put in SDES messages of this session",
+          DEFAULT_SDES_NAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_EMAIL,
+      g_param_spec_string ("sdes-email", "SDES EMAIL",
+          "The EMAIL to put in SDES messages of this session",
+          DEFAULT_SDES_EMAIL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_PHONE,
+      g_param_spec_string ("sdes-phone", "SDES PHONE",
+          "The PHONE to put in SDES messages of this session",
+          DEFAULT_SDES_PHONE, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_LOCATION,
+      g_param_spec_string ("sdes-location", "SDES LOCATION",
+          "The LOCATION to put in SDES messages of this session",
+          DEFAULT_SDES_LOCATION, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_TOOL,
+      g_param_spec_string ("sdes-tool", "SDES TOOL",
+          "The TOOL to put in SDES messages of this session",
+          DEFAULT_SDES_TOOL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NOTE,
+      g_param_spec_string ("sdes-note", "SDES NOTE",
+          "The NOTE to put in SDES messages of this session",
+          DEFAULT_SDES_NOTE, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_NUM_SOURCES,
+      g_param_spec_uint ("num-sources", "Num Sources",
+          "The number of sources in the session", 0, G_MAXUINT,
+          DEFAULT_NUM_SOURCES, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_NUM_ACTIVE_SOURCES,
+      g_param_spec_uint ("num-active-sources", "Num Active Sources",
+          "The number of active sources in the session", 0, G_MAXUINT,
+          DEFAULT_NUM_ACTIVE_SOURCES, G_PARAM_READABLE));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
   gstelement_class->request_new_pad =
@@ -550,17 +627,53 @@ gst_rtp_session_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
   GstRtpSession *rtpsession;
+  GstRtpSessionPrivate *priv;
 
   rtpsession = GST_RTP_SESSION (object);
+  priv = rtpsession->priv;
 
   switch (prop_id) {
     case PROP_NTP_NS_BASE:
       GST_OBJECT_LOCK (rtpsession);
-      rtpsession->priv->ntpnsbase = g_value_get_uint64 (value);
+      priv->ntpnsbase = g_value_get_uint64 (value);
       GST_DEBUG_OBJECT (rtpsession, "setting NTP base to %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (rtpsession->priv->ntpnsbase));
+          GST_TIME_ARGS (priv->ntpnsbase));
       GST_OBJECT_UNLOCK (rtpsession);
       break;
+    case PROP_BANDWIDTH:
+      rtp_session_set_bandwidth (priv->session, g_value_get_double (value));
+      break;
+    case PROP_RTCP_FRACTION:
+      rtp_session_set_rtcp_fraction (priv->session, g_value_get_double (value));
+      break;
+    case PROP_SDES_CNAME:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_CNAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NAME:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_NAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_EMAIL:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_EMAIL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_PHONE:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_PHONE,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_LOCATION:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_LOC,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_TOOL:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_TOOL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NOTE:
+      rtp_session_set_sdes_string (priv->session, GST_RTCP_SDES_NOTE,
+          g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -572,15 +685,58 @@ gst_rtp_session_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
   GstRtpSession *rtpsession;
+  GstRtpSessionPrivate *priv;
 
   rtpsession = GST_RTP_SESSION (object);
+  priv = rtpsession->priv;
 
   switch (prop_id) {
     case PROP_NTP_NS_BASE:
       GST_OBJECT_LOCK (rtpsession);
-      g_value_set_uint64 (value, rtpsession->priv->ntpnsbase);
+      g_value_set_uint64 (value, priv->ntpnsbase);
       GST_OBJECT_UNLOCK (rtpsession);
       break;
+    case PROP_BANDWIDTH:
+      g_value_set_double (value, rtp_session_get_bandwidth (priv->session));
+      break;
+    case PROP_RTCP_FRACTION:
+      g_value_set_double (value, rtp_session_get_rtcp_fraction (priv->session));
+      break;
+    case PROP_SDES_CNAME:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_CNAME));
+      break;
+    case PROP_SDES_NAME:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_NAME));
+      break;
+    case PROP_SDES_EMAIL:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_EMAIL));
+      break;
+    case PROP_SDES_PHONE:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_PHONE));
+      break;
+    case PROP_SDES_LOCATION:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_LOC));
+      break;
+    case PROP_SDES_TOOL:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_TOOL));
+      break;
+    case PROP_SDES_NOTE:
+      g_value_take_string (value, rtp_session_get_sdes_string (priv->session,
+              GST_RTCP_SDES_NOTE));
+      break;
+    case PROP_NUM_SOURCES:
+      g_value_set_uint (value, rtp_session_get_num_sources (priv->session));
+      break;
+    case PROP_NUM_ACTIVE_SOURCES:
+      g_value_set_uint (value,
+          rtp_session_get_num_active_sources (priv->session));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index f3c2a2a..4a9ea8f 100644 (file)
@@ -181,7 +181,7 @@ rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf)
  * We use a 2 second window or up to 512 data points, which is statistically big
  * enough to catch spikes (FIXME, detect spikes).
  * We also use a rather large weighting factor (125) to smoothly adapt. During
- * startup, when filling the window) we use a parabolic weighting factor, the
+ * startup, when filling the window, we use a parabolic weighting factor, the
  * more the window is filled, the faster we move to the detected possible skew.
  *
  * Returns: @time adjusted with the clock skew.
index 628147d..1ded0dc 100644 (file)
@@ -37,18 +37,42 @@ enum
   SIGNAL_ON_SSRC_COLLISION,
   SIGNAL_ON_SSRC_VALIDATED,
   SIGNAL_ON_SSRC_ACTIVE,
+  SIGNAL_ON_SSRC_SDES,
   SIGNAL_ON_BYE_SSRC,
   SIGNAL_ON_BYE_TIMEOUT,
   SIGNAL_ON_TIMEOUT,
   LAST_SIGNAL
 };
 
-#define RTP_DEFAULT_BANDWIDTH        64000.0
-#define RTP_DEFAULT_RTCP_BANDWIDTH   1000
+#define DEFAULT_INTERNAL_SOURCE      NULL
+#define DEFAULT_BANDWIDTH            RTP_STATS_BANDWIDTH
+#define DEFAULT_RTCP_FRACTION        RTP_STATS_RTCP_BANDWIDTH
+#define DEFAULT_SDES_CNAME           NULL
+#define DEFAULT_SDES_NAME            NULL
+#define DEFAULT_SDES_EMAIL           NULL
+#define DEFAULT_SDES_PHONE           NULL
+#define DEFAULT_SDES_LOCATION        NULL
+#define DEFAULT_SDES_TOOL            NULL
+#define DEFAULT_SDES_NOTE            NULL
+#define DEFAULT_NUM_SOURCES          0
+#define DEFAULT_NUM_ACTIVE_SOURCES   0
 
 enum
 {
-  PROP_0
+  PROP_0,
+  PROP_INTERNAL_SOURCE,
+  PROP_BANDWIDTH,
+  PROP_RTCP_FRACTION,
+  PROP_SDES_CNAME,
+  PROP_SDES_NAME,
+  PROP_SDES_EMAIL,
+  PROP_SDES_PHONE,
+  PROP_SDES_LOCATION,
+  PROP_SDES_TOOL,
+  PROP_SDES_NOTE,
+  PROP_NUM_SOURCES,
+  PROP_NUM_ACTIVE_SOURCES,
+  PROP_LAST
 };
 
 /* update average packet size, we keep this scaled by 16 to keep enough
@@ -121,7 +145,7 @@ rtp_session_class_init (RTPSessionClass * klass)
       NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
       G_TYPE_OBJECT);
   /**
-   * RTPSession::on-ssrc_active:
+   * RTPSession::on-ssrc-active:
    * @session: the object which received the signal
    * @src: the active RTPSource
    *
@@ -133,6 +157,18 @@ rtp_session_class_init (RTPSessionClass * klass)
       NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
       G_TYPE_OBJECT);
   /**
+   * RTPSession::on-ssrc-sdes:
+   * @session: the object which received the signal
+   * @src: the RTPSource
+   *
+   * Notify that a new SDES was received for SSRC.
+   */
+  rtp_session_signals[SIGNAL_ON_SSRC_SDES] =
+      g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_ssrc_sdes),
+      NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+      G_TYPE_OBJECT);
+  /**
    * RTPSession::on-bye-ssrc:
    * @session: the object which received the signal
    * @src: the RTPSource that went away
@@ -169,6 +205,66 @@ rtp_session_class_init (RTPSessionClass * klass)
       NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
       G_TYPE_OBJECT);
 
+  g_object_class_install_property (gobject_class, PROP_INTERNAL_SOURCE,
+      g_param_spec_object ("internal-source", "Internal Source",
+          "The internal source element of the session",
+          RTP_TYPE_SOURCE, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
+      g_param_spec_double ("bandwidth", "Bandwidth",
+          "The bandwidth of the session",
+          0.0, G_MAXDOUBLE, DEFAULT_BANDWIDTH, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_RTCP_FRACTION,
+      g_param_spec_double ("rtcp-fraction", "RTCP Fraction",
+          "The fraction of the bandwidth used for RTCP",
+          0.0, G_MAXDOUBLE, DEFAULT_RTCP_FRACTION, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_CNAME,
+      g_param_spec_string ("sdes-cname", "SDES CNAME",
+          "The CNAME to put in SDES messages of this session",
+          DEFAULT_SDES_CNAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NAME,
+      g_param_spec_string ("sdes-name", "SDES NAME",
+          "The NAME to put in SDES messages of this session",
+          DEFAULT_SDES_NAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_EMAIL,
+      g_param_spec_string ("sdes-email", "SDES EMAIL",
+          "The EMAIL to put in SDES messages of this session",
+          DEFAULT_SDES_EMAIL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_PHONE,
+      g_param_spec_string ("sdes-phone", "SDES PHONE",
+          "The PHONE to put in SDES messages of this session",
+          DEFAULT_SDES_PHONE, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_LOCATION,
+      g_param_spec_string ("sdes-location", "SDES LOCATION",
+          "The LOCATION to put in SDES messages of this session",
+          DEFAULT_SDES_LOCATION, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_TOOL,
+      g_param_spec_string ("sdes-tool", "SDES TOOL",
+          "The TOOL to put in SDES messages of this session",
+          DEFAULT_SDES_TOOL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NOTE,
+      g_param_spec_string ("sdes-note", "SDES NOTE",
+          "The NOTE to put in SDES messages of this session",
+          DEFAULT_SDES_NOTE, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_NUM_SOURCES,
+      g_param_spec_uint ("num-sources", "Num Sources",
+          "The number of sources in the session", 0, G_MAXUINT,
+          DEFAULT_NUM_SOURCES, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_NUM_ACTIVE_SOURCES,
+      g_param_spec_uint ("num-active-sources", "Num Active Sources",
+          "The number of active sources in the session", 0, G_MAXUINT,
+          DEFAULT_NUM_ACTIVE_SOURCES, G_PARAM_READABLE));
+
   GST_DEBUG_CATEGORY_INIT (rtp_session_debug, "rtpsession", 0, "RTP Session");
 }
 
@@ -176,6 +272,7 @@ static void
 rtp_session_init (RTPSession * sess)
 {
   gint i;
+  gchar *str;
 
   sess->lock = g_mutex_new ();
   sess->key = g_random_int ();
@@ -201,10 +298,13 @@ rtp_session_init (RTPSession * sess)
   sess->mtu = 1400;
 
   /* some default SDES entries */
-  sess->cname =
-      g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ());
-  sess->name = g_strdup (g_get_real_name ());
-  sess->tool = g_strdup ("GStreamer");
+  str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ());
+  rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_CNAME, str);
+  g_free (str);
+
+  rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_NAME,
+      g_get_real_name ());
+  rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_TOOL, "GStreamer");
 
   sess->first_rtcp = TRUE;
 
@@ -226,15 +326,6 @@ rtp_session_finalize (GObject * object)
   g_hash_table_destroy (sess->cnames);
   g_object_unref (sess->source);
 
-  g_free (sess->cname);
-  g_free (sess->name);
-  g_free (sess->email);
-  g_free (sess->phone);
-  g_free (sess->location);
-  g_free (sess->tool);
-  g_free (sess->note);
-  g_free (sess->bye_reason);
-
   G_OBJECT_CLASS (rtp_session_parent_class)->finalize (object);
 }
 
@@ -247,6 +338,40 @@ rtp_session_set_property (GObject * object, guint prop_id,
   sess = RTP_SESSION (object);
 
   switch (prop_id) {
+    case PROP_BANDWIDTH:
+      rtp_session_set_bandwidth (sess, g_value_get_double (value));
+      break;
+    case PROP_RTCP_FRACTION:
+      rtp_session_set_rtcp_fraction (sess, g_value_get_double (value));
+      break;
+    case PROP_SDES_CNAME:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_CNAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NAME:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_NAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_EMAIL:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_EMAIL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_PHONE:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_PHONE,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_LOCATION:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_LOC,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_TOOL:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_TOOL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NOTE:
+      rtp_session_set_sdes_string (sess, GST_RTCP_SDES_NOTE,
+          g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -262,6 +387,49 @@ rtp_session_get_property (GObject * object, guint prop_id,
   sess = RTP_SESSION (object);
 
   switch (prop_id) {
+    case PROP_INTERNAL_SOURCE:
+      g_value_take_object (value, rtp_session_get_internal_source (sess));
+      break;
+    case PROP_BANDWIDTH:
+      g_value_set_double (value, rtp_session_get_bandwidth (sess));
+      break;
+    case PROP_RTCP_FRACTION:
+      g_value_set_double (value, rtp_session_get_rtcp_fraction (sess));
+      break;
+    case PROP_SDES_CNAME:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_CNAME));
+      break;
+    case PROP_SDES_NAME:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_NAME));
+      break;
+    case PROP_SDES_EMAIL:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_EMAIL));
+      break;
+    case PROP_SDES_PHONE:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_PHONE));
+      break;
+    case PROP_SDES_LOCATION:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_LOC));
+      break;
+    case PROP_SDES_TOOL:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_TOOL));
+      break;
+    case PROP_SDES_NOTE:
+      g_value_take_string (value, rtp_session_get_sdes_string (sess,
+              GST_RTCP_SDES_NOTE));
+      break;
+    case PROP_NUM_SOURCES:
+      g_value_set_uint (value, rtp_session_get_num_sources (sess));
+      break;
+    case PROP_NUM_ACTIVE_SOURCES:
+      g_value_set_uint (value, rtp_session_get_num_active_sources (sess));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -303,6 +471,14 @@ on_ssrc_active (RTPSession * sess, RTPSource * source)
 }
 
 static void
+on_ssrc_sdes (RTPSession * sess, RTPSource * source)
+{
+  RTP_SESSION_UNLOCK (sess);
+  g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SSRC_SDES], 0, source);
+  RTP_SESSION_LOCK (sess);
+}
+
+static void
 on_bye_ssrc (RTPSession * sess, RTPSource * source)
 {
   RTP_SESSION_UNLOCK (sess);
@@ -378,7 +554,9 @@ rtp_session_set_bandwidth (RTPSession * sess, gdouble bandwidth)
 {
   g_return_if_fail (RTP_IS_SESSION (sess));
 
+  RTP_SESSION_LOCK (sess);
   sess->stats.bandwidth = bandwidth;
+  RTP_SESSION_UNLOCK (sess);
 }
 
 /**
@@ -392,13 +570,19 @@ rtp_session_set_bandwidth (RTPSession * sess, gdouble bandwidth)
 gdouble
 rtp_session_get_bandwidth (RTPSession * sess)
 {
+  gdouble result;
+
   g_return_val_if_fail (RTP_IS_SESSION (sess), 0);
 
-  return sess->stats.bandwidth;
+  RTP_SESSION_LOCK (sess);
+  result = sess->stats.bandwidth;
+  RTP_SESSION_UNLOCK (sess);
+
+  return result;
 }
 
 /**
- * rtp_session_set_rtcp_bandwidth:
+ * rtp_session_set_rtcp_fraction:
  * @sess: an #RTPSession
  * @bandwidth: the RTCP bandwidth
  *
@@ -406,15 +590,17 @@ rtp_session_get_bandwidth (RTPSession * sess)
  * messages.
  */
 void
-rtp_session_set_rtcp_bandwidth (RTPSession * sess, gdouble bandwidth)
+rtp_session_set_rtcp_fraction (RTPSession * sess, gdouble bandwidth)
 {
   g_return_if_fail (RTP_IS_SESSION (sess));
 
+  RTP_SESSION_LOCK (sess);
   sess->stats.rtcp_bandwidth = bandwidth;
+  RTP_SESSION_UNLOCK (sess);
 }
 
 /**
- * rtp_session_get_rtcp_bandwidth:
+ * rtp_session_get_rtcp_fraction:
  * @sess: an #RTPSession
  *
  * Get the session bandwidth used for RTCP.
@@ -422,235 +608,66 @@ rtp_session_set_rtcp_bandwidth (RTPSession * sess, gdouble bandwidth)
  * Returns: The bandwidth used for RTCP messages.
  */
 gdouble
-rtp_session_get_rtcp_bandwidth (RTPSession * sess)
+rtp_session_get_rtcp_fraction (RTPSession * sess)
 {
-  g_return_val_if_fail (RTP_IS_SESSION (sess), 0.0);
+  gdouble result;
 
-  return sess->stats.rtcp_bandwidth;
-}
-
-/**
- * rtp_session_set_cname:
- * @sess: an #RTPSession
- * @cname: a CNAME for the session
- *
- * Set the CNAME for the session.
- */
-void
-rtp_session_set_cname (RTPSession * sess, const gchar * cname)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
-
-  g_free (sess->cname);
-  sess->cname = g_strdup (cname);
-}
-
-/**
- * rtp_session_get_cname:
- * @sess: an #RTPSession
- *
- * Get the currently configured CNAME for the session.
- *
- * Returns: The CNAME. g_free after usage.
- */
-gchar *
-rtp_session_get_cname (RTPSession * sess)
-{
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
-
-  return g_strdup (sess->cname);
-}
-
-/**
- * rtp_session_set_name:
- * @sess: an #RTPSession
- * @name: a NAME for the session
- *
- * Set the NAME for the session.
- */
-void
-rtp_session_set_name (RTPSession * sess, const gchar * name)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
-
-  g_free (sess->name);
-  sess->name = g_strdup (name);
-}
-
-/**
- * rtp_session_get_name:
- * @sess: an #RTPSession
- *
- * Get the currently configured NAME for the session.
- *
- * Returns: The NAME. g_free after usage.
- */
-gchar *
-rtp_session_get_name (RTPSession * sess)
-{
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
-
-  return g_strdup (sess->name);
-}
-
-/**
- * rtp_session_set_email:
- * @sess: an #RTPSession
- * @email: an EMAIL for the session
- *
- * Set the EMAIL the session.
- */
-void
-rtp_session_set_email (RTPSession * sess, const gchar * email)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
-
-  g_free (sess->email);
-  sess->email = g_strdup (email);
-}
-
-/**
- * rtp_session_get_email:
- * @sess: an #RTPSession
- *
- * Get the currently configured EMAIL of the session.
- *
- * Returns: The EMAIL. g_free after usage.
- */
-gchar *
-rtp_session_get_email (RTPSession * sess)
-{
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
-
-  return g_strdup (sess->email);
-}
+  g_return_val_if_fail (RTP_IS_SESSION (sess), 0.0);
 
-/**
- * rtp_session_set_phone:
- * @sess: an #RTPSession
- * @phone: a PHONE for the session
- *
- * Set the PHONE the session.
- */
-void
-rtp_session_set_phone (RTPSession * sess, const gchar * phone)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
+  RTP_SESSION_LOCK (sess);
+  result = sess->stats.rtcp_bandwidth;
+  RTP_SESSION_UNLOCK (sess);
 
-  g_free (sess->phone);
-  sess->phone = g_strdup (phone);
+  return result;
 }
 
 /**
- * rtp_session_get_location:
+ * rtp_session_set_sdes_string:
  * @sess: an #RTPSession
+ * @type: the type of the SDES item
+ * @item: a null-terminated string to set. 
  *
- * Get the currently configured PHONE of the session.
+ * Store an SDES item of @type in @sess. 
  *
- * Returns: The PHONE. g_free after usage.
+ * Returns: %FALSE if the data was unchanged @type is invalid.
  */
-gchar *
-rtp_session_get_phone (RTPSession * sess)
+gboolean
+rtp_session_set_sdes_string (RTPSession * sess, GstRTCPSDESType type,
+    const gchar * item)
 {
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
+  gboolean result;
 
-  return g_strdup (sess->phone);
-}
+  g_return_val_if_fail (RTP_IS_SESSION (sess), FALSE);
 
-/**
- * rtp_session_set_location:
- * @sess: an #RTPSession
- * @location: a LOCATION for the session
- *
- * Set the LOCATION the session.
- */
-void
-rtp_session_set_location (RTPSession * sess, const gchar * location)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
+  RTP_SESSION_LOCK (sess);
+  result = rtp_source_set_sdes_string (sess->source, type, item);
+  RTP_SESSION_UNLOCK (sess);
 
-  g_free (sess->location);
-  sess->location = g_strdup (location);
+  return result;
 }
 
 /**
- * rtp_session_get_location:
+ * rtp_session_get_sdes_string:
  * @sess: an #RTPSession
+ * @type: the type of the SDES item
  *
- * Get the currently configured LOCATION of the session.
+ * Get the SDES item of @type from @sess. 
  *
- * Returns: The LOCATION. g_free after usage.
+ * Returns: a null-terminated copy of the SDES item or NULL when @type was not
+ * valid. g_free() after usage.
  */
 gchar *
-rtp_session_get_location (RTPSession * sess)
+rtp_session_get_sdes_string (RTPSession * sess, GstRTCPSDESType type)
 {
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
-
-  return g_strdup (sess->location);
-}
+  gchar *result;
 
-/**
- * rtp_session_set_tool:
- * @sess: an #RTPSession
- * @tool: a TOOL for the session
- *
- * Set the TOOL the session.
- */
-void
-rtp_session_set_tool (RTPSession * sess, const gchar * tool)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
-
-  g_free (sess->tool);
-  sess->tool = g_strdup (tool);
-}
-
-/**
- * rtp_session_get_tool:
- * @sess: an #RTPSession
- *
- * Get the currently configured TOOL of the session.
- *
- * Returns: The TOOL. g_free after usage.
- */
-gchar *
-rtp_session_get_tool (RTPSession * sess)
-{
   g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
 
-  return g_strdup (sess->tool);
-}
-
-/**
- * rtp_session_set_note:
- * @sess: an #RTPSession
- * @note: a NOTE for the session
- *
- * Set the NOTE the session.
- */
-void
-rtp_session_set_note (RTPSession * sess, const gchar * note)
-{
-  g_return_if_fail (RTP_IS_SESSION (sess));
-
-  g_free (sess->note);
-  sess->note = g_strdup (note);
-}
-
-/**
- * rtp_session_get_note:
- * @sess: an #RTPSession
- *
- * Get the currently configured NOTE of the session.
- *
- * Returns: The NOTE. g_free after usage.
- */
-gchar *
-rtp_session_get_note (RTPSession * sess)
-{
-  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
+  RTP_SESSION_LOCK (sess);
+  result = rtp_source_get_sdes_string (sess->source, type);
+  RTP_SESSION_UNLOCK (sess);
 
-  return g_strdup (sess->note);
+  return result;
 }
 
 static GstFlowReturn
@@ -714,6 +731,7 @@ check_collision (RTPSession * sess, RTPSource * source,
   return FALSE;
 }
 
+/* must be called with the session lock */
 static RTPSource *
 obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created,
     RTPArrivalStats * arrival, gboolean rtp)
@@ -726,6 +744,9 @@ obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created,
     /* make new Source in probation and insert */
     source = rtp_source_new (ssrc);
 
+    /* for RTP packets we need to set the source in probation. Receiving RTCP
+     * packets of an SSRC, on the other hand, is a strong indication that we
+     * are dealing with a valid source. */
     if (rtp)
       source->probation = RTP_DEFAULT_PROBATION;
     else
@@ -763,6 +784,26 @@ obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created,
 }
 
 /**
+ * rtp_session_get_internal_source:
+ * @sess: a #RTPSession
+ *
+ * Get the internal #RTPSource of @session.
+ *
+ * Returns: The internal #RTPSource. g_object_unref() after usage.
+ */
+RTPSource *
+rtp_session_get_internal_source (RTPSession * sess)
+{
+  RTPSource *result;
+
+  g_return_val_if_fail (RTP_IS_SESSION (sess), NULL);
+
+  result = g_object_ref (sess->source);
+
+  return result;
+}
+
+/**
  * rtp_session_add_source:
  * @sess: a #RTPSession
  * @src: #RTPSource to add
@@ -1194,11 +1235,17 @@ rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet,
   i = 0;
   while (more_items) {
     guint32 ssrc;
+    gboolean changed, created;
+    RTPSource *source;
 
     ssrc = gst_rtcp_packet_sdes_get_ssrc (packet);
 
     GST_DEBUG ("item %d, SSRC %08x", i, ssrc);
 
+    /* find src, no probation when dealing with RTCP */
+    source = obtain_source (sess, ssrc, &created, arrival, FALSE);
+    changed = FALSE;
+
     more_entries = gst_rtcp_packet_sdes_first_entry (packet);
     j = 0;
     while (more_entries) {
@@ -1211,9 +1258,17 @@ rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet,
       GST_DEBUG ("entry %d, type %d, len %d, data %.*s", j, type, len, len,
           data);
 
+
+
       more_entries = gst_rtcp_packet_sdes_next_entry (packet);
       j++;
     }
+
+    if (created)
+      on_new_ssrc (sess, source);
+    if (changed)
+      on_ssrc_sdes (sess, source);
+
     more_items = gst_rtcp_packet_sdes_next_item (packet);
     i++;
   }
@@ -1418,7 +1473,7 @@ ignore:
  * rtp_session_send_rtp:
  * @sess: an #RTPSession
  * @buffer: an RTP buffer
- * @ntptime: the NTP time of when this buffer was captured.
+ * @ntpnstime: the NTP time in nanoseconds of when this buffer was captured.
  *
  * Send the RTP buffer in the session manager. This function takes ownership of
  * @buffer.
@@ -1426,7 +1481,7 @@ ignore:
  * Returns: a #GstFlowReturn.
  */
 GstFlowReturn
-rtp_session_send_rtp (RTPSession * sess, GstBuffer * buffer, guint64 ntptime)
+rtp_session_send_rtp (RTPSession * sess, GstBuffer * buffer, guint64 ntpnstime)
 {
   GstFlowReturn result;
   RTPSource *source;
@@ -1451,7 +1506,7 @@ rtp_session_send_rtp (RTPSession * sess, GstBuffer * buffer, guint64 ntptime)
   prevsender = RTP_SOURCE_IS_SENDER (source);
 
   /* we use our own source to send */
-  result = rtp_source_send_rtp (source, buffer, ntptime);
+  result = rtp_source_send_rtp (source, buffer, ntpnstime);
 
   if (RTP_SOURCE_IS_SENDER (source) && !prevsender)
     sess->stats.sender_sources++;
@@ -1755,13 +1810,18 @@ static void
 session_sdes (RTPSession * sess, ReportData * data)
 {
   GstRTCPPacket *packet = &data->packet;
+  guint8 *sdes_data;
+  guint sdes_len;
 
   /* add SDES packet */
   gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_SDES, packet);
 
   gst_rtcp_packet_sdes_add_item (packet, sess->source->ssrc);
-  gst_rtcp_packet_sdes_add_entry (packet, GST_RTCP_SDES_CNAME,
-      strlen (sess->cname), (guint8 *) sess->cname);
+
+  rtp_source_get_sdes (sess->source, GST_RTCP_SDES_CNAME, &sdes_data,
+      &sdes_len);
+  gst_rtcp_packet_sdes_add_entry (packet, GST_RTCP_SDES_CNAME, sdes_len,
+      sdes_data);
 
   /* other SDES items must only be added at regular intervals and only when the
    * user requests to since it might be a privacy problem */
index 359a741..0c99d53 100644 (file)
@@ -162,15 +162,6 @@ struct _RTPSession {
 
   RTPSource    *source;
 
-  /* info for creating reports */
-  gchar        *cname;
-  gchar        *name;
-  gchar        *email;
-  gchar        *phone;
-  gchar        *location;
-  gchar        *tool;
-  gchar        *note;
-
   /* for sender/receiver counting */
   guint32       key;
   guint32       mask_idx;
@@ -210,6 +201,7 @@ struct _RTPSessionClass {
   void (*on_ssrc_collision) (RTPSession *sess, RTPSource *source);
   void (*on_ssrc_validated) (RTPSession *sess, RTPSource *source);
   void (*on_ssrc_active)    (RTPSession *sess, RTPSource *source);
+  void (*on_ssrc_sdes)      (RTPSession *sess, RTPSource *source);
   void (*on_bye_ssrc)       (RTPSession *sess, RTPSource *source);
   void (*on_bye_timeout)    (RTPSession *sess, RTPSource *source);
   void (*on_timeout)        (RTPSession *sess, RTPSource *source);
@@ -227,22 +219,12 @@ gdouble         rtp_session_get_bandwidth          (RTPSession *sess);
 void            rtp_session_set_rtcp_fraction      (RTPSession *sess, gdouble fraction);
 gdouble         rtp_session_get_rtcp_fraction      (RTPSession *sess);
 
-void            rtp_session_set_cname              (RTPSession *sess, const gchar *cname);
-gchar*          rtp_session_get_cname              (RTPSession *sess);
-void            rtp_session_set_name               (RTPSession *sess, const gchar *name);
-gchar*          rtp_session_get_name               (RTPSession *sess);
-void            rtp_session_set_email              (RTPSession *sess, const gchar *email);
-gchar*          rtp_session_get_email              (RTPSession *sess);
-void            rtp_session_set_phone              (RTPSession *sess, const gchar *phone);
-gchar*          rtp_session_get_phone              (RTPSession *sess);
-void            rtp_session_set_location           (RTPSession *sess, const gchar *location);
-gchar*          rtp_session_get_location           (RTPSession *sess);
-void            rtp_session_set_tool               (RTPSession *sess, const gchar *tool);
-gchar*          rtp_session_get_tool               (RTPSession *sess);
-void            rtp_session_set_note               (RTPSession *sess, const gchar *note);
-gchar*          rtp_session_get_note               (RTPSession *sess);
+gboolean        rtp_session_set_sdes_string        (RTPSession *sess, GstRTCPSDESType type,
+                                                    const gchar *cname);
+gchar*          rtp_session_get_sdes_string        (RTPSession *sess, GstRTCPSDESType type);
 
 /* handling sources */
+RTPSource*      rtp_session_get_internal_source    (RTPSession *sess);
 gboolean        rtp_session_add_source             (RTPSession *sess, RTPSource *src);
 guint           rtp_session_get_num_sources        (RTPSession *sess);
 guint           rtp_session_get_num_active_sources (RTPSession *sess);
@@ -255,13 +237,13 @@ GstFlowReturn   rtp_session_process_rtp            (RTPSession *sess, GstBuffer
 GstFlowReturn   rtp_session_process_rtcp           (RTPSession *sess, GstBuffer *buffer);
 
 /* processing packets for sending */
-GstFlowReturn   rtp_session_send_rtp               (RTPSession *sess, GstBuffer *buffer, guint64 ntptime);
+GstFlowReturn   rtp_session_send_rtp               (RTPSession *sess, GstBuffer *buffer, guint64 ntpnstime);
 
 /* stopping the session */
 GstFlowReturn   rtp_session_send_bye               (RTPSession *sess, const gchar *reason);
 
 /* get interval for next RTCP interval */
-GstClockTime    rtp_session_next_timeout          (RTPSession *sess, GstClockTime time);
-GstFlowReturn   rtp_session_on_timeout            (RTPSession *sess, GstClockTime time, guint64 ntpnstime);
+GstClockTime    rtp_session_next_timeout           (RTPSession *sess, GstClockTime time);
+GstFlowReturn   rtp_session_on_timeout             (RTPSession *sess, GstClockTime time, guint64 ntpnstime);
 
 #endif /* __RTP_SESSION_H__ */
index 1d7eb24..8374036 100644 (file)
@@ -34,13 +34,41 @@ enum
   LAST_SIGNAL
 };
 
+#define DEFAULT_SSRC                 0
+#define DEFAULT_IS_CSRC              FALSE
+#define DEFAULT_IS_VALIDATED         FALSE
+#define DEFAULT_IS_SENDER            FALSE
+#define DEFAULT_SDES_CNAME           NULL
+#define DEFAULT_SDES_NAME            NULL
+#define DEFAULT_SDES_EMAIL           NULL
+#define DEFAULT_SDES_PHONE           NULL
+#define DEFAULT_SDES_LOCATION        NULL
+#define DEFAULT_SDES_TOOL            NULL
+#define DEFAULT_SDES_NOTE            NULL
+
 enum
 {
-  PROP_0
+  PROP_0,
+  PROP_SSRC,
+  PROP_IS_CSRC,
+  PROP_IS_VALIDATED,
+  PROP_IS_SENDER,
+  PROP_SDES_CNAME,
+  PROP_SDES_NAME,
+  PROP_SDES_EMAIL,
+  PROP_SDES_PHONE,
+  PROP_SDES_LOCATION,
+  PROP_SDES_TOOL,
+  PROP_SDES_NOTE,
+  PROP_LAST
 };
 
 /* GObject vmethods */
 static void rtp_source_finalize (GObject * object);
+static void rtp_source_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void rtp_source_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
 /* static guint rtp_source_signals[LAST_SIGNAL] = { 0 }; */
 
@@ -55,6 +83,62 @@ rtp_source_class_init (RTPSourceClass * klass)
 
   gobject_class->finalize = rtp_source_finalize;
 
+  gobject_class->set_property = rtp_source_set_property;
+  gobject_class->get_property = rtp_source_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_SSRC,
+      g_param_spec_uint ("ssrc", "SSRC",
+          "The SSRC of this source", 0, G_MAXUINT,
+          DEFAULT_SSRC, G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class, PROP_IS_CSRC,
+      g_param_spec_boolean ("is-csrc", "Is CSRC",
+          "If this SSRC is acting as a contributing source",
+          DEFAULT_IS_CSRC, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_IS_VALIDATED,
+      g_param_spec_boolean ("is-validated", "Is Validated",
+          "If this SSRC is validated", DEFAULT_IS_VALIDATED, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_IS_SENDER,
+      g_param_spec_boolean ("is-sender", "Is Sender",
+          "If this SSRC is a sender", DEFAULT_IS_SENDER, G_PARAM_READABLE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_CNAME,
+      g_param_spec_string ("sdes-cname", "SDES CNAME",
+          "The CNAME to put in SDES messages of this source",
+          DEFAULT_SDES_CNAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NAME,
+      g_param_spec_string ("sdes-name", "SDES NAME",
+          "The NAME to put in SDES messages of this source",
+          DEFAULT_SDES_NAME, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_EMAIL,
+      g_param_spec_string ("sdes-email", "SDES EMAIL",
+          "The EMAIL to put in SDES messages of this source",
+          DEFAULT_SDES_EMAIL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_PHONE,
+      g_param_spec_string ("sdes-phone", "SDES PHONE",
+          "The PHONE to put in SDES messages of this source",
+          DEFAULT_SDES_PHONE, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_LOCATION,
+      g_param_spec_string ("sdes-location", "SDES LOCATION",
+          "The LOCATION to put in SDES messages of this source",
+          DEFAULT_SDES_LOCATION, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_TOOL,
+      g_param_spec_string ("sdes-tool", "SDES TOOL",
+          "The TOOL to put in SDES messages of this source",
+          DEFAULT_SDES_TOOL, G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_SDES_NOTE,
+      g_param_spec_string ("sdes-note", "SDES NOTE",
+          "The NOTE to put in SDES messages of this source",
+          DEFAULT_SDES_NOTE, G_PARAM_READWRITE));
+
   GST_DEBUG_CATEGORY_INIT (rtp_source_debug, "rtpsource", 0, "RTP Source");
 }
 
@@ -92,9 +176,109 @@ rtp_source_finalize (GObject * object)
     gst_buffer_unref (buffer);
   g_queue_free (src->packets);
 
+  g_free (src->bye_reason);
+
   G_OBJECT_CLASS (rtp_source_parent_class)->finalize (object);
 }
 
+static void
+rtp_source_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  RTPSource *src;
+
+  src = RTP_SOURCE (object);
+
+  switch (prop_id) {
+    case PROP_SDES_CNAME:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_CNAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NAME:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_NAME,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_EMAIL:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_EMAIL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_PHONE:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_PHONE,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_LOCATION:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_LOC,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_TOOL:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_TOOL,
+          g_value_get_string (value));
+      break;
+    case PROP_SDES_NOTE:
+      rtp_source_set_sdes_string (src, GST_RTCP_SDES_NOTE,
+          g_value_get_string (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+rtp_source_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  RTPSource *src;
+
+  src = RTP_SOURCE (object);
+
+  switch (prop_id) {
+    case PROP_SSRC:
+      g_value_set_uint (value, rtp_source_get_ssrc (src));
+      break;
+    case PROP_IS_CSRC:
+      g_value_set_boolean (value, rtp_source_is_as_csrc (src));
+      break;
+    case PROP_IS_VALIDATED:
+      g_value_set_boolean (value, rtp_source_is_validated (src));
+      break;
+    case PROP_IS_SENDER:
+      g_value_set_boolean (value, rtp_source_is_sender (src));
+      break;
+    case PROP_SDES_CNAME:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_CNAME));
+      break;
+    case PROP_SDES_NAME:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_NAME));
+      break;
+    case PROP_SDES_EMAIL:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_EMAIL));
+      break;
+    case PROP_SDES_PHONE:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_PHONE));
+      break;
+    case PROP_SDES_LOCATION:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_LOC));
+      break;
+    case PROP_SDES_TOOL:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_TOOL));
+      break;
+    case PROP_SDES_NOTE:
+      g_value_take_string (value, rtp_source_get_sdes_string (src,
+              GST_RTCP_SDES_NOTE));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
 /**
  * rtp_source_new:
  * @ssrc: an SSRC
@@ -115,6 +299,184 @@ rtp_source_new (guint32 ssrc)
 }
 
 /**
+ * rtp_source_set_callbacks:
+ * @src: an #RTPSource
+ * @cb: callback functions
+ * @user_data: user data
+ *
+ * Set the callbacks for the source.
+ */
+void
+rtp_source_set_callbacks (RTPSource * src, RTPSourceCallbacks * cb,
+    gpointer user_data)
+{
+  g_return_if_fail (RTP_IS_SOURCE (src));
+
+  src->callbacks.push_rtp = cb->push_rtp;
+  src->callbacks.clock_rate = cb->clock_rate;
+  src->user_data = user_data;
+}
+
+/**
+ * rtp_source_get_ssrc:
+ * @src: an #RTPSource
+ *
+ * Get the SSRC of @source.
+ *
+ * Returns: the SSRC of src.
+ */
+guint32
+rtp_source_get_ssrc (RTPSource * src)
+{
+  guint32 result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), 0);
+
+  result = src->ssrc;
+
+  return result;
+}
+
+/**
+ * rtp_source_set_as_csrc:
+ * @src: an #RTPSource
+ *
+ * Configure @src as a CSRC, this will also validate @src.
+ */
+void
+rtp_source_set_as_csrc (RTPSource * src)
+{
+  g_return_if_fail (RTP_IS_SOURCE (src));
+
+  src->validated = TRUE;
+  src->is_csrc = TRUE;
+}
+
+/**
+ * rtp_source_is_as_csrc:
+ * @src: an #RTPSource
+ *
+ * Check if @src is a contributing source.
+ *
+ * Returns: %TRUE if @src is acting as a contributing source.
+ */
+gboolean
+rtp_source_is_as_csrc (RTPSource * src)
+{
+  gboolean result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  result = src->is_csrc;
+
+  return result;
+}
+
+/**
+ * rtp_source_is_active:
+ * @src: an #RTPSource
+ *
+ * Check if @src is an active source. A source is active if it has been
+ * validated and has not yet received a BYE packet
+ *
+ * Returns: %TRUE if @src is an qactive source.
+ */
+gboolean
+rtp_source_is_active (RTPSource * src)
+{
+  gboolean result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  result = RTP_SOURCE_IS_ACTIVE (src);
+
+  return result;
+}
+
+/**
+ * rtp_source_is_validated:
+ * @src: an #RTPSource
+ *
+ * Check if @src is a validated source.
+ *
+ * Returns: %TRUE if @src is a validated source.
+ */
+gboolean
+rtp_source_is_validated (RTPSource * src)
+{
+  gboolean result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  result = src->validated;
+
+  return result;
+}
+
+/**
+ * rtp_source_is_sender:
+ * @src: an #RTPSource
+ *
+ * Check if @src is a sending source.
+ *
+ * Returns: %TRUE if @src is a sending source.
+ */
+gboolean
+rtp_source_is_sender (RTPSource * src)
+{
+  gboolean result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  result = RTP_SOURCE_IS_SENDER (src);
+
+  return result;
+}
+
+/**
+ * rtp_source_received_bye:
+ * @src: an #RTPSource
+ *
+ * Check if @src has receoved a BYE packet.
+ *
+ * Returns: %TRUE if @src has received a BYE packet.
+ */
+gboolean
+rtp_source_received_bye (RTPSource * src)
+{
+  gboolean result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  result = src->received_bye;
+
+  return result;
+}
+
+
+/**
+ * rtp_source_get_bye_reason:
+ * @src: an #RTPSource
+ *
+ * Get the BYE reason for @src. Check if the source receoved a BYE message first
+ * with rtp_source_received_bye().
+ *
+ * Returns: The BYE reason or NULL when no reason was given or the source did
+ * not receive a BYE message yet. g_fee() after usage.
+ */
+gchar *
+rtp_source_get_bye_reason (RTPSource * src)
+{
+  gchar *result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), NULL);
+
+  result = g_strdup (src->bye_reason);
+
+  return result;
+}
+
+/**
  * rtp_source_update_caps:
  * @src: an #RTPSource
  * @caps: a #GstCaps
@@ -153,37 +515,130 @@ rtp_source_update_caps (RTPSource * src, GstCaps * caps)
 }
 
 /**
- * rtp_source_set_callbacks:
+ * rtp_source_set_sdes:
  * @src: an #RTPSource
- * @cb: callback functions
- * @user_data: user data
+ * @type: the type of the SDES item
+ * @data: the SDES data
+ * @len: the SDES length
  *
- * Set the callbacks for the source.
+ * Store an SDES item of @type in @src. 
+ *
+ * Returns: %FALSE if the SDES item was unchanged or @type is unknown.
  */
-void
-rtp_source_set_callbacks (RTPSource * src, RTPSourceCallbacks * cb,
-    gpointer user_data)
+gboolean
+rtp_source_set_sdes (RTPSource * src, GstRTCPSDESType type,
+    const guint8 * data, guint len)
 {
-  g_return_if_fail (RTP_IS_SOURCE (src));
+  guint8 *old;
 
-  src->callbacks.push_rtp = cb->push_rtp;
-  src->callbacks.clock_rate = cb->clock_rate;
-  src->user_data = user_data;
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  if (type < 0 || type > GST_RTCP_SDES_PRIV)
+    return FALSE;
+
+  old = src->sdes[type];
+
+  /* lengths are the same, check if the data is the same */
+  if ((src->sdes_len[type] == len))
+    if (data != NULL && old != NULL && (memcmp (old, data, len) == 0))
+      return FALSE;
+
+  /* NULL data, make sure we store 0 length or if no length is given,
+   * take strlen */
+  if (data == NULL)
+    len = 0;
+
+  g_free (src->sdes[type]);
+  src->sdes[type] = g_memdup (data, len);
+  src->sdes_len[type] = len;
+
+  return TRUE;
 }
 
 /**
- * rtp_source_set_as_csrc:
+ * rtp_source_set_sdes_string:
  * @src: an #RTPSource
+ * @type: the type of the SDES item
+ * @data: the SDES data
+ *
+ * Store an SDES item of @type in @src. This function is similar to
+ * rtp_source_set_sdes() but takes a null-terminated string for convenience.
  *
- * Configure @src as a CSRC, this will validate the RTpSource.
+ * Returns: %FALSE if the SDES item was unchanged or @type is unknown.
  */
-void
-rtp_source_set_as_csrc (RTPSource * src)
+gboolean
+rtp_source_set_sdes_string (RTPSource * src, GstRTCPSDESType type,
+    const gchar * data)
 {
-  g_return_if_fail (RTP_IS_SOURCE (src));
+  guint len;
+  gboolean result;
 
-  src->validated = TRUE;
-  src->is_csrc = TRUE;
+  if (data)
+    len = strlen (data);
+  else
+    len = 0;
+
+  result = rtp_source_set_sdes (src, type, (guint8 *) data, len);
+
+  return result;
+}
+
+/**
+ * rtp_source_get_sdes:
+ * @src: an #RTPSource
+ * @type: the type of the SDES item
+ * @data: location to store the SDES data or NULL
+ * @len: location to store the SDES length or NULL
+ *
+ * Get the SDES item of @type from @src. Note that @data does not always point
+ * to a null-terminated string, use rtp_source_get_sdes_string() to retrieve a
+ * null-terminated string instead.
+ *
+ * @data remains valid until the next call to rtp_source_set_sdes().
+ *
+ * Returns: %TRUE if @type was valid and @data and @len contain valid
+ * data. 
+ */
+gboolean
+rtp_source_get_sdes (RTPSource * src, GstRTCPSDESType type, guint8 ** data,
+    guint * len)
+{
+  g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE);
+
+  if (type < 0 || type > GST_RTCP_SDES_PRIV)
+    return FALSE;
+
+  if (data)
+    *data = src->sdes[type];
+  if (len)
+    *len = src->sdes_len[type];
+
+  return TRUE;
+}
+
+/**
+ * rtp_source_get_sdes_string:
+ * @src: an #RTPSource
+ * @type: the type of the SDES item
+ *
+ * Get the SDES item of @type from @src. 
+ *
+ * Returns: a null-terminated copy of the SDES item or NULL when @type was not
+ * valid. g_free() after usage.
+ */
+gchar *
+rtp_source_get_sdes_string (RTPSource * src, GstRTCPSDESType type)
+{
+  gchar *result;
+
+  g_return_val_if_fail (RTP_IS_SOURCE (src), NULL);
+
+  if (type < 0 || type > GST_RTCP_SDES_PRIV)
+    return NULL;
+
+  result = g_strndup ((const gchar *) src->sdes[type], src->sdes_len[type]);
+
+  return result;
 }
 
 /**
@@ -588,7 +1043,7 @@ rtp_source_send_rtp (RTPSource * src, GstBuffer * buffer, guint64 ntpnstime)
  * rtp_source_process_sr:
  * @src: an #RTPSource
  * @time: time of packet arrival
- * @ntptime: the NTP time
+ * @ntptime: the NTP time in 32.32 fixed point
  * @rtptime: the RTP time
  * @packet_count: the packet count
  * @octet_count: the octect count
@@ -684,9 +1139,9 @@ rtp_source_process_rb (RTPSource * src, GstClockTime time, guint8 fractionlost,
 /**
  * rtp_source_get_new_sr:
  * @src: an #RTPSource
- * @time: the current time in nanoseconds since 1970
- * @ntptime: the NTP time
- * @rtptime: the RTP time
+ * @ntpnstime: the current time in nanoseconds since 1970
+ * @ntptime: the NTP time in 32.32 fixed point
+ * @rtptime: the RTP time corresponding to @ntptime
  * @packet_count: the packet count
  * @octet_count: the octect count
  *
@@ -695,7 +1150,7 @@ rtp_source_process_rb (RTPSource * src, GstClockTime time, guint8 fractionlost,
  * Returns: %TRUE on success.
  */
 gboolean
-rtp_source_get_new_sr (RTPSource * src, GstClockTime ntpnstime,
+rtp_source_get_new_sr (RTPSource * src, guint64 ntpnstime,
     guint64 * ntptime, guint32 * rtptime, guint32 * packet_count,
     guint32 * octet_count)
 {
@@ -757,7 +1212,7 @@ rtp_source_get_new_sr (RTPSource * src, GstClockTime ntpnstime,
 /**
  * rtp_source_get_new_rb:
  * @src: an #RTPSource
- * @time: the current time in nanoseconds since 1970
+ * @ntpnstime: the current time in nanoseconds since 1970
  * @fractionlost: fraction lost since last SR/RR
  * @packetslost: the cumululative number of packets lost
  * @exthighestseq: the extended last sequence number received
@@ -765,12 +1220,12 @@ rtp_source_get_new_sr (RTPSource * src, GstClockTime ntpnstime,
  * @lsr: the last SR packet from this source
  * @dlsr: the delay since last SR packet
  *
- * Get the values of the last RB report set with rtp_source_process_rb().
+ * Get new values to put into a new report block from this source.
  *
  * Returns: %TRUE on success.
  */
 gboolean
-rtp_source_get_new_rb (RTPSource * src, GstClockTime time,
+rtp_source_get_new_rb (RTPSource * src, guint64 ntpnstime,
     guint8 * fractionlost, gint32 * packetslost, guint32 * exthighestseq,
     guint32 * jitter, guint32 * lsr, guint32 * dlsr)
 {
@@ -816,7 +1271,7 @@ rtp_source_get_new_rb (RTPSource * src, GstClockTime time,
 
     /* LSR is middle 32 bits of the last ntptime */
     LSR = (ntptime >> 16) & 0xffffffff;
-    diff = time - sr_time;
+    diff = ntpnstime - sr_time;
     GST_DEBUG ("last SR time diff %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));
     /* DLSR, delay since last SR is expressed in 1/65536 second units */
     DLSR = gst_util_uint64_scale_int (diff, 65536, GST_SECOND);
@@ -849,7 +1304,7 @@ rtp_source_get_new_rb (RTPSource * src, GstClockTime time,
  * rtp_source_get_last_sr:
  * @src: an #RTPSource
  * @time: time of packet arrival
- * @ntptime: the NTP time
+ * @ntptime: the NTP time in 32.32 fixed point
  * @rtptime: the RTP time
  * @packet_count: the packet count
  * @octet_count: the octect count
index 1952a4c..0a744df 100644 (file)
@@ -118,13 +118,9 @@ struct _RTPSource {
   gboolean      is_csrc;
   gboolean      is_sender;
 
-  gchar        *cname;
-  gchar        *name;
-  gchar        *email;
-  gchar        *phone;
-  gchar        *location;
-  gchar        *tool;
-  gchar        *note;
+  guint8       *sdes[9];
+  guint         sdes_len[9];
+
   gboolean      received_bye;
   gchar        *bye_reason;
 
@@ -161,38 +157,62 @@ struct _RTPSourceClass {
 GType rtp_source_get_type (void);
 
 /* managing lifetime of sources */
-RTPSource*      rtp_source_new            (guint32 ssrc);
-void            rtp_source_update_caps    (RTPSource *src, GstCaps *caps);
+RTPSource*      rtp_source_new                 (guint32 ssrc);
+void            rtp_source_set_callbacks       (RTPSource *src, RTPSourceCallbacks *cb, gpointer data);
+
+/* properties */
+guint32         rtp_source_get_ssrc            (RTPSource *src);
+
+void            rtp_source_set_as_csrc         (RTPSource *src);
+gboolean        rtp_source_is_as_csrc          (RTPSource *src);
+
+gboolean        rtp_source_is_active           (RTPSource *src);
+gboolean        rtp_source_is_validated        (RTPSource *src);
+gboolean        rtp_source_is_sender           (RTPSource *src);
+
+gboolean        rtp_source_received_bye        (RTPSource *src);
+gchar *         rtp_source_get_bye_reason      (RTPSource *src);
+
+void            rtp_source_update_caps         (RTPSource *src, GstCaps *caps);
 
-void            rtp_source_set_callbacks  (RTPSource *src, RTPSourceCallbacks *cb, gpointer data);
-void            rtp_source_set_as_csrc    (RTPSource *src);
+/* SDES info */
+gboolean        rtp_source_set_sdes            (RTPSource *src, GstRTCPSDESType type, 
+                                                const guint8 *data, guint len);
+gboolean        rtp_source_set_sdes_string     (RTPSource *src, GstRTCPSDESType type,
+                                                const gchar *data);
+gboolean        rtp_source_get_sdes            (RTPSource *src, GstRTCPSDESType type,
+                                                guint8 **data, guint *len);
+gchar*          rtp_source_get_sdes_string     (RTPSource *src, GstRTCPSDESType type);
 
-void            rtp_source_set_rtp_from   (RTPSource *src, GstNetAddress *address);
-void            rtp_source_set_rtcp_from  (RTPSource *src, GstNetAddress *address);
+/* handling network address */
+void            rtp_source_set_rtp_from        (RTPSource *src, GstNetAddress *address);
+void            rtp_source_set_rtcp_from       (RTPSource *src, GstNetAddress *address);
 
 /* handling RTP */
-GstFlowReturn   rtp_source_process_rtp    (RTPSource *src, GstBuffer *buffer, RTPArrivalStats *arrival);
+GstFlowReturn   rtp_source_process_rtp         (RTPSource *src, GstBuffer *buffer, RTPArrivalStats *arrival);
 
-GstFlowReturn   rtp_source_send_rtp       (RTPSource *src, GstBuffer *buffer, guint64 ntpnstime);
+GstFlowReturn   rtp_source_send_rtp            (RTPSource *src, GstBuffer *buffer, guint64 ntpnstime);
 
 /* RTCP messages */
-void            rtp_source_process_bye    (RTPSource *src, const gchar *reason);
-void            rtp_source_process_sr     (RTPSource *src, GstClockTime time, guint64 ntptime,
-                                           guint32 rtptime, guint32 packet_count, guint32 octet_count);
-void            rtp_source_process_rb     (RTPSource *src, GstClockTime time, guint8 fractionlost,
-                                           gint32 packetslost, guint32 exthighestseq, guint32 jitter,
-                                           guint32 lsr, guint32 dlsr);
-
-gboolean        rtp_source_get_new_sr     (RTPSource *src, GstClockTime time, guint64 *ntptime,
-                                          guint32 *rtptime, guint32 *packet_count, guint32 *octet_count);
-gboolean        rtp_source_get_new_rb     (RTPSource *src, GstClockTime time, guint8 *fractionlost,
-                                           gint32 *packetslost, guint32 *exthighestseq, guint32 *jitter,
-                                           guint32 *lsr, guint32 *dlsr);
-
-gboolean        rtp_source_get_last_sr    (RTPSource *src, GstClockTime *time, guint64 *ntptime,
-                                           guint32 *rtptime, guint32 *packet_count, guint32 *octet_count);
-gboolean        rtp_source_get_last_rb    (RTPSource *src, guint8 *fractionlost, gint32 *packetslost,
-                                           guint32 *exthighestseq, guint32 *jitter,
-                                           guint32 *lsr, guint32 *dlsr);
+void            rtp_source_process_bye         (RTPSource *src, const gchar *reason);
+void            rtp_source_process_sr          (RTPSource *src, GstClockTime time, guint64 ntptime,
+                                                guint32 rtptime, guint32 packet_count, guint32 octet_count);
+void            rtp_source_process_rb          (RTPSource *src, GstClockTime time, guint8 fractionlost,
+                                                gint32 packetslost, guint32 exthighestseq, guint32 jitter,
+                                                guint32 lsr, guint32 dlsr);
+
+gboolean        rtp_source_get_new_sr          (RTPSource *src, GstClockTime time, guint64 *ntptime,
+                                               guint32 *rtptime, guint32 *packet_count,
+                                               guint32 *octet_count);
+gboolean        rtp_source_get_new_rb          (RTPSource *src, GstClockTime time, guint8 *fractionlost,
+                                                gint32 *packetslost, guint32 *exthighestseq, guint32 *jitter,
+                                                guint32 *lsr, guint32 *dlsr);
+
+gboolean        rtp_source_get_last_sr         (RTPSource *src, GstClockTime *time, guint64 *ntptime,
+                                                guint32 *rtptime, guint32 *packet_count,
+                                               guint32 *octet_count);
+gboolean        rtp_source_get_last_rb         (RTPSource *src, guint8 *fractionlost, gint32 *packetslost,
+                                                guint32 *exthighestseq, guint32 *jitter,
+                                                guint32 *lsr, guint32 *dlsr);
 
 #endif /* __RTP_SOURCE_H__ */