diff --git a/gst/tcp/gsttcpserversink.c b/gst/tcp/gsttcpserversink.c index 44a3bfd15a..695097c8a8 100644 --- a/gst/tcp/gsttcpserversink.c +++ b/gst/tcp/gsttcpserversink.c @@ -53,6 +53,7 @@ enum PROP_0, PROP_HOST, PROP_PORT, + PROP_CURRENT_PORT }; static void gst_tcp_server_sink_finalize (GObject * gobject); @@ -93,6 +94,10 @@ gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass) g_param_spec_int ("port", "port", "The port to send the packets to", 0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CURRENT_PORT, + g_param_spec_int ("current-port", "current-port", + "The port number the socket is currently bound to", 0, + TCP_HIGHEST_PORT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); gst_element_class_set_static_metadata (gstelement_class, "TCP server sink", "Sink/Network", @@ -256,6 +261,9 @@ gst_tcp_server_sink_get_property (GObject * object, guint prop_id, case PROP_PORT: g_value_set_int (value, sink->server_port); break; + case PROP_CURRENT_PORT: + g_value_set_int (value, g_atomic_int_get (&sink->current_port)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -272,6 +280,7 @@ gst_tcp_server_sink_init_send (GstMultiHandleSink * parent) GInetAddress *addr; GSocketAddress *saddr; GResolver *resolver; + gint bound_port; /* look up name if we need to */ addr = g_inet_address_new_from_string (this->host); @@ -330,6 +339,20 @@ gst_tcp_server_sink_init_send (GstMultiHandleSink * parent) "listened on server socket %p, returning from connection setup", this->server_socket); + if (this->server_port == 0) { + saddr = g_socket_get_local_address (this->server_socket, NULL); + bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr); + g_object_unref (saddr); + } else { + bound_port = this->server_port; + } + + GST_DEBUG_OBJECT (this, "listening on port %d", bound_port); + + g_atomic_int_set (&this->current_port, bound_port); + + g_object_notify (G_OBJECT (this), "current-port"); + this->server_source = g_socket_create_source (this->server_socket, G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP, @@ -413,6 +436,9 @@ gst_tcp_server_sink_close (GstMultiHandleSink * parent) } g_object_unref (this->server_socket); this->server_socket = NULL; + + g_atomic_int_set (&this->current_port, 0); + g_object_notify (G_OBJECT (this), "current-port"); } return TRUE; diff --git a/gst/tcp/gsttcpserversink.h b/gst/tcp/gsttcpserversink.h index 0a67ea0839..0786d03282 100644 --- a/gst/tcp/gsttcpserversink.h +++ b/gst/tcp/gsttcpserversink.h @@ -59,8 +59,10 @@ struct _GstTCPServerSink { GstMultiSocketSink element; /* server information */ - gint server_port; - gchar *host; + int current_port; /* currently bound-to port, or 0 */ /* ATOMIC */ + int server_port; /* port property */ + gchar *host; /* host property */ + GSocket *server_socket; GSource *server_source; }; diff --git a/gst/tcp/gsttcpserversrc.c b/gst/tcp/gsttcpserversrc.c index ab4fa4fc6b..e0d4e2cf26 100644 --- a/gst/tcp/gsttcpserversrc.c +++ b/gst/tcp/gsttcpserversrc.c @@ -60,7 +60,8 @@ enum { PROP_0, PROP_HOST, - PROP_PORT + PROP_PORT, + PROP_CURRENT_PORT }; #define gst_tcp_server_src_parent_class parent_class @@ -104,6 +105,10 @@ gst_tcp_server_src_class_init (GstTCPServerSrcClass * klass) g_param_spec_int ("port", "Port", "The port to listen to", 0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CURRENT_PORT, + g_param_spec_int ("current-port", "current-port", + "The port number the socket is currently bound to", 0, + TCP_HIGHEST_PORT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate)); @@ -338,6 +343,9 @@ gst_tcp_server_src_get_property (GObject * object, guint prop_id, case PROP_PORT: g_value_set_int (value, tcpserversrc->server_port); break; + case PROP_CURRENT_PORT: + g_value_set_int (value, g_atomic_int_get (&tcpserversrc->current_port)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -353,6 +361,7 @@ gst_tcp_server_src_start (GstBaseSrc * bsrc) GInetAddress *addr; GSocketAddress *saddr; GResolver *resolver; + gint bound_port = 0; /* look up name if we need to */ addr = g_inet_address_new_from_string (src->host); @@ -407,6 +416,19 @@ gst_tcp_server_src_start (GstBaseSrc * bsrc) GST_OBJECT_FLAG_SET (src, GST_TCP_SERVER_SRC_OPEN); + if (src->server_port == 0) { + saddr = g_socket_get_local_address (src->server_socket, NULL); + bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr); + g_object_unref (saddr); + } else { + bound_port = src->server_port; + } + + GST_DEBUG_OBJECT (src, "listening on port %d", bound_port); + + g_atomic_int_set (&src->current_port, bound_port); + g_object_notify (G_OBJECT (src), "current-port"); + return TRUE; /* ERRORS */ @@ -485,6 +507,9 @@ gst_tcp_server_src_stop (GstBaseSrc * bsrc) } g_object_unref (src->server_socket); src->server_socket = NULL; + + g_atomic_int_set (&src->current_port, 0); + g_object_notify (G_OBJECT (src), "current-port"); } GST_OBJECT_FLAG_UNSET (src, GST_TCP_SERVER_SRC_OPEN); diff --git a/gst/tcp/gsttcpserversrc.h b/gst/tcp/gsttcpserversrc.h index 326c4a5865..c49fc978e6 100644 --- a/gst/tcp/gsttcpserversrc.h +++ b/gst/tcp/gsttcpserversrc.h @@ -54,8 +54,9 @@ struct _GstTCPServerSrc { GstPushSrc element; /* server information */ - int server_port; - gchar *host; + int current_port; /* currently bound-to port, or 0 */ /* ATOMIC */ + int server_port; /* port property */ + gchar *host; /* host property */ GCancellable *cancellable; GSocket *server_socket;