[0.11] gst-plugins-base: multisocketsink: Re-add QoS DSCP property
Sebastian Dröge
slomo at kemper.freedesktop.org
Mon Jan 16 03:17:32 PST 2012
Module: gst-plugins-base
Branch: 0.11
Commit: 7794a113471c67ce6bfa180df0bb2a57d712ae8f
URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=7794a113471c67ce6bfa180df0bb2a57d712ae8f
Author: Sebastian Dröge <sebastian.droege at collabora.co.uk>
Date: Mon Jan 16 12:17:00 2012 +0100
multisocketsink: Re-add QoS DSCP property
---
gst/tcp/gstmultisocketsink.c | 104 ++++++++++++++++++++++++++++++++++++++++++
gst/tcp/gstmultisocketsink.h | 1 +
2 files changed, 105 insertions(+), 0 deletions(-)
diff --git a/gst/tcp/gstmultisocketsink.c b/gst/tcp/gstmultisocketsink.c
index 157f332..8622d3d 100644
--- a/gst/tcp/gstmultisocketsink.c
+++ b/gst/tcp/gstmultisocketsink.c
@@ -113,6 +113,10 @@
#include "gstmultisocketsink.h"
#include "gsttcp-marshal.h"
+#ifndef G_OS_WIN32
+#include <netinet/in.h>
+#endif
+
#define NOT_IMPLEMENTED 0
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -160,6 +164,7 @@ enum
#define DEFAULT_BURST_FORMAT GST_FORMAT_UNDEFINED
#define DEFAULT_BURST_VALUE 0
+#define DEFAULT_QOS_DSCP -1
#define DEFAULT_HANDLE_READ TRUE
#define DEFAULT_RESEND_STREAMHEADER TRUE
@@ -192,6 +197,8 @@ enum
PROP_BURST_FORMAT,
PROP_BURST_VALUE,
+ PROP_QOS_DSCP,
+
PROP_HANDLE_READ,
PROP_RESEND_STREAMHEADER,
@@ -406,6 +413,12 @@ gst_multi_socket_sink_class_init (GstMultiSocketSinkClass * klass)
"The amount of burst expressed in burst-unit", 0, G_MAXUINT64,
DEFAULT_BURST_VALUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_QOS_DSCP,
+ g_param_spec_int ("qos-dscp", "QoS diff srv code point",
+ "Quality of Service, differentiated services code point (-1 default)",
+ -1, 63, DEFAULT_QOS_DSCP,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/**
* GstMultiSocketSink::handle-read
*
@@ -634,6 +647,7 @@ gst_multi_socket_sink_init (GstMultiSocketSink * this)
this->def_burst_format = DEFAULT_BURST_FORMAT;
this->def_burst_value = DEFAULT_BURST_VALUE;
+ this->qos_dscp = DEFAULT_QOS_DSCP;
this->handle_read = DEFAULT_HANDLE_READ;
this->resend_streamheader = DEFAULT_RESEND_STREAMHEADER;
@@ -661,6 +675,87 @@ gst_multi_socket_sink_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gint
+setup_dscp_client (GstMultiSocketSink * sink, GstSocketClient * client)
+{
+#ifndef IP_TOS
+ return 0;
+#else
+ gint tos;
+ gint ret;
+ int fd;
+ union gst_sockaddr
+ {
+ struct sockaddr sa;
+ struct sockaddr_in6 sa_in6;
+ struct sockaddr_storage sa_stor;
+ } sa;
+ socklen_t slen = sizeof (sa);
+ gint af;
+
+ /* don't touch */
+ if (sink->qos_dscp < 0)
+ return 0;
+
+ fd = g_socket_get_fd (client->socket);
+
+ if ((ret = getsockname (fd, &sa.sa, &slen)) < 0) {
+ GST_DEBUG_OBJECT (sink, "could not get sockname: %s", g_strerror (errno));
+ return ret;
+ }
+
+ af = sa.sa.sa_family;
+
+ /* if this is an IPv4-mapped address then do IPv4 QoS */
+ if (af == AF_INET6) {
+
+ GST_DEBUG_OBJECT (sink, "check IP6 socket");
+ if (IN6_IS_ADDR_V4MAPPED (&(sa.sa_in6.sin6_addr))) {
+ GST_DEBUG_OBJECT (sink, "mapped to IPV4");
+ af = AF_INET;
+ }
+ }
+
+ /* extract and shift 6 bits of the DSCP */
+ tos = (sink->qos_dscp & 0x3f) << 2;
+
+ switch (af) {
+ case AF_INET:
+ ret = setsockopt (fd, IPPROTO_IP, IP_TOS, &tos, sizeof (tos));
+ break;
+ case AF_INET6:
+#ifdef IPV6_TCLASS
+ ret = setsockopt (fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof (tos));
+ break;
+#endif
+ default:
+ ret = 0;
+ GST_ERROR_OBJECT (sink, "unsupported AF");
+ break;
+ }
+ if (ret)
+ GST_DEBUG_OBJECT (sink, "could not set DSCP: %s", g_strerror (errno));
+
+ return ret;
+#endif
+}
+
+static void
+setup_dscp (GstMultiSocketSink * sink)
+{
+ GList *clients;
+
+ CLIENTS_LOCK (sink);
+ for (clients = sink->clients; clients; clients = clients->next) {
+ GstSocketClient *client;
+
+ client = clients->data;
+
+ setup_dscp_client (sink, client);
+ }
+ CLIENTS_UNLOCK (sink);
+}
+
/* "add-full" signal implementation */
void
gst_multi_socket_sink_add_full (GstMultiSocketSink * sink, GSocket * socket,
@@ -736,6 +831,8 @@ gst_multi_socket_sink_add_full (GstMultiSocketSink * sink, GSocket * socket,
g_source_attach (client->source, sink->main_context);
}
+ setup_dscp_client (sink, client);
+
CLIENTS_UNLOCK (sink);
g_signal_emit (G_OBJECT (sink),
@@ -2383,6 +2480,10 @@ gst_multi_socket_sink_set_property (GObject * object, guint prop_id,
case PROP_BURST_VALUE:
multisocketsink->def_burst_value = g_value_get_uint64 (value);
break;
+ case PROP_QOS_DSCP:
+ multisocketsink->qos_dscp = g_value_get_int (value);
+ setup_dscp (multisocketsink);
+ break;
case PROP_HANDLE_READ:
multisocketsink->handle_read = g_value_get_boolean (value);
break;
@@ -2459,6 +2560,9 @@ gst_multi_socket_sink_get_property (GObject * object, guint prop_id,
case PROP_BURST_VALUE:
g_value_set_uint64 (value, multisocketsink->def_burst_value);
break;
+ case PROP_QOS_DSCP:
+ g_value_set_int (value, multisocketsink->qos_dscp);
+ break;
case PROP_HANDLE_READ:
g_value_set_boolean (value, multisocketsink->handle_read);
break;
diff --git a/gst/tcp/gstmultisocketsink.h b/gst/tcp/gstmultisocketsink.h
index 051b4d5..f373d90 100644
--- a/gst/tcp/gstmultisocketsink.h
+++ b/gst/tcp/gstmultisocketsink.h
@@ -190,6 +190,7 @@ struct _GstMultiSocketSink {
gboolean previous_buffer_in_caps;
guint mtu;
+ gint qos_dscp;
gboolean handle_read;
GArray *bufqueue; /* global queue of buffers */
More information about the gstreamer-commits
mailing list