[calls] sip: media-pipeline: Setup socket reuse for RTP and RTCP during initialization



commit 0e3a07aabf95708085a2e2fec4942dba632de08e
Author: Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
Date:   Mon Feb 28 22:04:23 2022 +0100

    sip: media-pipeline: Setup socket reuse for RTP and RTCP during initialization
    
    Now that initialization is split per pipeline and that the OS handles port
    allocation we can move setting up socket reuse into the pipeline initialization
    step instead of setting it up when starting the media pipelines.
    
    This makes the calls_sip_media_pipeline_start() method a bit simpler.
    
    We're also now reusing sockets for RTCP.
    
    Closes #315

 plugins/sip/calls-sip-media-pipeline.c | 78 ++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 18 deletions(-)
---
diff --git a/plugins/sip/calls-sip-media-pipeline.c b/plugins/sip/calls-sip-media-pipeline.c
index 9c740b84..78dc4cb9 100644
--- a/plugins/sip/calls-sip-media-pipeline.c
+++ b/plugins/sip/calls-sip-media-pipeline.c
@@ -457,6 +457,8 @@ static gboolean
 send_pipeline_init (CallsSipMediaPipeline *self,
                     GError               **error)
 {
+  g_autoptr (GSocket) rtp_sock = NULL;
+  g_autoptr (GSocket) rtcp_sock = NULL;
   const char *env_var;
 
   g_assert (CALLS_SIP_MEDIA_PIPELINE (self));
@@ -518,7 +520,36 @@ send_pipeline_init (CallsSipMediaPipeline *self,
                           self->rtcp_send_sink, "host",
                           G_BINDING_BIDIRECTIONAL);
 
-  /* TODO bind sockets */
+  /* bind sockets for hole punching scheme */
+  g_object_get (self->rtp_src, "used-socket", &rtp_sock, NULL);
+  if (!rtp_sock) {
+    if (error)
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Could not retrieve used socket from RTP udpsrc element");
+    return FALSE;
+  }
+
+  g_object_set (self->rtp_sink,
+                "socket", rtp_sock,
+                "close-socket", FALSE,
+                NULL);
+
+
+  g_object_get (self->rtcp_recv_src, "used-socket", &rtcp_sock, NULL);
+  if (!rtcp_sock) {
+    if (error)
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Could not retrieve used socket from RTCP udpsrc element");
+    return FALSE;
+  }
+  g_object_set (self->rtcp_send_sink,
+                "socket", rtcp_sock,
+                "close-socket", FALSE,
+                NULL);
+  g_object_set (self->rtcp_send_src,
+                "socket", rtcp_sock,
+                "close-socket", FALSE,
+                NULL);
 
   gst_bin_add (GST_BIN (self->send_pipeline), self->send_rtpbin);
   gst_bin_add_many (GST_BIN (self->send_pipeline), self->rtp_sink,
@@ -645,6 +676,7 @@ static gboolean
 recv_pipeline_init (CallsSipMediaPipeline *self,
                     GError               **error)
 {
+  g_autoptr (GSocket) rtcp_sock = NULL;
   const char *env_var;
 
   g_assert (CALLS_SIP_MEDIA_PIPELINE (self));
@@ -712,9 +744,32 @@ recv_pipeline_init (CallsSipMediaPipeline *self,
   self->bus_recv = gst_pipeline_get_bus (GST_PIPELINE (self->recv_pipeline));
   self->bus_watch_recv = gst_bus_add_watch (self->bus_recv, on_bus_message, self);
 
+  g_object_set (self->rtp_src,
+                "close-socket", FALSE,
+                "reuse", TRUE,
+                NULL);
+  g_object_set (self->rtcp_recv_src,
+                "close-socket", FALSE,
+                "reuse", TRUE,
+                NULL);
+
   /* Set pipeline to ready to get ports allocated */
   gst_element_set_state (self->recv_pipeline, GST_STATE_READY);
 
+  g_object_get (self->rtcp_recv_src, "used-socket", &rtcp_sock, NULL);
+  if (!rtcp_sock) {
+    if (error)
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Could not retrieve used socket from RTCP udpsrc element");
+    return FALSE;
+  }
+
+  /* Ports are allocated. Let's reuse the socket for rtcp source in the sink for NAT traversal*/
+  g_object_set (self->rtcp_recv_sink,
+                "socket", rtcp_sock,
+                "close-socket", FALSE,
+                NULL);
+
   return TRUE;
 }
 
@@ -1036,7 +1091,6 @@ diagnose_ports_in_use (CallsSipMediaPipeline *self)
 void
 calls_sip_media_pipeline_start (CallsSipMediaPipeline *self)
 {
-  GSocket *socket;
   g_return_if_fail (CALLS_IS_SIP_MEDIA_PIPELINE (self));
 
   if (self->state != CALLS_MEDIA_PIPELINE_STATE_READY) {
@@ -1046,25 +1100,13 @@ calls_sip_media_pipeline_start (CallsSipMediaPipeline *self)
 
   g_debug ("Starting media pipeline");
 
-  /* First start the receiver pipeline so that
-     we may reuse the socket in the sender pipeline */
-  /* TODO can we do something similar for RTCP? */
   gst_element_set_state (self->recv_pipeline, GST_STATE_PLAYING);
-
-  g_object_get (self->rtp_src, "used-socket", &socket, NULL);
-
-  if (socket) {
-    g_object_set (self->rtp_sink,
-                  "close-socket", FALSE,
-                  "socket", socket,
-                  NULL);
-  }
-  else
-    g_warning ("Could not get used socket of udpsrc element");
-
-  /* Now start the sender pipeline */
   gst_element_set_state (self->send_pipeline, GST_STATE_PLAYING);
 
+  g_debug ("RTP/RTCP port after starting pipeline: %d/%d",
+           calls_sip_media_pipeline_get_rtp_port (self),
+           calls_sip_media_pipeline_get_rtcp_port (self));
+
   set_state (self, CALLS_MEDIA_PIPELINE_STATE_PLAY_PENDING);
 
   if (self->debug)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]