diff --git a/ChangeLog b/ChangeLog index 5280e004a6..41413f0534 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-06-08 Thomas Vander Stichele + + * gst/tcp/Makefile.am: + * gst/tcp/gsttcpclientsink.c: (gst_tcpclientsink_get_type), + (gst_tcpclientsink_class_init), (gst_tcpclientsink_init), + (gst_tcpclientsink_set_property), (gst_tcpclientsink_get_property): + * gst/tcp/gsttcpclientsrc.c: (gst_tcpclientsrc_class_init), + (gst_tcpclientsrc_init), (gst_tcpclientsrc_set_property), + (gst_tcpclientsrc_get_property): + * gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init), + (gst_tcpserversink_init), (gst_tcpserversink_handle_server_read), + (gst_tcpserversink_handle_client_read), + (gst_tcpserversink_handle_client_write), + (gst_tcpserversink_set_property), (gst_tcpserversink_get_property): + * gst/tcp/gsttcpserversink.h: + add signals client-added and client-removed + * gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_class_init), + (gst_tcpserversrc_init), (gst_tcpserversrc_set_property), + (gst_tcpserversrc_get_property): + uniformized, change default protocol to NONE + * gst/tcp/gsttcp-marshal.list: added 2004-06-07 Benjamin Otte * ext/alsa/gstalsasink.c: (gst_alsa_sink_check_event): diff --git a/gst/tcp/Makefile.am b/gst/tcp/Makefile.am index 08858ebbba..cd4736ada2 100644 --- a/gst/tcp/Makefile.am +++ b/gst/tcp/Makefile.am @@ -2,13 +2,13 @@ plugin_LTLIBRARIES = libgsttcp.la # variables used for enum/marshal generation glib_enum_headers = gsttcp.h -glib_enum_define = GST_TCP_PROTOCOL -glib_enum_prefix = gst_tcp_protocol +glib_enum_define = GST_TCP +glib_enum_prefix = gst_tcp include $(top_srcdir)/common/glib-gen.mak -built_sources = gsttcp-enumtypes.c -built_headers = gsttcp-enumtypes.h +built_sources = gsttcp-enumtypes.c gsttcp-marshal.c +built_headers = gsttcp-enumtypes.h gsttcp-marshal.h BUILT_SOURCES = $(built_sources) $(built_headers) diff --git a/gst/tcp/gsttcp-marshal.list b/gst/tcp/gsttcp-marshal.list new file mode 100644 index 0000000000..08f95dbbf9 --- /dev/null +++ b/gst/tcp/gsttcp-marshal.list @@ -0,0 +1 @@ +VOID:STRING,UINT diff --git a/gst/tcp/gsttcpclientsink.c b/gst/tcp/gsttcpclientsink.c index 8f42eca3a1..89cc299ce9 100644 --- a/gst/tcp/gsttcpclientsink.c +++ b/gst/tcp/gsttcpclientsink.c @@ -131,7 +131,7 @@ gst_tcpclientsink_class_init (GstTCPClientSink * klass) 0, 32768, TCP_DEFAULT_PORT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_PROTOCOL, g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in", - GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_GDP, + GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_NONE, G_PARAM_READWRITE)); gobject_class->set_property = gst_tcpclientsink_set_property; gobject_class->get_property = gst_tcpclientsink_get_property; @@ -166,7 +166,7 @@ gst_tcpclientsink_init (GstTCPClientSink * this) /* this->mtu = 1500; */ this->sock_fd = -1; - this->protocol = GST_TCP_PROTOCOL_TYPE_GDP; + this->protocol = GST_TCP_PROTOCOL_TYPE_NONE; GST_FLAG_UNSET (this, GST_TCPCLIENTSINK_OPEN); this->clock = NULL; @@ -254,12 +254,8 @@ gst_tcpclientsink_set_property (GObject * object, guint prop_id, switch (prop_id) { case ARG_HOST: - if (tcpclientsink->host != NULL) - g_free (tcpclientsink->host); - if (g_value_get_string (value) == NULL) - tcpclientsink->host = NULL; - else - tcpclientsink->host = g_strdup (g_value_get_string (value)); + g_free (tcpclientsink->host); + tcpclientsink->host = g_strdup (g_value_get_string (value)); break; case ARG_PORT: tcpclientsink->port = g_value_get_int (value); @@ -267,7 +263,9 @@ gst_tcpclientsink_set_property (GObject * object, guint prop_id, case ARG_PROTOCOL: tcpclientsink->protocol = g_value_get_enum (value); break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -292,6 +290,7 @@ gst_tcpclientsink_get_property (GObject * object, guint prop_id, GValue * value, case ARG_PROTOCOL: g_value_set_enum (value, tcpclientsink->protocol); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/tcp/gsttcpclientsrc.c b/gst/tcp/gsttcpclientsrc.c index e69004a282..45bd4f58a7 100644 --- a/gst/tcp/gsttcpclientsrc.c +++ b/gst/tcp/gsttcpclientsrc.c @@ -61,8 +61,8 @@ enum enum { ARG_0, - ARG_PORT, ARG_HOST, + ARG_PORT, ARG_PROTOCOL }; @@ -139,7 +139,7 @@ gst_tcpclientsrc_class_init (GstTCPClientSrc * klass) 32768, TCP_DEFAULT_PORT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_PROTOCOL, g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in", - GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_GDP, + GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_NONE, G_PARAM_READWRITE)); gobject_class->set_property = gst_tcpclientsrc_set_property; @@ -174,7 +174,7 @@ gst_tcpclientsrc_init (GstTCPClientSrc * this) this->host = g_strdup (TCP_DEFAULT_HOST); this->clock = NULL; this->sock_fd = -1; - this->protocol = GST_TCP_PROTOCOL_TYPE_GDP; + this->protocol = GST_TCP_PROTOCOL_TYPE_NONE; this->curoffset = 0; GST_FLAG_UNSET (this, GST_TCPCLIENTSRC_OPEN); @@ -345,17 +345,17 @@ gst_tcpclientsrc_set_property (GObject * object, guint prop_id, tcpclientsrc = GST_TCPCLIENTSRC (object); switch (prop_id) { - case ARG_PORT: - tcpclientsrc->port = g_value_get_int (value); - break; case ARG_HOST: - /* FIXME: create a setter and handle changes correctly */ g_free (tcpclientsrc->host); tcpclientsrc->host = g_strdup (g_value_get_string (value)); break; + case ARG_PORT: + tcpclientsrc->port = g_value_get_int (value); + break; case ARG_PROTOCOL: tcpclientsrc->protocol = g_value_get_enum (value); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -372,12 +372,12 @@ gst_tcpclientsrc_get_property (GObject * object, guint prop_id, GValue * value, tcpclientsrc = GST_TCPCLIENTSRC (object); switch (prop_id) { - case ARG_PORT: - g_value_set_int (value, tcpclientsrc->port); - break; case ARG_HOST: g_value_set_string (value, tcpclientsrc->host); break; + case ARG_PORT: + g_value_set_int (value, tcpclientsrc->port); + break; case ARG_PROTOCOL: g_value_set_enum (value, tcpclientsrc->protocol); break; diff --git a/gst/tcp/gsttcpserversink.c b/gst/tcp/gsttcpserversink.c index 455b7783df..cc6d268b37 100644 --- a/gst/tcp/gsttcpserversink.c +++ b/gst/tcp/gsttcpserversink.c @@ -30,6 +30,7 @@ #endif #include "gsttcpserversink.h" +#include "gsttcp-marshal.h" #define TCP_DEFAULT_HOST "127.0.0.1" #define TCP_DEFAULT_PORT 4953 @@ -42,23 +43,23 @@ GST_ELEMENT_DETAILS ("TCP Server sink", "Send data as a server over the network via TCP", "Thomas Vander Stichele "); +GST_DEBUG_CATEGORY (tcpserversink_debug); +#define GST_CAT_DEFAULT (tcpserversink_debug) + /* TCPServerSink signals and args */ enum { - FRAME_ENCODED, - /* FILL ME */ + SIGNAL_CLIENT_ADDED, + SIGNAL_CLIENT_REMOVED, LAST_SIGNAL }; -GST_DEBUG_CATEGORY (tcpserversink_debug); -#define GST_CAT_DEFAULT (tcpserversink_debug) - enum { ARG_0, ARG_HOST, - ARG_PORT - /* FILL ME */ + ARG_PORT, + ARG_PROTOCOL }; static void gst_tcpserversink_base_init (gpointer g_class); @@ -80,7 +81,7 @@ static void gst_tcpserversink_get_property (GObject * object, guint prop_id, static GstElementClass *parent_class = NULL; -/*static guint gst_tcpserversink_signals[LAST_SIGNAL] = { 0 }; */ +static guint gst_tcpserversink_signals[LAST_SIGNAL] = { 0 }; GType gst_tcpserversink_get_type (void) @@ -134,6 +135,22 @@ gst_tcpserversink_class_init (GstTCPServerSink * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT, g_param_spec_int ("port", "port", "The port to send the packets to", 0, 32768, TCP_DEFAULT_PORT, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_PROTOCOL, + g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in", + GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_NONE, + G_PARAM_READWRITE)); + + gst_tcpserversink_signals[SIGNAL_CLIENT_ADDED] = + g_signal_new ("client-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTCPServerSinkClass, client_added), + NULL, NULL, gst_tcp_marshal_VOID__STRING_UINT, G_TYPE_NONE, 2, + G_TYPE_STRING, G_TYPE_UINT); + gst_tcpserversink_signals[SIGNAL_CLIENT_REMOVED] = + g_signal_new ("client-removed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTCPServerSinkClass, + client_removed), NULL, NULL, gst_tcp_marshal_VOID__STRING_UINT, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); + gobject_class->set_property = gst_tcpserversink_set_property; gobject_class->get_property = gst_tcpserversink_get_property; @@ -168,7 +185,7 @@ gst_tcpserversink_init (GstTCPServerSink * this) this->server_sock_fd = -1; GST_FLAG_UNSET (this, GST_TCPSERVERSINK_OPEN); - this->protocol = GST_TCP_PROTOCOL_TYPE_GDP; + this->protocol = GST_TCP_PROTOCOL_TYPE_NONE; this->clock = NULL; } @@ -205,6 +222,9 @@ gst_tcpserversink_handle_server_read (GstTCPServerSink * sink) FD_SET (client_sock_fd, &(sink->clientfds)); GST_DEBUG_OBJECT (sink, "added new client ip %s with fd %d", inet_ntoa (client_address.sin_addr), client_sock_fd); + g_signal_emit (G_OBJECT (sink), + gst_tcpserversink_signals[SIGNAL_CLIENT_ADDED], 0, + inet_ntoa (client_address.sin_addr), client_sock_fd); return TRUE; } @@ -229,6 +249,9 @@ gst_tcpserversink_handle_client_read (GstTCPServerSink * sink, int fd) } FD_CLR (fd, &sink->clientfds); FD_CLR (fd, &sink->caps_sent); + /* FIXME: we need to keep track of IP info so we can signal it here */ + g_signal_emit (G_OBJECT (sink), + gst_tcpserversink_signals[SIGNAL_CLIENT_REMOVED], 0, NULL, fd); } else { /* FIXME: we should probably just Read 'n' Drop */ g_warning ("Don't know what to do with %d bytes to read", nread); @@ -248,7 +271,7 @@ gst_tcpserversink_handle_client_write (GstTCPServerSink * sink, int fd, break; case GST_TCP_PROTOCOL_TYPE_GDP: - /* if we haven't send caps yet, send them first */ + /* if we haven't sent caps yet, send them first */ if (!FD_ISSET (fd, &(sink->caps_sent))) { const GstCaps *caps; gchar *string; @@ -295,7 +318,8 @@ gst_tcpserversink_handle_client_write (GstTCPServerSink * sink, int fd, */ /* FIXME: there should be a better way to report problems, since we want to continue for other clients and just drop this particular one */ - g_warning ("Write failed: %d of %d written", wrote, GST_BUFFER_SIZE (buf)); + GST_DEBUG_OBJECT (sink, "Write failed: %d of %d bytes written", wrote, + GST_BUFFER_SIZE (buf)); /* write failed, so drop the client */ GST_DEBUG_OBJECT (sink, "removing client on fd %d", fd); if (close (fd) != 0) { @@ -304,6 +328,8 @@ gst_tcpserversink_handle_client_write (GstTCPServerSink * sink, int fd, } FD_CLR (fd, &sink->clientfds); FD_CLR (fd, &sink->caps_sent); + g_signal_emit (G_OBJECT (sink), + gst_tcpserversink_signals[SIGNAL_CLIENT_REMOVED], 0, NULL, fd); return FALSE; } return TRUE; @@ -416,17 +442,18 @@ gst_tcpserversink_set_property (GObject * object, guint prop_id, switch (prop_id) { case ARG_HOST: - if (tcpserversink->host != NULL) - g_free (tcpserversink->host); - if (g_value_get_string (value) == NULL) - tcpserversink->host = NULL; - else - tcpserversink->host = g_strdup (g_value_get_string (value)); + g_free (tcpserversink->host); + tcpserversink->host = g_strdup (g_value_get_string (value)); break; case ARG_PORT: tcpserversink->server_port = g_value_get_int (value); break; + case ARG_PROTOCOL: + tcpserversink->protocol = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -447,6 +474,10 @@ gst_tcpserversink_get_property (GObject * object, guint prop_id, GValue * value, case ARG_PORT: g_value_set_int (value, tcpserversink->server_port); break; + case ARG_PROTOCOL: + g_value_set_enum (value, tcpserversink->protocol); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/tcp/gsttcpserversink.h b/gst/tcp/gsttcpserversink.h index 095ea5a83c..fb496a6a11 100644 --- a/gst/tcp/gsttcpserversink.h +++ b/gst/tcp/gsttcpserversink.h @@ -81,7 +81,10 @@ struct _GstTCPServerSink { size_t data_written; /* how much bytes have we written ? */ fd_set clientfds; /* all the client file descriptors that are open */ - fd_set caps_sent; /* all the client file descriptors that have had caps sent */ + fd_set caps_sent; /* all the client file descriptors + * that have had caps sent */ + fd_set streamheader_sent; /* all the client file descriptors that have had + * streamheader sent */ GstTCPProtocolType protocol; guint mtu; @@ -90,6 +93,10 @@ struct _GstTCPServerSink { struct _GstTCPServerSinkClass { GstElementClass parent_class; + + /* signals */ + void (*client_added) (GstElement *element, gchar *host, gint fd); + void (*client_removed) (GstElement *element, gchar *host, gint fd); }; GType gst_tcpserversink_get_type (void); diff --git a/gst/tcp/gsttcpserversrc.c b/gst/tcp/gsttcpserversrc.c index 35b44ac254..4edff3ef33 100644 --- a/gst/tcp/gsttcpserversrc.c +++ b/gst/tcp/gsttcpserversrc.c @@ -56,8 +56,8 @@ enum enum { ARG_0, - ARG_PORT, ARG_HOST, + ARG_PORT, ARG_PROTOCOL }; @@ -125,16 +125,16 @@ gst_tcpserversrc_class_init (GstTCPServerSrc * klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HOST, + g_param_spec_string ("host", "Host", "The hostname to listen", + TCP_DEFAULT_HOST, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT, g_param_spec_int ("port", "Port", "The port to listen to", 0, 32768, TCP_DEFAULT_PORT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_PROTOCOL, g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in", - GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_GDP, + GST_TYPE_TCP_PROTOCOL_TYPE, GST_TCP_PROTOCOL_TYPE_NONE, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HOST, - g_param_spec_string ("host", "Host", "The hostname to listen", - TCP_DEFAULT_HOST, G_PARAM_READWRITE)); gobject_class->set_property = gst_tcpserversrc_set_property; gobject_class->get_property = gst_tcpserversrc_get_property; @@ -170,7 +170,7 @@ gst_tcpserversrc_init (GstTCPServerSrc * this) this->server_sock_fd = -1; this->client_sock_fd = -1; this->curoffset = 0; - this->protocol = GST_TCP_PROTOCOL_TYPE_GDP; + this->protocol = GST_TCP_PROTOCOL_TYPE_NONE; GST_FLAG_UNSET (this, GST_TCPSERVERSRC_OPEN); } @@ -403,17 +403,17 @@ gst_tcpserversrc_set_property (GObject * object, guint prop_id, tcpserversrc = GST_TCPSERVERSRC (object); switch (prop_id) { + case ARG_HOST: + g_free (tcpserversrc->host); + tcpserversrc->host = g_strdup (g_value_get_string (value)); + break; case ARG_PORT: tcpserversrc->server_port = g_value_get_int (value); break; case ARG_PROTOCOL: tcpserversrc->protocol = g_value_get_enum (value); break; - case ARG_HOST: - if (tcpserversrc->host) - g_free (tcpserversrc->host); - tcpserversrc->host = g_strdup (g_value_get_string (value)); - break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -430,15 +430,16 @@ gst_tcpserversrc_get_property (GObject * object, guint prop_id, GValue * value, tcpserversrc = GST_TCPSERVERSRC (object); switch (prop_id) { + case ARG_HOST: + g_value_set_string (value, tcpserversrc->host); + break; case ARG_PORT: g_value_set_int (value, tcpserversrc->server_port); break; case ARG_PROTOCOL: g_value_set_enum (value, tcpserversrc->protocol); break; - case ARG_HOST: - g_value_set_string (value, tcpserversrc->host); - break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break;