Merge branch 'srtsrc-port-allocation' into 'main'

srt: Introduce port allocation

See merge request gstreamer/gstreamer!5320
This commit is contained in:
Jonas Danielsson 2024-05-03 20:30:27 +00:00
commit bf69ebe47e
5 changed files with 90 additions and 20 deletions

View file

@ -238791,7 +238791,7 @@
"writable": true
},
"localport": {
"blurb": "Local port to bind",
"blurb": "Local port to bind (0 = allocate)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
@ -239051,7 +239051,7 @@
"writable": true
},
"localport": {
"blurb": "Local port to bind",
"blurb": "Local port to bind (0 = allocate)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
@ -239347,7 +239347,7 @@
"writable": true
},
"localport": {
"blurb": "Local port to bind",
"blurb": "Local port to bind (0 = allocate)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
@ -239596,7 +239596,7 @@
"writable": true
},
"localport": {
"blurb": "Local port to bind",
"blurb": "Local port to bind (0 = allocate)",
"conditionally-available": false,
"construct": false,
"construct-only": false,

View file

@ -617,7 +617,7 @@ gst_srt_object_install_properties_helper (GObjectClass * gobject_class)
*/
g_object_class_install_property (gobject_class, PROP_LOCALPORT,
g_param_spec_uint ("localport", "Local port",
"Local port to bind", 0,
"Local port to bind (0 = allocate)", 0,
65535, GST_SRT_DEFAULT_PORT,
G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
G_PARAM_STATIC_STRINGS));
@ -1378,7 +1378,9 @@ gst_srt_object_open_internal (GstSRTObject * srtobject, GError ** error)
" setting listener mode", addr_str);
}
port = gst_uri_get_port (srtobject->uri);
if (!gst_structure_get_uint (srtobject->parameters, "localport", &port)) {
port = gst_uri_get_port (srtobject->uri);
}
GST_DEBUG_OBJECT (srtobject->element,
"Opening SRT socket with parameters: %" GST_PTR_FORMAT,
@ -1405,6 +1407,24 @@ gst_srt_object_open_internal (GstSRTObject * srtobject, GError ** error)
gst_srt_object_connect (srtobject, connection_mode, sa, sa_len, error);
}
if (ret && port == 0) {
struct sockaddr_in addr;
socklen_t len;
len = sizeof (addr);
if (srt_getsockname (srtobject->sock, (struct sockaddr *) &addr,
(int *) &len) < 0) {
ret = FALSE;
g_set_error (error, GST_RESOURCE_ERROR,
GST_RESOURCE_ERROR_OPEN_READ_WRITE,
"Could not retrieve allocated port");
}
gst_structure_set (srtobject->parameters, "localport",
G_TYPE_UINT, (guint) g_ntohs (addr.sin_port), NULL);
GST_DEBUG_OBJECT (srtobject->element, "localport bound to %d",
g_ntohs (addr.sin_port));
}
out:
g_clear_object (&socket_address);

View file

