[calls] sip: media-pipeline: Fix socket reuse



commit 605776641d68271da6f1d498c1204a2a480d35de
Author: Evangelos Ribeiro Tzaras <devrtz fortysixandtwo eu>
Date:   Fri Apr 22 17:46:50 2022 +0200

    sip: media-pipeline: Fix socket reuse
    
    We were using two distinct pipelines, one for receiving and one for
    sending. The receive pipeline was set to the playing state to allocate
    the sockets which we would reuse for the sending direction for our NAT
    traversal scheme.
    
    The rework to a single pipeline broke reusing sockets subtly.
    
    This happened because the state of the GstUDPSrc could be reset leading
    to newly allocated sockets once the pipeline is set to play.
    
    This is now fixed by locking the state of the GstUDPSrc in the ready
    state during socket reuse setup and while the pipeline is paused.
    
    Additionally get rid of the "close-socket" property on the udp sources
    because it was never needed.
    
    Fixes aa446f82
    
    sq

 plugins/sip/calls-sip-media-pipeline.c | 48 ++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 17 deletions(-)
---
diff --git a/plugins/sip/calls-sip-media-pipeline.c b/plugins/sip/calls-sip-media-pipeline.c
index eb97bf92..5532dfd9 100644
--- a/plugins/sip/calls-sip-media-pipeline.c
+++ b/plugins/sip/calls-sip-media-pipeline.c
@@ -370,8 +370,9 @@ setup_socket_reuse (CallsSipMediaPipeline *self,
   g_autoptr (GSocket) rtp_sock = NULL;
   g_autoptr (GSocket) rtcp_sock = NULL;
 
-  /* Set udp sources to ready to get ports allocated */
-  gst_element_set_state (self->pipeline, GST_STATE_READY);
+  /* set rtp element ready and lock it's state so it doesn't get stopped */
+  gst_element_set_locked_state (self->rtp_src, TRUE);
+  gst_element_set_state (self->rtp_src, GST_STATE_READY);
 
   g_object_get (self->rtp_src, "used-socket", &rtp_sock, NULL);
   if (!rtp_sock) {
@@ -381,6 +382,16 @@ setup_socket_reuse (CallsSipMediaPipeline *self,
     return FALSE;
   }
 
+  /* configure socket and don't close it, since it belongs to rtp_src */
+  g_object_set (self->rtp_sink,
+                "socket", rtp_sock,
+                "close-socket", FALSE,
+                NULL);
+
+  /* set rtcp element ready and lock it's state so it doesn't get stopped */
+  gst_element_set_locked_state (self->rtcp_src, TRUE);
+  gst_element_set_state (self->rtcp_src, GST_STATE_READY);
+
   g_object_get (self->rtcp_src, "used-socket", &rtcp_sock, NULL);
   if (!rtcp_sock) {
     if (error)
@@ -389,12 +400,8 @@ setup_socket_reuse (CallsSipMediaPipeline *self,
     return FALSE;
   }
 
-  /* Ports are allocated. Let's reuse the socket for rtcp source in the sink for NAT traversal*/
-  g_object_set (self->rtp_sink,
-                "socket", rtp_sock,
-                "close-socket", FALSE,
-                NULL);
 
+  /* configure socket and don't close it, since it belongs to rtcp_src */
   g_object_set (self->rtcp_sink,
                 "socket", rtcp_sock,
                 "close-socket", FALSE,
@@ -478,17 +485,9 @@ pipeline_init (CallsSipMediaPipeline *self,
   MAKE_ELEMENT (rtcp_sink, "udpsink", "rtcp-udp-sink");
 
   /* port 0 means letting the OS allocate */
-  g_object_set (self->rtp_src,
-                "port", 0,
-                "close-socket", FALSE,
-                "reuse", TRUE,
-                NULL);
+  g_object_set (self->rtp_src, "port", 0, NULL);
 
-  g_object_set (self->rtcp_src,
-                "port", 0,
-                "close-socket", FALSE,
-                "reuse", TRUE,
-                NULL);
+  g_object_set (self->rtcp_src, "port", 0, NULL);
 
   g_object_set (self->rtp_sink, "async", FALSE, "sync", FALSE, NULL);
   g_object_set (self->rtcp_sink, "async", FALSE, "sync", FALSE, NULL);
@@ -993,6 +992,10 @@ calls_sip_media_pipeline_start (CallsSipMediaPipeline *self)
            calls_sip_media_pipeline_get_rtp_port (self),
            calls_sip_media_pipeline_get_rtcp_port (self));
 
+  /* unlock the state of our udp sources, see setup_socket_reuse() */
+  gst_element_set_locked_state (self->rtp_src, FALSE);
+  gst_element_set_locked_state (self->rtcp_src, FALSE);
+
   gst_element_set_state (self->pipeline, GST_STATE_PLAYING);
 
   g_debug ("RTP/RTCP port after starting pipeline: %d/%d",
@@ -1013,6 +1016,11 @@ calls_sip_media_pipeline_stop (CallsSipMediaPipeline *self)
 
   g_debug ("Stopping media pipeline");
 
+  gst_element_set_locked_state (self->rtp_src, FALSE);
+  gst_element_set_locked_state (self->rtcp_src, FALSE);
+  gst_element_set_locked_state (self->rtp_sink, FALSE);
+  gst_element_set_locked_state (self->rtcp_sink, FALSE);
+
   gst_element_set_state (self->pipeline, GST_STATE_NULL);
 
   set_state (self, CALLS_MEDIA_PIPELINE_STATE_STOP_PENDING);
@@ -1048,6 +1056,12 @@ calls_sip_media_pipeline_pause (CallsSipMediaPipeline *self,
            "Unpausing");
 
 
+  /* leave udpsrc running to prevent timeouts */
+  gst_element_set_locked_state (self->rtp_src, pause);
+  gst_element_set_locked_state (self->rtcp_src, pause);
+  gst_element_set_locked_state (self->rtp_sink, pause);
+  gst_element_set_locked_state (self->rtcp_sink, pause);
+
   gst_element_set_state (self->pipeline, pause ?
                          GST_STATE_PAUSED :
                          GST_STATE_PLAYING);


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