gstudpsink.c 7.23 KB
Newer Older
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
1
/* GStreamer
2
 * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * 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
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
19 20 21 22 23 24 25 26 27 28 29 30 31 32
/**
 * SECTION:element-udpsink
 * @see_also: udpsrc, multifdsink
 *
 * udpsink is a network sink that sends UDP packets to the network.
 * It can be combined with RTP payloaders to implement RTP streaming.
 *
 * <refsect2>
 * <title>Examples</title>
 * |[
 * gst-launch -v audiotestsrc ! udpsink
 * ]|
 * </refsect2>
 */
33 34 35
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
36 37
#include "gstudpsink.h"

38 39 40 41 42 43 44 45
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <string.h>

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
46 47
#define UDP_DEFAULT_HOST        "localhost"
#define UDP_DEFAULT_PORT        4951
Wim Taymans's avatar
Wim Taymans committed
48

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
49
/* UDPSink signals and args */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
50 51
enum
{
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
52 53 54 55
  /* FILL ME */
  LAST_SIGNAL
};

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
56 57
enum
{
58 59 60 61
  PROP_0,
  PROP_HOST,
  PROP_PORT,
  PROP_URI,
62
  /* FILL ME */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
63 64
};

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
65 66 67
static void gst_udpsink_base_init (gpointer g_class);
static void gst_udpsink_class_init (GstUDPSink * klass);
static void gst_udpsink_init (GstUDPSink * udpsink);
68
static void gst_udpsink_finalize (GstUDPSink * udpsink);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
69

70 71 72
static void gst_udpsink_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
73 74 75 76
static void gst_udpsink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_udpsink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
77 78

static GstElementClass *parent_class = NULL;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
79

80
/*static guint gst_udpsink_signals[LAST_SIGNAL] = { 0 }; */
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
81 82 83 84 85 86 87 88

GType
gst_udpsink_get_type (void)
{
  static GType udpsink_type = 0;

  if (!udpsink_type) {
    static const GTypeInfo udpsink_info = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
89
      sizeof (GstUDPSinkClass),
Benjamin Otte's avatar
Benjamin Otte committed
90
      gst_udpsink_base_init,
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
91
      NULL,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
92
      (GClassInitFunc) gst_udpsink_class_init,
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
93 94
      NULL,
      NULL,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
95
      sizeof (GstUDPSink),
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
96
      0,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
97
      (GInstanceInitFunc) gst_udpsink_init,
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
98 99
      NULL
    };
100 101 102 103 104
    static const GInterfaceInfo urihandler_info = {
      gst_udpsink_uri_handler_init,
      NULL,
      NULL
    };
105

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
106
    udpsink_type =
107 108
        g_type_register_static (GST_TYPE_MULTIUDPSINK, "GstUDPSink",
        &udpsink_info, 0);
109 110 111 112

    g_type_add_interface_static (udpsink_type, GST_TYPE_URI_HANDLER,
        &urihandler_info);

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
113 114 115 116
  }
  return udpsink_type;
}

Benjamin Otte's avatar
Benjamin Otte committed
117 118 119 120 121
static void
gst_udpsink_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

122 123 124
  gst_element_class_set_details_simple (element_class, "UDP packet sender",
      "Sink/Network",
      "Send data over the network via UDP", "Wim Taymans <wim@fluendo.com>");
Benjamin Otte's avatar
Benjamin Otte committed
125 126
}

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
127
static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
128
gst_udpsink_class_init (GstUDPSink * klass)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
129 130 131
{
  GObjectClass *gobject_class;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
132
  gobject_class = (GObjectClass *) klass;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
133

134
  parent_class = g_type_class_peek_parent (klass);
Wim Taymans's avatar
Wim Taymans committed
135 136 137

  gobject_class->set_property = gst_udpsink_set_property;
  gobject_class->get_property = gst_udpsink_get_property;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
138

139 140
  gobject_class->finalize = (GObjectFinalizeFunc) gst_udpsink_finalize;

141
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HOST,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
142
      g_param_spec_string ("host", "host",
143 144
          "The host/IP/Multicast group to send the packets to",
          UDP_DEFAULT_HOST, G_PARAM_READWRITE));
145
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PORT,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
146
      g_param_spec_int ("port", "port", "The port to send the packets to",
147
          0, 65535, UDP_DEFAULT_PORT, G_PARAM_READWRITE));
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
148 149
}

Zeeshan Ali's avatar
Zeeshan Ali committed
150

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
151
static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
152
gst_udpsink_init (GstUDPSink * udpsink)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
153
{
Wim Taymans's avatar
Wim Taymans committed
154 155 156 157
  gst_udp_uri_init (&udpsink->uri, UDP_DEFAULT_HOST, UDP_DEFAULT_PORT);

  gst_multiudpsink_add (GST_MULTIUDPSINK (udpsink), udpsink->uri.host,
      udpsink->uri.port);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
158 159
}