@ -26,6 +26,11 @@
* srtsink is a network sink that sends [SRT](http://www.srtalliance.org/)
* packets to the network.
*
* When in listener or rendezvouz mode the srtsink element supports automatic
* port allocation. This can be achieved by setting the #GstSRTSink:localport
* property to 0. After setting the srtsink to PAUSED, the allocated port can
* be obtained by reading the #GstSRTSink:localport property.
*
* ## Examples</title>
*
* |[

View file

@ -26,6 +26,11 @@
* srtsrc is a network source that reads [SRT](http://www.srtalliance.org/)
* packets from the network.
*
* When in listener or rendezvouz mode the srtsrc element supports automatic
* port allocation. This can be achieved by setting the #GstSRTSrc:localport
* property to 0. After setting the srtsrc to PAUSED, the allocated port can
* be obtained by reading the #GstSRTSrc:localport property.
*
* ## Examples
* |[
* gst-launch-1.0 -v srtsrc uri="srt://127.0.0.1:7001" ! fakesink

View file

@ -24,26 +24,16 @@
static const gchar elements[][8] = { "srtsrc", "srtsink" };
static void
check_play (const gchar * src_uri,
check_play (GstHarness * h_src,
GstSRTConnectionMode src_mode,
const gchar * sink_uri, GstSRTConnectionMode sink_mode)
GstHarness * h_sink, GstSRTConnectionMode sink_mode)
{
GstHarness *h_src, *h_sink;
GstStructure *stats;
gint64 packets_received;
GstBuffer *in_buf, *out_buf;
gchar *src_launchline, *sink_launchline;
GstElement *src_element;
guint8 data[1316] = { 0 };
sink_launchline = g_strdup_printf ("srtsink uri=%s", sink_uri);
h_sink = gst_harness_new_parse (sink_launchline);
g_free (sink_launchline);
src_launchline = g_strdup_printf ("srtsrc name=src uri=%s", src_uri);
h_src = gst_harness_new_parse (src_launchline);
g_free (src_launchline);
gst_harness_set_src_caps_str (h_sink, "video/mpegts");
if (src_mode == GST_SRT_CONNECTION_MODE_LISTENER) {
@ -99,6 +89,25 @@ check_play (const gchar * src_uri,
gst_harness_teardown (h_sink);
}
static void
check_play_uri (const gchar * src_uri,
GstSRTConnectionMode src_mode,
const gchar * sink_uri, GstSRTConnectionMode sink_mode)
{
gchar *src_launchline, *sink_launchline;
GstHarness *h_src, *h_sink;
sink_launchline = g_strdup_printf ("srtsink uri=%s", sink_uri);
h_sink = gst_harness_new_parse (sink_launchline);
g_free (sink_launchline);
src_launchline = g_strdup_printf ("srtsrc name=src uri=%s", src_uri);
h_src = gst_harness_new_parse (src_launchline);
g_free (src_launchline);
check_play (h_src, src_mode, h_sink, sink_mode);
}
GST_START_TEST (test_create_and_unref)
{
GstElement *e;
@ -156,7 +165,7 @@ GST_END_TEST;
GST_START_TEST (test_src_caller_sink_listener)
{
check_play ("srt://127.0.0.1:3434?mode=caller",
check_play_uri ("srt://127.0.0.1:3434?mode=caller",
GST_SRT_CONNECTION_MODE_CALLER,
"srt://:3434?mode=listener", GST_SRT_CONNECTION_MODE_LISTENER);
}
@ -165,13 +174,43 @@ GST_END_TEST;
GST_START_TEST (test_src_listener_sink_caller)
{
check_play ("srt://:4242?mode=listener",
check_play_uri ("srt://:4242?mode=listener",
GST_SRT_CONNECTION_MODE_LISTENER,
"srt://127.0.0.1:4242?mode=caller", GST_SRT_CONNECTION_MODE_CALLER);
}
GST_END_TEST;
GST_START_TEST (test_src_allocate_port)
{
GstHarness *h_src, *h_sink;
GstElement *src;
gchar *sink_launchline;
gint local_port = 0;
h_src = gst_harness_new_parse ("srtsrc name=src localport=0 mode=listener");
g_assert_nonnull (h_src);
src = gst_bin_get_by_name (GST_BIN (h_src->element), "src");
gst_element_set_state (src, GST_STATE_PAUSED);
g_object_get (src, "localport", &local_port, NULL);
g_object_unref (src);
GST_INFO ("srtsrc localport = %d", local_port);
g_assert_cmpint (local_port, !=, 0);
sink_launchline =
g_strdup_printf ("srtsink uri=srt://127.0.0.1:%u?mode=caller",
local_port);
h_sink = gst_harness_new_parse (sink_launchline);
g_free (sink_launchline);
check_play (h_src, GST_SRT_CONNECTION_MODE_LISTENER, h_sink,
GST_SRT_CONNECTION_MODE_CALLER);
}
GST_END_TEST;
static Suite *
srt_suite (void)
{
@ -185,6 +224,7 @@ srt_suite (void)
G_N_ELEMENTS (elements));
tcase_add_test (tc_chain, test_src_caller_sink_listener);
tcase_add_test (tc_chain, test_src_listener_sink_caller);
tcase_add_test (tc_chain, test_src_allocate_port);
return s;
}