ristsink: set properties on children early
authorMarc Leeman <m.leeman@televic.com>
Thu, 2 Dec 2021 14:52:06 +0000 (15:52 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 3 Dec 2021 23:46:08 +0000 (23:46 +0000)
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/1411>

subprojects/gst-plugins-bad/gst/rist/gstristsink.c

index 98acd65..009f1ae 100644 (file)
@@ -710,10 +710,37 @@ dns_resolve_failed:
 }
 
 static GstStateChangeReturn
+gst_rist_sink_reuse_socket (GstRistSink * sink)
+{
+  gint i;
+
+  for (i = 0; i < sink->bonds->len; i++) {
+    RistSenderBond *bond = g_ptr_array_index (sink->bonds, i);
+    GObject *session = NULL;
+    GstPad *pad;
+    gchar name[32];
+
+    g_signal_emit_by_name (sink->rtpbin, "get-session", i, &session);
+    g_object_set (session, "rtcp-min-interval", sink->min_rtcp_interval,
+        "rtcp-fraction", sink->max_rtcp_bandwidth, NULL);
+    g_object_unref (session);
+
+    g_snprintf (name, 32, "src_%u", bond->session);
+    pad = gst_element_request_pad_simple (sink->dispatcher, name);
+    gst_element_link_pads (sink->dispatcher, name, bond->rtx_queue, "sink");
+    gst_object_unref (pad);
+
+    if (!gst_rist_sink_setup_rtcp_socket (sink, bond))
+      return GST_STATE_CHANGE_FAILURE;
+  }
+
+  return GST_STATE_CHANGE_SUCCESS;
+}
+
+static GstStateChangeReturn
 gst_rist_sink_start (GstRistSink * sink)
 {
   GstPad *rtxbin_gpad, *rtpext_sinkpad;
-  gint i;
 
   /* Unless a custom dispatcher was provided, use the specified bonding method
    * to create one */
@@ -750,26 +777,6 @@ gst_rist_sink_start (GstRistSink * sink)
   gst_bin_add (GST_BIN (sink->rtxbin), sink->dispatcher);
   gst_element_link (sink->rtpext, sink->dispatcher);
 
-  for (i = 0; i < sink->bonds->len; i++) {
-    RistSenderBond *bond = g_ptr_array_index (sink->bonds, i);
-    GObject *session = NULL;
-    GstPad *pad;
-    gchar name[32];
-
-    g_signal_emit_by_name (sink->rtpbin, "get-session", i, &session);
-    g_object_set (session, "rtcp-min-interval", sink->min_rtcp_interval,
-        "rtcp-fraction", sink->max_rtcp_bandwidth, NULL);
-    g_object_unref (session);
-
-    g_snprintf (name, 32, "src_%u", bond->session);
-    pad = gst_element_request_pad_simple (sink->dispatcher, name);
-    gst_element_link_pads (sink->dispatcher, name, bond->rtx_queue, "sink");
-    gst_object_unref (pad);
-
-    if (!gst_rist_sink_setup_rtcp_socket (sink, bond))
-      return GST_STATE_CHANGE_FAILURE;
-  }
-
   return GST_STATE_CHANGE_SUCCESS;
 }
 
@@ -897,6 +904,11 @@ gst_rist_sink_change_state (GstElement * element, GstStateChange transition)
   GstStateChangeReturn ret;
 
   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_rist_sink_start (sink) == GST_STATE_CHANGE_FAILURE)
+        return GST_STATE_CHANGE_FAILURE;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       gst_rist_sink_disable_stats_interval (sink);
       break;
@@ -909,7 +921,7 @@ gst_rist_sink_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-      ret = gst_rist_sink_start (sink);
+      ret = gst_rist_sink_reuse_socket (sink);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       gst_rist_sink_enable_stats_interval (sink);