160 161 162
static void
gst_udpsink_finalize (GstUDPSink * udpsink)
{
Wim Taymans's avatar
Wim Taymans committed
163 164
  gst_udp_uri_free (&udpsink->uri);
  g_free (udpsink->uristr);
165 166 167 168

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) udpsink);
}

169 170
static gboolean
gst_udpsink_set_uri (GstUDPSink * sink, const gchar * uri)
Wim Taymans's avatar
Wim Taymans committed
171
{
Wim Taymans's avatar
Wim Taymans committed
172 173
  gst_multiudpsink_remove (GST_MULTIUDPSINK (sink), sink->uri.host,
      sink->uri.port);
174

Wim Taymans's avatar
Wim Taymans committed
175 176
  if (gst_udp_parse_uri (uri, &sink->uri) < 0)
    goto wrong_uri;
177

Wim Taymans's avatar
Wim Taymans committed
178 179
  gst_multiudpsink_add (GST_MULTIUDPSINK (sink), sink->uri.host,
      sink->uri.port);
180 181 182 183

  return TRUE;

  /* ERRORS */
Wim Taymans's avatar
Wim Taymans committed
184
wrong_uri:
185 186
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, READ, (NULL),
Wim Taymans's avatar
Wim Taymans committed
187
        ("error parsing uri %s", uri));
188 189
    return FALSE;
  }
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
190 191 192
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
193 194
gst_udpsink_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
195 196 197
{
  GstUDPSink *udpsink;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
198
  udpsink = GST_UDPSINK (object);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
199

200 201
  /* remove old host */
  gst_multiudpsink_remove (GST_MULTIUDPSINK (udpsink),
Wim Taymans's avatar
Wim Taymans committed
202
      udpsink->uri.host, udpsink->uri.port);
203

Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
204
  switch (prop_id) {
205
    case PROP_HOST:
Wim Taymans's avatar
Wim Taymans committed
206 207 208 209 210 211 212 213 214
    {
      const gchar *host;

      host = g_value_get_string (value);

      if (host)
        gst_udp_uri_update (&udpsink->uri, host, -1);
      else
        gst_udp_uri_update (&udpsink->uri, UDP_DEFAULT_HOST, -1);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
215
      break;
Wim Taymans's avatar
Wim Taymans committed
216
    }
217
    case PROP_PORT:
Wim Taymans's avatar
Wim Taymans committed
218
      gst_udp_uri_update (&udpsink->uri, NULL, g_value_get_int (value));
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
219 220
      break;
    default:
221
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
222 223
      break;
  }
224 225
  /* add new host */
  gst_multiudpsink_add (GST_MULTIUDPSINK (udpsink),
Wim Taymans's avatar
Wim Taymans committed
226
      udpsink->uri.host, udpsink->uri.port);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
227 228 229
}

static void
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
230 231
gst_udpsink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
232 233 234
{
  GstUDPSink *udpsink;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
235
  udpsink = GST_UDPSINK (object);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
236 237

  switch (prop_id) {
238
    case PROP_HOST:
Wim Taymans's avatar
Wim Taymans committed
239
      g_value_set_string (value, udpsink->uri.host);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
240
      break;
241
    case PROP_PORT:
Wim Taymans's avatar
Wim Taymans committed
242
      g_value_set_int (value, udpsink->uri.port);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
243 244 245 246 247 248 249
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

250
/*** GSTURIHANDLER INTERFACE *************************************************/
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
251

252
static GstURIType
253
gst_udpsink_uri_get_type (void)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
254
{
255
  return GST_URI_SINK;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
256
}
257

258 259
static gchar **
gst_udpsink_uri_get_protocols (void)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
260
{
261
  static gchar *protocols[] = { (char *) "udp", NULL };
262 263

  return protocols;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
264 265
}

266 267
static const gchar *
gst_udpsink_uri_get_uri (GstURIHandler * handler)
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
268
{
269
  GstUDPSink *sink = GST_UDPSINK (handler);
Wim Taymans's avatar
Wim Taymans committed
270

Wim Taymans's avatar
Wim Taymans committed
271 272 273 274
  g_free (sink->uristr);
  sink->uristr = gst_udp_uri_string (&sink->uri);

  return sink->uristr;
275
}
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
276

277 278 279 280 281
static gboolean
gst_udpsink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gboolean ret;
  GstUDPSink *sink = GST_UDPSINK (handler);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
282

283
  ret = gst_udpsink_set_uri (sink, uri);
Wim Taymans's avatar
Wim Taymans committed
284 285

  return ret;
286
}
Wim Taymans's avatar
Wim Taymans committed
287

288 289 290 291 292 293 294 295 296
static void
gst_udpsink_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = gst_udpsink_uri_get_type;
  iface->get_protocols = gst_udpsink_uri_get_protocols;
  iface->get_uri = gst_udpsink_uri_get_uri;
  iface->set_uri = gst_udpsink_uri_set_uri;
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
297
}