rtpsink: set properties on children early
authorMarc Leeman <m.leeman@televic.com>
Tue, 30 Nov 2021 09:24:37 +0000 (10:24 +0100)
committerMarc Leeman <m.leeman@televic.com>
Thu, 2 Dec 2021 13:23:05 +0000 (14:23 +0100)
The properties on the udpsink/udpsrc elements need to be set before
there is any state change. If not, in a network without default gateway,
udpsink tries to bind an a NULL interface and fails.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1398>

subprojects/gst-plugins-bad/gst/rtp/gstrtpsink.c

index 1695e7cd5e3048a0a2fd9b5ae5df588c63e70914..c4e43a4263c834c343562994b90835887adbd262 100644 (file)
@@ -444,9 +444,30 @@ gst_rtp_sink_rtpbin_pad_removed_cb (GstElement * element, GstPad * pad,
 }
 
 static gboolean
-gst_rtp_sink_start (GstRtpSink * self)
+gst_rtp_sink_reuse_socket (GstRtpSink * self)
 {
   GSocket *socket = NULL;
+
+  gst_element_set_locked_state (self->rtcp_src, FALSE);
+  gst_element_sync_state_with_parent (self->rtcp_src);
+
+  /* share the socket created by the sink */
+  g_object_get (self->rtcp_src, "used-socket", &socket, NULL);
+  g_object_set (self->rtcp_sink, "socket", socket, "auto-multicast", FALSE,
+      "close-socket", FALSE, NULL);
+  g_object_unref (socket);
+
+  g_object_set (self->rtcp_sink, "sync", FALSE, "async", FALSE, NULL);
+  gst_element_set_locked_state (self->rtcp_sink, FALSE);
+  gst_element_sync_state_with_parent (self->rtcp_sink);
+
+  return TRUE;
+
+}
+
+static gboolean
+gst_rtp_sink_start (GstRtpSink * self)
+{
   GInetAddress *iaddr = NULL;
   gchar *remote_addr = NULL;
   GError *error = NULL;
@@ -497,19 +518,6 @@ gst_rtp_sink_start (GstRtpSink * self)
   g_free (remote_addr);
   g_object_unref (iaddr);
 
-  gst_element_set_locked_state (self->rtcp_src, FALSE);
-  gst_element_sync_state_with_parent (self->rtcp_src);
-
-  /* share the socket created by the sink */
-  g_object_get (self->rtcp_src, "used-socket", &socket, NULL);
-  g_object_set (self->rtcp_sink, "socket", socket, "auto-multicast", FALSE,
-      "close-socket", FALSE, NULL);
-  g_object_unref (socket);
-
-  g_object_set (self->rtcp_sink, "sync", FALSE, "async", FALSE, NULL);
-  gst_element_set_locked_state (self->rtcp_sink, FALSE);
-  gst_element_sync_state_with_parent (self->rtcp_sink);
-
   return TRUE;
 
 dns_resolve_failed:
@@ -532,6 +540,10 @@ gst_rtp_sink_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
+      /* Set the properties to the child elements to avoid binding to
+       * a NULL interface on a network without a default gateway */
+      if (gst_rtp_sink_start (self) == FALSE)
+        return GST_STATE_CHANGE_FAILURE;
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       break;
@@ -545,7 +557,8 @@ gst_rtp_sink_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-      if (gst_rtp_sink_start (self) == FALSE)
+      /* re-use the sockets after they have been initialised */
+      if (gst_rtp_sink_reuse_socket (self) == FALSE)
         return GST_STATE_CHANGE_FAILURE;
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED: