tcpserver{sink,src}: add 'current-port' property and signal actually used port
authorAlexandre Relange <alexandre.relange@pineasystems.org>
Wed, 17 Oct 2012 10:19:56 +0000 (12:19 +0200)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 19 Oct 2012 17:23:20 +0000 (18:23 +0100)
Useful when port=0 (use random available port) was requested.

https://bugzilla.gnome.org/show_bug.cgi?id=580093

gst/tcp/gsttcpserversink.c
gst/tcp/gsttcpserversink.h
gst/tcp/gsttcpserversrc.c
gst/tcp/gsttcpserversrc.h

index 44a3bfd..695097c 100644 (file)
@@ -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;
index 0a67ea0..0786d03 100644 (file)
@@ -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;
 };
index ab4fa4f..e0d4e2c 100644 (file)
@@ -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);
index 326c4a5..c49fc97 100644 (file)
@@ -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;