diff options
-rw-r--r-- | gst/rtsp-server/rtsp-sdp.c | 90 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-stream.c | 26 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-stream.h | 2 |
3 files changed, 114 insertions, 4 deletions
diff --git a/gst/rtsp-server/rtsp-sdp.c b/gst/rtsp-server/rtsp-sdp.c index 348cab3..b5a789b 100644 --- a/gst/rtsp-server/rtsp-sdp.c +++ b/gst/rtsp-server/rtsp-sdp.c @@ -16,6 +16,9 @@ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ + +#define GLIB_DISABLE_DEPRECATION_WARNINGS + /** * SECTION:rtsp-sdp * @short_description: Make SDP messages @@ -73,6 +76,87 @@ update_sdp_from_tags (GstRTSPStream * stream, GstSDPMedia * stream_media) gst_object_unref (src_pad); } +static guint +get_roc_from_stats (GstStructure * stats, guint ssrc) +{ + const GValue *va, *v; + guint i, len, roc = 0; + + va = gst_structure_get_value (stats, "streams"); + if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY)) { + GST_WARNING ("stats doesn't have a valid 'streams' field"); + return 0; + } + + len = gst_value_array_get_size (va); + + /* Look if there's any SSRC that matches. */ + for (i = 0; i < len; i++) { + GstStructure *stream; + v = gst_value_array_get_value (va, i); + if (v && (stream = g_value_get_boxed (v))) { + guint stream_ssrc; + gst_structure_get_uint (stream, "ssrc", &stream_ssrc); + if (stream_ssrc == ssrc) { + gst_structure_get_uint (stream, "roc", &roc); + break; + } + } + } + + return roc; +} + +static void +mikey_add_crypto_sessions (GstRTSPStream * stream, GstMIKEYMessage * msg) +{ + guint i; + GObject *session; + GstElement *encoder; + GValueArray *sources; + + session = gst_rtsp_stream_get_rtpsession (stream); + if (session == NULL) + return; + + encoder = gst_rtsp_stream_get_srtp_encoder (stream); + if (encoder == NULL) { + g_object_unref (session); + return; + } + + g_object_get (session, "sources", &sources, NULL); + for (i = 0; i < sources->n_values; i++) { + GValue *val; + GObject *source; + guint32 ssrc; + gboolean is_sender; + + val = g_value_array_get_nth (sources, i); + source = (GObject *) g_value_get_object (val); + + g_object_get (source, "ssrc", &ssrc, "is-sender", &is_sender, NULL); + + if (is_sender) { + guint32 roc = 0; + GstStructure *stats; + + g_object_get (encoder, "stats", &stats, NULL); + + if (stats) { + roc = get_roc_from_stats (stats, ssrc); + gst_structure_free (stats); + } + + gst_mikey_message_add_cs_srtp (msg, 0, ssrc, roc); + } + } + g_value_array_free (sources); + + gst_object_unref (encoder); + g_object_unref (session); +} + static void make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile) @@ -86,7 +170,6 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info, guint ttl; GstClockTime rtx_time; gchar *base64; - guint32 ssrc; GstMIKEYMessage *mikey_msg; gst_sdp_media_new (&smedia); @@ -155,9 +238,8 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info, /* check for srtp */ mikey_msg = gst_mikey_message_new_from_caps (caps); if (mikey_msg) { - gst_rtsp_stream_get_ssrc (stream, &ssrc); - /* add policy '0' for our SSRC */ - gst_mikey_message_add_cs_srtp (mikey_msg, 0, ssrc, 0); + /* add policy '0' for all sending SSRC */ + mikey_add_crypto_sessions (stream, mikey_msg); base64 = gst_mikey_message_base64_encode (mikey_msg); if (base64) { diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c index 27ad5ac..5389456 100644 --- a/gst/rtsp-server/rtsp-stream.c +++ b/gst/rtsp-server/rtsp-stream.c @@ -1672,6 +1672,32 @@ gst_rtsp_stream_get_rtpsession (GstRTSPStream * stream) } /** + * gst_rtsp_stream_get_encoder: + * @stream: a #GstRTSPStream + * + * Get the SRTP encoder for this stream. + * + * Returns: (transfer full): The SRTP encoder for this stream. Unref after usage. + */ +GstElement * +gst_rtsp_stream_get_srtp_encoder (GstRTSPStream * stream) +{ + GstRTSPStreamPrivate *priv; + GstElement *encoder; + + g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL); + + priv = stream->priv; + + g_mutex_lock (&priv->lock); + if ((encoder = priv->srtpenc)) + g_object_ref (encoder); + g_mutex_unlock (&priv->lock); + + return encoder; +} + +/** * gst_rtsp_stream_get_ssrc: * @stream: a #GstRTSPStream * @ssrc: (out): result ssrc diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h index a6ab1ff..9ef887a 100644 --- a/gst/rtsp-server/rtsp-stream.h +++ b/gst/rtsp-server/rtsp-stream.h @@ -129,6 +129,8 @@ GstRTSPAddress * gst_rtsp_stream_get_multicast_address (GstRTSPStream *stream, GObject * gst_rtsp_stream_get_rtpsession (GstRTSPStream *stream); +GstElement * gst_rtsp_stream_get_srtp_encoder (GstRTSPStream *stream); + void gst_rtsp_stream_get_ssrc (GstRTSPStream *stream, guint *ssrc); |