ristsink: set properties on children early

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>
This commit is contained in:
Marc Leeman 2021-12-02 15:52:06 +01:00 committed by GStreamer Marge Bot
parent 7e875ddb2c
commit 49736fb3fd

View file

@ -709,11 +709,38 @@ dns_resolve_failed:
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;
} }
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 static GstStateChangeReturn
gst_rist_sink_start (GstRistSink * sink) gst_rist_sink_start (GstRistSink * sink)
{ {
GstPad *rtxbin_gpad, *rtpext_sinkpad; GstPad *rtxbin_gpad, *rtpext_sinkpad;
gint i;
/* Unless a custom dispatcher was provided, use the specified bonding method /* Unless a custom dispatcher was provided, use the specified bonding method
* to create one */ * to create one */
@ -750,26 +777,6 @@ gst_rist_sink_start (GstRistSink * sink)
gst_bin_add (GST_BIN (sink->rtxbin), sink->dispatcher); gst_bin_add (GST_BIN (sink->rtxbin), sink->dispatcher);
gst_element_link (sink->rtpext, 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; return GST_STATE_CHANGE_SUCCESS;
} }
@ -897,6 +904,11 @@ gst_rist_sink_change_state (GstElement * element, GstStateChange transition)
GstStateChangeReturn ret; GstStateChangeReturn ret;
switch (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_rist_sink_start (sink) == GST_STATE_CHANGE_FAILURE)
return GST_STATE_CHANGE_FAILURE;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_rist_sink_disable_stats_interval (sink); gst_rist_sink_disable_stats_interval (sink);
break; break;
@ -909,7 +921,7 @@ gst_rist_sink_change_state (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
ret = gst_rist_sink_start (sink); ret = gst_rist_sink_reuse_socket (sink);
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_rist_sink_enable_stats_interval (sink); gst_rist_sink_enable_stats_interval (sink);