2004-05-20 10:15:31 +00:00
|
|
|
/* GStreamer
|
|
|
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
|
|
* Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
2012-11-03 23:05:09 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2004-05-20 10:15:31 +00:00
|
|
|
*/
|
|
|
|
|
2005-08-05 18:51:29 +00:00
|
|
|
/**
|
2009-03-23 14:19:11 +00:00
|
|
|
* SECTION:element-tcpserversink
|
2017-01-23 19:36:11 +00:00
|
|
|
* @title: tcpserversink
|
2005-08-05 18:51:29 +00:00
|
|
|
* @see_also: #multifdsink
|
2008-07-10 21:06:06 +00:00
|
|
|
*
|
2018-05-05 16:02:16 +00:00
|
|
|
* ## Example launch line (server):
|
2009-03-23 14:19:11 +00:00
|
|
|
* |[
|
2015-05-09 21:33:26 +00:00
|
|
|
* gst-launch-1.0 fdsrc fd=1 ! tcpserversink port=3000
|
2018-05-05 16:02:16 +00:00
|
|
|
* ]|
|
|
|
|
* ## Example launch line (client):
|
|
|
|
* |[
|
2015-05-09 21:33:26 +00:00
|
|
|
* gst-launch-1.0 tcpclientsrc port=3000 ! fdsink fd=2
|
2017-01-23 19:36:11 +00:00
|
|
|
* ]|
|
|
|
|
*
|
2005-08-05 18:51:29 +00:00
|
|
|
*/
|
|
|
|
|
2004-05-20 10:15:31 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
#include <gst/gst-i18n-plugin.h>
|
2005-12-16 11:25:51 +00:00
|
|
|
#include <string.h> /* memset */
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2004-11-05 17:38:20 +00:00
|
|
|
#include "gsttcp.h"
|
2020-12-11 11:42:03 +00:00
|
|
|
#include "gsttcpelements.h"
|
2004-05-20 10:15:31 +00:00
|
|
|
#include "gsttcpserversink.h"
|
|
|
|
|
2005-12-06 19:42:02 +00:00
|
|
|
#define TCP_BACKLOG 5
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2006-06-23 09:53:09 +00:00
|
|
|
GST_DEBUG_CATEGORY_STATIC (tcpserversink_debug);
|
2004-06-08 09:12:12 +00:00
|
|
|
#define GST_CAT_DEFAULT (tcpserversink_debug)
|
|
|
|
|
2004-05-20 10:15:31 +00:00
|
|
|
enum
|
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
PROP_0,
|
|
|
|
PROP_HOST,
|
|
|
|
PROP_PORT,
|
2012-10-17 10:19:56 +00:00
|
|
|
PROP_CURRENT_PORT
|
2004-05-20 10:15:31 +00:00
|
|
|
};
|
|
|
|
|
2005-12-01 01:21:49 +00:00
|
|
|
static void gst_tcp_server_sink_finalize (GObject * gobject);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2012-01-26 22:19:33 +00:00
|
|
|
static gboolean gst_tcp_server_sink_init_send (GstMultiHandleSink * this);
|
|
|
|
static gboolean gst_tcp_server_sink_close (GstMultiHandleSink * this);
|
2012-01-27 20:28:05 +00:00
|
|
|
static void gst_tcp_server_sink_removed (GstMultiHandleSink * sink,
|
|
|
|
GstMultiSinkHandle handle);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2005-12-01 01:21:49 +00:00
|
|
|
static void gst_tcp_server_sink_set_property (GObject * object, guint prop_id,
|
2004-05-20 10:15:31 +00:00
|
|
|
const GValue * value, GParamSpec * pspec);
|
2005-12-01 01:21:49 +00:00
|
|
|
static void gst_tcp_server_sink_get_property (GObject * object, guint prop_id,
|
2004-05-20 10:15:31 +00:00
|
|
|
GValue * value, GParamSpec * pspec);
|
|
|
|
|
2011-04-19 09:35:53 +00:00
|
|
|
#define gst_tcp_server_sink_parent_class parent_class
|
2012-01-16 09:08:24 +00:00
|
|
|
G_DEFINE_TYPE (GstTCPServerSink, gst_tcp_server_sink,
|
|
|
|
GST_TYPE_MULTI_SOCKET_SINK);
|
2020-12-11 11:42:03 +00:00
|
|
|
GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (tcpserversink, "tcpserversink",
|
|
|
|
GST_RANK_NONE, GST_TYPE_TCP_SERVER_SINK, tcp_element_init (plugin));
|
2004-05-20 10:15:31 +00:00
|
|
|
|
|
|
|
static void
|
2005-12-01 01:21:49 +00:00
|
|
|
gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
|
|
|
GObjectClass *gobject_class;
|
2011-04-19 09:35:53 +00:00
|
|
|
GstElementClass *gstelement_class;
|
2012-01-26 22:19:33 +00:00
|
|
|
GstMultiHandleSinkClass *gstmultihandlesink_class;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
|
|
|
gobject_class = (GObjectClass *) klass;
|
2011-04-19 09:35:53 +00:00
|
|
|
gstelement_class = (GstElementClass *) klass;
|
2012-01-26 22:19:33 +00:00
|
|
|
gstmultihandlesink_class = (GstMultiHandleSinkClass *) klass;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2005-12-01 01:21:49 +00:00
|
|
|
gobject_class->set_property = gst_tcp_server_sink_set_property;
|
|
|
|
gobject_class->get_property = gst_tcp_server_sink_get_property;
|
|
|
|
gobject_class->finalize = gst_tcp_server_sink_finalize;
|
Ported tcp plugins to 0.9.
Original commit message from CVS:
* configure.ac:
* gst/tcp/Makefile.am:
* gst/tcp/README:
* gst/tcp/gstmultifdsink.c: (gst_multifdsink_get_type),
(gst_multifdsink_base_init), (gst_multifdsink_class_init),
(gst_multifdsink_init), (gst_multifdsink_remove_client_link),
(is_sync_frame), (gst_multifdsink_handle_client_write),
(gst_multifdsink_render), (gst_multifdsink_start),
(gst_multifdsink_stop), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcp.c: (gst_tcp_host_to_ip),
(gst_tcp_gdp_read_buffer), (gst_tcp_gdp_read_caps),
(gst_tcp_gdp_write_buffer), (gst_tcp_gdp_write_caps):
* gst/tcp/gsttcp.h:
* gst/tcp/gsttcpclientsink.c: (gst_tcpclientsink_class_init),
(gst_tcpclientsink_init), (gst_tcpclientsink_setcaps),
(gst_tcpclientsink_render), (gst_tcpclientsink_start),
(gst_tcpclientsink_stop), (gst_tcpclientsink_change_state):
* gst/tcp/gsttcpclientsink.h:
* gst/tcp/gsttcpclientsrc.c: (gst_tcpclientsrc_get_type),
(gst_tcpclientsrc_base_init), (gst_tcpclientsrc_class_init),
(gst_tcpclientsrc_init), (gst_tcpclientsrc_getcaps),
(gst_tcpclientsrc_create), (gst_tcpclientsrc_start),
(gst_tcpclientsrc_stop), (gst_tcpclientsrc_unlock):
* gst/tcp/gsttcpclientsrc.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init):
* gst/tcp/gsttcpserversink.h:
* gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_get_type),
(gst_tcpserversrc_base_init), (gst_tcpserversrc_class_init),
(gst_tcpserversrc_init), (gst_tcpserversrc_finalize),
(gst_tcpserversrc_create), (gst_tcpserversrc_start),
(gst_tcpserversrc_stop):
* gst/tcp/gsttcpserversrc.h:
* gst/tcp/gsttcpsink.c:
* gst/tcp/gsttcpsink.h:
* gst/tcp/gsttcpsrc.c:
* gst/tcp/gsttcpsrc.h:
Ported tcp plugins to 0.9.
2005-07-05 10:21:40 +00:00
|
|
|
|
2013-04-25 07:05:55 +00:00
|
|
|
/* FIXME 2.0: Rename this to bind-address, host does not make much
|
|
|
|
* sense here */
|
2012-01-16 09:08:24 +00:00
|
|
|
g_object_class_install_property (gobject_class, PROP_HOST,
|
2012-10-19 17:29:00 +00:00
|
|
|
g_param_spec_string ("host", "host", "The host/IP to listen on",
|
2008-03-22 15:00:53 +00:00
|
|
|
TCP_DEFAULT_HOST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
2012-01-16 09:08:24 +00:00
|
|
|
g_object_class_install_property (gobject_class, PROP_PORT,
|
2012-10-19 17:29:00 +00:00
|
|
|
g_param_spec_int ("port", "port",
|
|
|
|
"The port to listen to (0=random available port)",
|
2008-03-22 15:00:53 +00:00
|
|
|
0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
2012-10-19 17:29:00 +00:00
|
|
|
/**
|
|
|
|
* GstTCPServerSink:current-port:
|
|
|
|
*
|
|
|
|
* The port number the socket is currently bound to. Applications can use
|
|
|
|
* this property to retrieve the port number actually bound to in case
|
|
|
|
* the port requested was 0 (=allocate a random available port).
|
|
|
|
*
|
|
|
|
* Since: 1.0.2
|
|
|
|
**/
|
2012-10-17 10:19:56 +00:00
|
|
|
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));
|
2004-06-08 09:12:12 +00:00
|
|
|
|
2012-04-09 23:45:16 +00:00
|
|
|
gst_element_class_set_static_metadata (gstelement_class,
|
2011-04-19 09:35:53 +00:00
|
|
|
"TCP server sink", "Sink/Network",
|
|
|
|
"Send data as a server over the network via TCP",
|
|
|
|
"Thomas Vander Stichele <thomas at apestaart dot org>");
|
|
|
|
|
2012-01-26 22:19:33 +00:00
|
|
|
gstmultihandlesink_class->init = gst_tcp_server_sink_init_send;
|
|
|
|
gstmultihandlesink_class->close = gst_tcp_server_sink_close;
|
2012-01-28 17:07:46 +00:00
|
|
|
gstmultihandlesink_class->removed = gst_tcp_server_sink_removed;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
|
|
|
GST_DEBUG_CATEGORY_INIT (tcpserversink_debug, "tcpserversink", 0, "TCP sink");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-04-19 09:35:53 +00:00
|
|
|
gst_tcp_server_sink_init (GstTCPServerSink * this)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
|
|
|
this->server_port = TCP_DEFAULT_PORT;
|
|
|
|
/* should support as minimum 576 for IPV4 and 1500 for IPV6 */
|
|
|
|
/* this->mtu = 1500; */
|
2005-02-02 06:26:15 +00:00
|
|
|
this->host = g_strdup (TCP_DEFAULT_HOST);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
this->server_socket = NULL;
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|
|
|
|
|
2005-02-02 06:26:15 +00:00
|
|
|
static void
|
2005-12-01 01:21:49 +00:00
|
|
|
gst_tcp_server_sink_finalize (GObject * gobject)
|
2005-02-02 06:26:15 +00:00
|
|
|
{
|
2005-12-01 01:21:49 +00:00
|
|
|
GstTCPServerSink *this = GST_TCP_SERVER_SINK (gobject);
|
2005-02-02 06:26:15 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
if (this->server_socket)
|
|
|
|
g_object_unref (this->server_socket);
|
|
|
|
this->server_socket = NULL;
|
2005-02-02 06:26:15 +00:00
|
|
|
g_free (this->host);
|
2012-01-16 09:08:24 +00:00
|
|
|
this->host = NULL;
|
2007-03-08 12:53:51 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (gobject);
|
2005-02-02 06:26:15 +00:00
|
|
|
}
|
|
|
|
|
2004-05-20 10:15:31 +00:00
|
|
|
/* handle a read request on the server,
|
|
|
|
* which indicates a new client connection */
|
|
|
|
static gboolean
|
2005-12-01 01:21:49 +00:00
|
|
|
gst_tcp_server_sink_handle_server_read (GstTCPServerSink * sink)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
2013-11-28 16:22:01 +00:00
|
|
|
GstMultiSinkHandle handle;
|
2012-01-16 09:08:24 +00:00
|
|
|
GSocket *client_socket;
|
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
/* wait on server socket for connections */
|
|
|
|
client_socket =
|
|
|
|
g_socket_accept (sink->server_socket, sink->element.cancellable, &err);
|
|
|
|
if (!client_socket)
|
2008-05-13 16:02:19 +00:00
|
|
|
goto accept_failed;
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
|
2013-11-28 16:22:01 +00:00
|
|
|
handle.socket = client_socket;
|
2014-11-06 14:14:22 +00:00
|
|
|
/* gst_multi_handle_sink_add does not take ownership of client_socket */
|
2013-11-28 16:22:01 +00:00
|
|
|
gst_multi_handle_sink_add (GST_MULTI_HANDLE_SINK (sink), handle);
|
2012-01-16 09:08:24 +00:00
|
|
|
|
|
|
|
#ifndef GST_DISABLE_GST_DEBUG
|
|
|
|
{
|
|
|
|
GInetSocketAddress *addr =
|
|
|
|
G_INET_SOCKET_ADDRESS (g_socket_get_remote_address (client_socket,
|
|
|
|
NULL));
|
2020-10-30 12:52:29 +00:00
|
|
|
if (addr) {
|
|
|
|
gchar *ip =
|
|
|
|
g_inet_address_to_string (g_inet_socket_address_get_address (addr));
|
|
|
|
|
|
|
|
GST_DEBUG_OBJECT (sink, "added new client ip %s:%u with socket %p",
|
|
|
|
ip, g_inet_socket_address_get_port (addr), client_socket);
|
|
|
|
|
|
|
|
g_free (ip);
|
|
|
|
g_object_unref (addr);
|
|
|
|
} else {
|
|
|
|
/* This can happen when the client immediately closes the connection */
|
|
|
|
GST_DEBUG_OBJECT (sink, "added new client (no address) with socket %p",
|
|
|
|
client_socket);
|
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
}
|
|
|
|
#endif
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2014-11-06 14:14:22 +00:00
|
|
|
g_object_unref (client_socket);
|
2004-05-20 10:15:31 +00:00
|
|
|
return TRUE;
|
2008-05-13 16:02:19 +00:00
|
|
|
|
|
|
|
/* ERRORS */
|
|
|
|
accept_failed:
|
|
|
|
{
|
|
|
|
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
|
2012-01-16 09:08:24 +00:00
|
|
|
("Could not accept client on server socket %p: %s",
|
|
|
|
sink->server_socket, err->message));
|
|
|
|
g_clear_error (&err);
|
2008-05-13 16:02:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|
|
|
|
|
gst/tcp/: Small cleanups in fdset.c
Original commit message from CVS:
* gst/tcp/gstfdset.c: (gst_fdset_fd_has_closed),
(gst_fdset_fd_has_error), (gst_fdset_fd_can_read),
(gst_fdset_fd_can_write), (gst_fdset_wait):
* gst/tcp/gstmultifdsink.c: (gst_client_status_get_type),
(gst_multifdsink_init), (gst_multifdsink_add),
(gst_multifdsink_remove), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_handle_clients),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_removed):
Small cleanups in fdset.c
Use a hastable to map fd to the client structure for faster
lookup in _remove and get_stats.
Added virtual function to close the fds.
Handle clients even when the select/poll call was unblocked because
of a command.
Implement syncing to keyframe in the recovery procedure.
2004-09-17 10:06:52 +00:00
|
|
|
static void
|
2012-01-27 20:28:05 +00:00
|
|
|
gst_tcp_server_sink_removed (GstMultiHandleSink * sink,
|
|
|
|
GstMultiSinkHandle handle)
|
gst/tcp/: Small cleanups in fdset.c
Original commit message from CVS:
* gst/tcp/gstfdset.c: (gst_fdset_fd_has_closed),
(gst_fdset_fd_has_error), (gst_fdset_fd_can_read),
(gst_fdset_fd_can_write), (gst_fdset_wait):
* gst/tcp/gstmultifdsink.c: (gst_client_status_get_type),
(gst_multifdsink_init), (gst_multifdsink_add),
(gst_multifdsink_remove), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_handle_clients),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_removed):
Small cleanups in fdset.c
Use a hastable to map fd to the client structure for faster
lookup in _remove and get_stats.
Added virtual function to close the fds.
Handle clients even when the select/poll call was unblocked because
of a command.
Implement syncing to keyframe in the recovery procedure.
2004-09-17 10:06:52 +00:00
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
GError *err = NULL;
|
gst/tcp/: Small cleanups in fdset.c
Original commit message from CVS:
* gst/tcp/gstfdset.c: (gst_fdset_fd_has_closed),
(gst_fdset_fd_has_error), (gst_fdset_fd_can_read),
(gst_fdset_fd_can_write), (gst_fdset_wait):
* gst/tcp/gstmultifdsink.c: (gst_client_status_get_type),
(gst_multifdsink_init), (gst_multifdsink_add),
(gst_multifdsink_remove), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_handle_clients),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_removed):
Small cleanups in fdset.c
Use a hastable to map fd to the client structure for faster
lookup in _remove and get_stats.
Added virtual function to close the fds.
Handle clients even when the select/poll call was unblocked because
of a command.
Implement syncing to keyframe in the recovery procedure.
2004-09-17 10:06:52 +00:00
|
|
|
|
2012-10-19 17:29:00 +00:00
|
|
|
GST_DEBUG_OBJECT (sink, "closing socket");
|
2012-01-16 09:08:24 +00:00
|
|
|
|
2012-01-27 20:28:05 +00:00
|
|
|
if (!g_socket_close (handle.socket, &err)) {
|
2012-10-19 17:29:00 +00:00
|
|
|
GST_ERROR_OBJECT (sink, "Failed to close socket: %s", err->message);
|
2012-01-16 09:08:24 +00:00
|
|
|
g_clear_error (&err);
|
gst/tcp/: Small cleanups in fdset.c
Original commit message from CVS:
* gst/tcp/gstfdset.c: (gst_fdset_fd_has_closed),
(gst_fdset_fd_has_error), (gst_fdset_fd_can_read),
(gst_fdset_fd_can_write), (gst_fdset_wait):
* gst/tcp/gstmultifdsink.c: (gst_client_status_get_type),
(gst_multifdsink_init), (gst_multifdsink_add),
(gst_multifdsink_remove), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_handle_clients),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_removed):
Small cleanups in fdset.c
Use a hastable to map fd to the client structure for faster
lookup in _remove and get_stats.
Added virtual function to close the fds.
Handle clients even when the select/poll call was unblocked because
of a command.
Implement syncing to keyframe in the recovery procedure.
2004-09-17 10:06:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-20 10:15:31 +00:00
|
|
|
static gboolean
|
2012-01-16 09:08:24 +00:00
|
|
|
gst_tcp_server_sink_socket_condition (GSocket * socket, GIOCondition condition,
|
|
|
|
GstTCPServerSink * sink)
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
if ((condition & G_IO_ERR)) {
|
|
|
|
goto error;
|
|
|
|
} else if ((condition & G_IO_IN) || (condition & G_IO_PRI)) {
|
|
|
|
if (!gst_tcp_server_sink_handle_server_read (sink))
|
|
|
|
return FALSE;
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
return TRUE;
|
2008-05-13 16:02:19 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
error:
|
|
|
|
GST_ELEMENT_ERROR (sink, RESOURCE, READ, (NULL),
|
|
|
|
("client connection failed"));
|
|
|
|
|
|
|
|
return FALSE;
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-12-01 01:21:49 +00:00
|
|
|
gst_tcp_server_sink_set_property (GObject * object, guint prop_id,
|
2004-05-20 10:15:31 +00:00
|
|
|
const GValue * value, GParamSpec * pspec)
|
|
|
|
{
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
GstTCPServerSink *sink;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2005-12-01 01:21:49 +00:00
|
|
|
sink = GST_TCP_SERVER_SINK (object);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
|
|
|
switch (prop_id) {
|
2012-01-16 09:08:24 +00:00
|
|
|
case PROP_HOST:
|
2005-01-13 17:13:51 +00:00
|
|
|
if (!g_value_get_string (value)) {
|
|
|
|
g_warning ("host property cannot be NULL");
|
|
|
|
break;
|
|
|
|
}
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
g_free (sink->host);
|
2019-12-18 15:03:54 +00:00
|
|
|
sink->host = g_value_dup_string (value);
|
2004-05-20 10:15:31 +00:00
|
|
|
break;
|
2012-01-16 09:08:24 +00:00
|
|
|
case PROP_PORT:
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
sink->server_port = g_value_get_int (value);
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
break;
|
2004-05-20 10:15:31 +00:00
|
|
|
default:
|
2004-06-08 09:12:12 +00:00
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
2004-05-20 10:15:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-12-01 01:21:49 +00:00
|
|
|
gst_tcp_server_sink_get_property (GObject * object, guint prop_id,
|
|
|
|
GValue * value, GParamSpec * pspec)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
GstTCPServerSink *sink;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2005-12-01 01:21:49 +00:00
|
|
|
sink = GST_TCP_SERVER_SINK (object);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
|
|
|
switch (prop_id) {
|
2012-01-16 09:08:24 +00:00
|
|
|
case PROP_HOST:
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
g_value_set_string (value, sink->host);
|
2004-05-20 10:15:31 +00:00
|
|
|
break;
|
2012-01-16 09:08:24 +00:00
|
|
|
case PROP_PORT:
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
g_value_set_int (value, sink->server_port);
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
break;
|
2012-10-17 10:19:56 +00:00
|
|
|
case PROP_CURRENT_PORT:
|
|
|
|
g_value_set_int (value, g_atomic_int_get (&sink->current_port));
|
|
|
|
break;
|
2004-05-20 10:15:31 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* create a socket for sending to remote machine */
|
|
|
|
static gboolean
|
2012-01-26 22:19:33 +00:00
|
|
|
gst_tcp_server_sink_init_send (GstMultiHandleSink * parent)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
2005-12-01 01:21:49 +00:00
|
|
|
GstTCPServerSink *this = GST_TCP_SERVER_SINK (parent);
|
2012-01-16 09:08:24 +00:00
|
|
|
GError *err = NULL;
|
|
|
|
GInetAddress *addr;
|
|
|
|
GSocketAddress *saddr;
|
2012-01-17 10:32:01 +00:00
|
|
|
GResolver *resolver;
|
2012-10-17 10:19:56 +00:00
|
|
|
gint bound_port;
|
2012-01-16 09:08:24 +00:00
|
|
|
|
|
|
|
/* look up name if we need to */
|
|
|
|
addr = g_inet_address_new_from_string (this->host);
|
|
|
|
if (!addr) {
|
|
|
|
GList *results;
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2012-01-17 10:32:01 +00:00
|
|
|
resolver = g_resolver_get_default ();
|
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
results =
|
|
|
|
g_resolver_lookup_by_name (resolver, this->host,
|
|
|
|
this->element.cancellable, &err);
|
|
|
|
if (!results)
|
|
|
|
goto name_resolve;
|
|
|
|
addr = G_INET_ADDRESS (g_object_ref (results->data));
|
2008-05-13 16:02:19 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
g_resolver_free_addresses (results);
|
|
|
|
g_object_unref (resolver);
|
|
|
|
}
|
|
|
|
#ifndef GST_DISABLE_GST_DEBUG
|
|
|
|
{
|
|
|
|
gchar *ip = g_inet_address_to_string (addr);
|
|
|
|
|
|
|
|
GST_DEBUG_OBJECT (this, "IP address for host %s is %s", this->host, ip);
|
|
|
|
g_free (ip);
|
|
|
|
}
|
|
|
|
#endif
|
2012-01-17 11:08:17 +00:00
|
|
|
saddr = g_inet_socket_address_new (addr, this->server_port);
|
|
|
|
g_object_unref (addr);
|
|
|
|
|
|
|
|
/* create the server listener socket */
|
|
|
|
this->server_socket =
|
|
|
|
g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM,
|
|
|
|
G_SOCKET_PROTOCOL_TCP, &err);
|
|
|
|
if (!this->server_socket)
|
|
|
|
goto no_socket;
|
|
|
|
|
|
|
|
GST_DEBUG_OBJECT (this, "opened sending server socket with socket %p",
|
|
|
|
this->server_socket);
|
2004-06-17 09:10:57 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
g_socket_set_blocking (this->server_socket, FALSE);
|
2004-06-17 09:10:57 +00:00
|
|
|
|
|
|
|
/* bind it */
|
|
|
|
GST_DEBUG_OBJECT (this, "binding server socket to address");
|
2012-01-16 09:08:24 +00:00
|
|
|
if (!g_socket_bind (this->server_socket, saddr, TRUE, &err))
|
2008-05-13 16:02:19 +00:00
|
|
|
goto bind_failed;
|
2004-06-17 09:10:57 +00:00
|
|
|
|
2012-01-17 11:08:17 +00:00
|
|
|
g_object_unref (saddr);
|
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
GST_DEBUG_OBJECT (this, "listening on server socket");
|
|
|
|
g_socket_set_listen_backlog (this->server_socket, TCP_BACKLOG);
|
2004-05-20 10:15:31 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
if (!g_socket_listen (this->server_socket, &err))
|
2008-05-13 16:02:19 +00:00
|
|
|
goto listen_failed;
|
|
|
|
|
2012-10-19 17:29:00 +00:00
|
|
|
GST_DEBUG_OBJECT (this, "listened on server socket %p", this->server_socket);
|
2012-01-16 09:08:24 +00:00
|
|
|
|
2012-10-17 10:19:56 +00:00
|
|
|
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");
|
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
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,
|
|
|
|
this->element.cancellable);
|
|
|
|
g_source_set_callback (this->server_source,
|
|
|
|
(GSourceFunc) gst_tcp_server_sink_socket_condition, gst_object_ref (this),
|
|
|
|
(GDestroyNotify) gst_object_unref);
|
|
|
|
g_source_attach (this->server_source, this->element.main_context);
|
gst/tcp/: Abstracted away the select call, implemented poll (yes we ran into the 1024 limit in production).
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstfdset.c: (gst_fdset_mode_get_type), (nearest_pow),
(ensure_size), (gst_fdset_new), (gst_fdset_free),
(gst_fdset_set_mode), (gst_fdset_get_mode), (gst_fdset_add_fd),
(gst_fdset_remove_fd), (gst_fdset_fd_ctl_write),
(gst_fdset_fd_ctl_read), (gst_fdset_fd_has_closed),
(gst_fdset_fd_has_error), (gst_fdset_fd_can_read),
(gst_fdset_fd_can_write), (gst_fdset_wait):
* gst/tcp/gstfdset.h:
* gst/tcp/gstmultifdsink.c: (gst_unit_type_get_type),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_add), (gst_multifdsink_remove),
(gst_multifdsink_clear), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_wait), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Abstracted away the select call, implemented poll (yes we ran into
the 1024 limit in production).
2004-08-11 15:58:48 +00:00
|
|
|
|
2004-05-20 10:15:31 +00:00
|
|
|
return TRUE;
|
2008-05-13 16:02:19 +00:00
|
|
|
|
|
|
|
/* ERRORS */
|
|
|
|
no_socket:
|
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
|
|
|
|
("Failed to create socket: %s", err->message));
|
|
|
|
g_clear_error (&err);
|
2012-01-17 11:08:17 +00:00
|
|
|
g_object_unref (saddr);
|
2008-05-13 16:02:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
name_resolve:
|
2008-05-13 16:02:19 +00:00
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
GST_DEBUG_OBJECT (this, "Cancelled name resolval");
|
|
|
|
} else {
|
|
|
|
GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
|
|
|
|
("Failed to resolve host '%s': %s", this->host, err->message));
|
|
|
|
}
|
|
|
|
g_clear_error (&err);
|
2012-01-17 10:32:01 +00:00
|
|
|
g_object_unref (resolver);
|
2008-05-13 16:02:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
bind_failed:
|
2008-05-13 16:02:19 +00:00
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
GST_DEBUG_OBJECT (this, "Cancelled binding");
|
|
|
|
} else {
|
|
|
|
GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
|
|
|
|
("Failed to bind on host '%s:%d': %s", this->host, this->server_port,
|
|
|
|
err->message));
|
|
|
|
}
|
|
|
|
g_clear_error (&err);
|
|
|
|
g_object_unref (saddr);
|
2012-01-26 22:19:33 +00:00
|
|
|
gst_tcp_server_sink_close (GST_MULTI_HANDLE_SINK (&this->element));
|
2008-05-13 16:02:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
listen_failed:
|
|
|
|
{
|
2012-01-16 09:08:24 +00:00
|
|
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
GST_DEBUG_OBJECT (this, "Cancelled listening");
|
|
|
|
} else {
|
|
|
|
GST_ELEMENT_ERROR (this, RESOURCE, OPEN_READ, (NULL),
|
|
|
|
("Failed to listen on host '%s:%d': %s", this->host,
|
|
|
|
this->server_port, err->message));
|
2008-05-13 16:02:19 +00:00
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
g_clear_error (&err);
|
2012-01-26 22:19:33 +00:00
|
|
|
gst_tcp_server_sink_close (GST_MULTI_HANDLE_SINK (&this->element));
|
2008-05-13 16:02:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|
|
|
|
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
static gboolean
|
2012-01-26 22:19:33 +00:00
|
|
|
gst_tcp_server_sink_close (GstMultiHandleSink * parent)
|
2004-05-20 10:15:31 +00:00
|
|
|
{
|
2005-12-01 01:21:49 +00:00
|
|
|
GstTCPServerSink *this = GST_TCP_SERVER_SINK (parent);
|
gst/tcp/gsttcpserversink.*: Serversink rewrite. Really do non blocking writes to clients and maintain an internal que...
Original commit message from CVS:
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
(gst_tcpserversink_init), (gst_tcpserversink_handle_server_read),
(gst_tcpserversink_client_remove),
(gst_tcpserversink_handle_client_read),
(gst_tcpserversink_client_queue_data),
(gst_tcpserversink_client_queue_caps),
(gst_tcpserversink_client_queue_buffer),
(gst_tcpserversink_handle_client_write),
(gst_tcpserversink_queue_buffer),
(gst_tcpserversink_handle_clients), (gst_tcpserversink_thread),
(gst_tcpserversink_chain), (gst_tcpserversink_set_property),
(gst_tcpserversink_get_property), (gst_tcpserversink_init_send),
(gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Serversink rewrite. Really do non blocking writes to clients and
maintain an internal queue to handle slower clients while not
disturbing fast clients.
2004-06-25 17:06:51 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
if (this->server_source) {
|
|
|
|
g_source_destroy (this->server_source);
|
|
|
|
g_source_unref (this->server_source);
|
|
|
|
this->server_source = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->server_socket) {
|
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
GST_DEBUG_OBJECT (this, "closing socket");
|
2004-09-14 14:03:16 +00:00
|
|
|
|
2012-01-16 09:08:24 +00:00
|
|
|
if (!g_socket_close (this->server_socket, &err)) {
|
|
|
|
GST_ERROR_OBJECT (this, "Failed to close socket: %s", err->message);
|
|
|
|
g_clear_error (&err);
|
|
|
|
}
|
|
|
|
g_object_unref (this->server_socket);
|
|
|
|
this->server_socket = NULL;
|
2012-10-17 10:19:56 +00:00
|
|
|
|
|
|
|
g_atomic_int_set (&this->current_port, 0);
|
|
|
|
g_object_notify (G_OBJECT (this), "current-port");
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|
2012-01-16 09:08:24 +00:00
|
|
|
|
gst/tcp/: Added multifdsink, made tcpserversink a subclass of fdsink, removed one of the locks, added recovery policy...
Original commit message from CVS:
* gst/tcp/Makefile.am:
* gst/tcp/gstmultifdsink.c: (gst_recover_policy_get_type),
(gst_multifdsink_get_type), (gst_multifdsink_base_init),
(gst_multifdsink_class_init), (gst_multifdsink_init),
(gst_multifdsink_debug_fdset), (gst_multifdsink_client_remove),
(gst_multifdsink_handle_client_read),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_handle_client_write),
(gst_multifdsink_recover_client), (gst_multifdsink_queue_buffer),
(gst_multifdsink_handle_clients), (gst_multifdsink_thread),
(gst_multifdsink_chain), (gst_multifdsink_set_property),
(gst_multifdsink_get_property), (gst_multifdsink_init_send),
(gst_multifdsink_close), (gst_multifdsink_change_state):
* gst/tcp/gstmultifdsink.h:
* gst/tcp/gsttcpplugin.c: (plugin_init):
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_get_type),
(gst_tcpserversink_class_init), (gst_tcpserversink_init),
(gst_tcpserversink_handle_server_read),
(gst_tcpserversink_handle_select),
(gst_tcpserversink_set_property), (gst_tcpserversink_get_property),
(gst_tcpserversink_init_send), (gst_tcpserversink_close):
* gst/tcp/gsttcpserversink.h:
Added multifdsink, made tcpserversink a subclass of fdsink, removed
one of the locks, added recovery policy to multifdsink.
2004-06-26 16:49:42 +00:00
|
|
|
return TRUE;
|
2004-05-20 10:15:31 +00:00
|
|
|
}
|