summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2017-01-31 20:56:59 +1100
committerMatthew Waters <matthew@centricular.com>2018-02-02 15:02:21 +1100
commit1894293d6378c69548d974d2965e9decc1527654 (patch)
tree2aebde896fb4f411bb30cc9275161942cd9464ac /gst-libs
parent94a7bf9ede14494ffdc73677eeb980a0cf2490e7 (diff)
webrtcbin: an element that handles the transport aspects of webrtc connections
SDP's are generated and consumed according to the W3C PeerConnection API available from https://www.w3.org/TR/webrtc/ The SDP is either created initially from the connected sink pads/attached transceivers as in the case of generating an offer or intersected with the connected sink pads/attached transceivers as in the case for creating an answer. In both cases, the rtp payloaded streams sent by the peer are exposed as separate src pads. The implementation supports trickle ICE, RTCP muxing, reduced size RTCP. With contributions from: Nirbheek Chauhan <nirbheek@centricular.com> Mathieu Duponchelle <mathieu@centricular.com> Edward Hervey <edward@centricular.com> https://bugzilla.gnome.org/show_bug.cgi?id=792523
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/Makefile.am4
-rw-r--r--gst-libs/gst/meson.build1
-rw-r--r--gst-libs/gst/webrtc/Makefile.am54
-rw-r--r--gst-libs/gst/webrtc/dtlstransport.c238
-rw-r--r--gst-libs/gst/webrtc/dtlstransport.h70
-rw-r--r--gst-libs/gst/webrtc/icetransport.c204
-rw-r--r--gst-libs/gst/webrtc/icetransport.h76
-rw-r--r--gst-libs/gst/webrtc/meson.build59
-rw-r--r--gst-libs/gst/webrtc/rtcsessiondescription.c123
-rw-r--r--gst-libs/gst/webrtc/rtcsessiondescription.h58
-rw-r--r--gst-libs/gst/webrtc/rtpreceiver.c135
-rw-r--r--gst-libs/gst/webrtc/rtpreceiver.h76
-rw-r--r--gst-libs/gst/webrtc/rtpsender.c141
-rw-r--r--gst-libs/gst/webrtc/rtpsender.h77
-rw-r--r--gst-libs/gst/webrtc/rtptransceiver.c186
-rw-r--r--gst-libs/gst/webrtc/rtptransceiver.h69
-rw-r--r--gst-libs/gst/webrtc/webrtc.h33
-rw-r--r--gst-libs/gst/webrtc/webrtc_fwd.h251
-rwxr-xr-xgst-libs/gst/webrtc/webrtc_mkenum.py55
19 files changed, 1908 insertions, 2 deletions
diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am
index ae541aaf8..db67fc89f 100644
--- a/gst-libs/gst/Makefile.am
+++ b/gst-libs/gst/Makefile.am
@@ -7,12 +7,12 @@ OPENCV_DIR=opencv
endif
SUBDIRS = uridownloader adaptivedemux interfaces basecamerabinsrc codecparsers \
- insertbin mpegts video audio player isoff $(WAYLAND_DIR) \
+ insertbin mpegts video audio player isoff webrtc $(WAYLAND_DIR) \
$(OPENCV_DIR)
noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h
DIST_SUBDIRS = uridownloader adaptivedemux interfaces basecamerabinsrc \
- codecparsers insertbin mpegts wayland opencv video audio player isoff
+ codecparsers insertbin mpegts wayland opencv video audio player isoff webrtc
adaptivedemux: uridownloader
diff --git a/gst-libs/gst/meson.build b/gst-libs/gst/meson.build
index aac5398af..2e579540e 100644
--- a/gst-libs/gst/meson.build
+++ b/gst-libs/gst/meson.build
@@ -12,3 +12,4 @@ subdir('opencv')
subdir('player')
subdir('video')
subdir('wayland')
+subdir('webrtc')
diff --git a/gst-libs/gst/webrtc/Makefile.am b/gst-libs/gst/webrtc/Makefile.am
new file mode 100644
index 000000000..49bb95a01
--- /dev/null
+++ b/gst-libs/gst/webrtc/Makefile.am
@@ -0,0 +1,54 @@
+lib_LTLIBRARIES = libgstwebrtc-@GST_API_VERSION@.la
+
+glib_enum_headers = dtlstransport.h icetransport.h rtptransceiver.h webrtc_fwd.h
+glib_enum_define = GST_WEBRTC
+glib_gen_prefix = gst_webrtc
+glib_gen_basename = webrtc
+glib_gen_decl_banner=GST_EXPORT
+
+built_sources = webrtc-enumtypes.c
+built_headers = webrtc-enumtypes.h
+BUILT_SOURCES = $(built_sources) $(built_headers)
+CLEANFILES = $(BUILT_SOURCES)
+
+libgstwebrtc_@GST_API_VERSION@_la_SOURCES = \
+ dtlstransport.c \
+ icetransport.c \
+ rtcsessiondescription.c \
+ rtpreceiver.c \
+ rtpsender.c \
+ rtptransceiver.c
+
+nodist_libgstwebrtc_@GST_API_VERSION@_la_SOURCES = $(built_sources)
+
+libgstwebrtc_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/webrtc
+libgstwebrtc_@GST_API_VERSION@include_HEADERS = \
+ dtlstransport.h \
+ icetransport.h \
+ rtcsessiondescription.h \
+ rtpreceiver.h \
+ rtpsender.h \
+ rtptransceiver.h \
+ webrtc_fwd.h \
+ webrtc.h
+
+nodist_libgstwebrtc_@GST_API_VERSION@include_HEADERS = $(built_headers)
+
+libgstwebrtc_@GST_API_VERSION@_la_CFLAGS = \
+ -I$(top_builddir)/gst-libs \
+ -I$(top_srcdir)/gst-libs \
+ $(GST_PLUGINS_BASE_CFLAGS) \
+ $(GST_BASE_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(GST_SDP_CFLAGS)
+libgstwebrtc_@GST_API_VERSION@_la_LIBADD = \
+ $(GST_PLUGINS_BASE_LIBS) \
+ $(GST_BASE_LIBS) \
+ $(GST_LIBS) \
+ $(GST_SDP_LIBS)
+libgstwebrtc_@GST_API_VERSION@_la_LDFLAGS = \
+ $(GST_LIB_LDFLAGS) \
+ $(GST_ALL_LDFLAGS) \
+ $(GST_LT_LDFLAGS)
+
+include $(top_srcdir)/common/gst-glib-gen.mak
diff --git a/gst-libs/gst/webrtc/dtlstransport.c b/gst-libs/gst/webrtc/dtlstransport.c
new file mode 100644
index 000000000..31324c34d
--- /dev/null
+++ b/gst-libs/gst/webrtc/dtlstransport.c
@@ -0,0 +1,238 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-dtlstransport
+ * @short_description: RTCDtlsTransport object
+ * @title: GstWebRTCDTLSTransport
+ * @see_also: #GstWebRTCRTPSender, #GstWebRTCRTPReceiver, #GstWebRTCICETransport
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcdtlstransport">https://www.w3.org/TR/webrtc/#rtcdtlstransport</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dtlstransport.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_dtls_transport_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define gst_webrtc_dtls_transport_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstWebRTCDTLSTransport, gst_webrtc_dtls_transport,
+ GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_dtls_transport_debug,
+ "dtlstransport", 0, "dtlstransport");
+ );
+
+enum
+{
+ SIGNAL_0,
+ LAST_SIGNAL,
+};
+
+enum
+{
+ PROP_0,
+ PROP_SESSION_ID,
+ PROP_TRANSPORT,
+ PROP_STATE,
+ PROP_CLIENT,
+ PROP_CERTIFICATE,
+ PROP_REMOTE_CERTIFICATE,
+ PROP_RTCP,
+};
+
+void
+gst_webrtc_dtls_transport_set_transport (GstWebRTCDTLSTransport * transport,
+ GstWebRTCICETransport * ice)
+{
+ g_return_if_fail (GST_IS_WEBRTC_DTLS_TRANSPORT (transport));
+ g_return_if_fail (GST_IS_WEBRTC_ICE_TRANSPORT (ice));
+
+ gst_object_replace ((GstObject **) & transport->transport, GST_OBJECT (ice));
+}
+
+static void
+gst_webrtc_dtls_transport_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCDTLSTransport *webrtc = GST_WEBRTC_DTLS_TRANSPORT (object);
+
+ switch (prop_id) {
+ case PROP_SESSION_ID:
+ webrtc->session_id = g_value_get_uint (value);
+ break;
+ case PROP_CLIENT:
+ g_object_set_property (G_OBJECT (webrtc->dtlssrtpenc), "is-client",
+ value);
+ gst_element_set_locked_state (webrtc->dtlssrtpenc, FALSE);
+ gst_element_sync_state_with_parent (webrtc->dtlssrtpenc);
+ break;
+ case PROP_CERTIFICATE:
+ g_object_set_property (G_OBJECT (webrtc->dtlssrtpdec), "pem", value);
+ break;
+ case PROP_RTCP:
+ webrtc->is_rtcp = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_dtls_transport_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCDTLSTransport *webrtc = GST_WEBRTC_DTLS_TRANSPORT (object);
+
+ switch (prop_id) {
+ case PROP_SESSION_ID:
+ g_value_set_uint (value, webrtc->session_id);
+ break;
+ case PROP_TRANSPORT:
+ g_value_set_object (value, webrtc->transport);
+ break;
+ case PROP_STATE:
+ g_value_set_enum (value, webrtc->state);
+ break;
+ case PROP_CLIENT:
+ g_object_get_property (G_OBJECT (webrtc->dtlssrtpenc), "is-client",
+ value);
+ break;
+ case PROP_CERTIFICATE:
+ g_object_get_property (G_OBJECT (webrtc->dtlssrtpdec), "pem", value);
+ break;
+ case PROP_REMOTE_CERTIFICATE:
+ g_object_get_property (G_OBJECT (webrtc->dtlssrtpdec), "peer-pem", value);
+ break;
+ case PROP_RTCP:
+ g_value_set_boolean (value, webrtc->is_rtcp);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_dtls_transport_finalize (GObject * object)
+{
+ GstWebRTCDTLSTransport *webrtc = GST_WEBRTC_DTLS_TRANSPORT (object);
+
+ if (webrtc->transport) {
+ gst_object_unref (webrtc->transport);
+ }
+ webrtc->transport = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_webrtc_dtls_transport_constructed (GObject * object)
+{
+ GstWebRTCDTLSTransport *webrtc = GST_WEBRTC_DTLS_TRANSPORT (object);
+ gchar *connection_id;
+
+ /* XXX: this may collide with another connection_id however this is only a
+ * problem if multiple dtls element sets are being used within the same
+ * process */
+ connection_id = g_strdup_printf ("%s_%u_%u", webrtc->is_rtcp ? "rtcp" : "rtp",
+ webrtc->session_id, g_random_int ());
+
+ webrtc->dtlssrtpenc = gst_element_factory_make ("dtlssrtpenc", NULL);
+ g_object_set (webrtc->dtlssrtpenc, "connection-id", connection_id,
+ "is-client", webrtc->client, NULL);
+
+ webrtc->dtlssrtpdec = gst_element_factory_make ("dtlssrtpdec", NULL);
+ g_object_set (webrtc->dtlssrtpdec, "connection-id", connection_id, NULL);
+ g_free (connection_id);
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+}
+
+static void
+gst_webrtc_dtls_transport_class_init (GstWebRTCDTLSTransportClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->constructed = gst_webrtc_dtls_transport_constructed;
+ gobject_class->get_property = gst_webrtc_dtls_transport_get_property;
+ gobject_class->set_property = gst_webrtc_dtls_transport_set_property;
+ gobject_class->finalize = gst_webrtc_dtls_transport_finalize;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SESSION_ID,
+ g_param_spec_uint ("session-id", "Session ID",
+ "Unique session ID", 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TRANSPORT,
+ g_param_spec_object ("transport", "ICE transport",
+ "ICE transport used by this dtls transport",
+ GST_TYPE_WEBRTC_ICE_TRANSPORT,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /* FIXME: implement */
+ g_object_class_install_property (gobject_class,
+ PROP_STATE,
+ g_param_spec_enum ("state", "DTLS state",
+ "State of the DTLS transport",
+ GST_TYPE_WEBRTC_DTLS_TRANSPORT_STATE,
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CLIENT,
+ g_param_spec_boolean ("client", "DTLS client",
+ "Are we the client in the DTLS handshake?", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CERTIFICATE,
+ g_param_spec_string ("certificate", "DTLS certificate",
+ "DTLS certificate", NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_REMOTE_CERTIFICATE,
+ g_param_spec_string ("remote-certificate", "Remote DTLS certificate",
+ "Remote DTLS certificate", NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_RTCP,
+ g_param_spec_boolean ("rtcp", "RTCP",
+ "The transport is being used solely for RTCP", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_webrtc_dtls_transport_init (GstWebRTCDTLSTransport * webrtc)
+{
+}
+
+GstWebRTCDTLSTransport *
+gst_webrtc_dtls_transport_new (guint session_id, gboolean is_rtcp)
+{
+ return g_object_new (GST_TYPE_WEBRTC_DTLS_TRANSPORT, "session-id", session_id,
+ "rtcp", is_rtcp, NULL);
+}
diff --git a/gst-libs/gst/webrtc/dtlstransport.h b/gst-libs/gst/webrtc/dtlstransport.h
new file mode 100644
index 000000000..366a602a2
--- /dev/null
+++ b/gst-libs/gst/webrtc/dtlstransport.h
@@ -0,0 +1,70 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_DTLS_TRANSPORT_H__
+#define __GST_WEBRTC_DTLS_TRANSPORT_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+#include <gst/webrtc/icetransport.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+GType gst_webrtc_dtls_transport_get_type(void);
+#define GST_TYPE_WEBRTC_DTLS_TRANSPORT (gst_webrtc_dtls_transport_get_type())
+#define GST_WEBRTC_DTLS_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_DTLS_TRANSPORT,GstWebRTCDTLSTransport))
+#define GST_IS_WEBRTC_DTLS_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_DTLS_TRANSPORT))
+#define GST_WEBRTC_DTLS_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_DTLS_TRANSPORT,GstWebRTCDTLSTransportClass))
+#define GST_IS_WEBRTC_DTLS_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_DTLS_TRANSPORT))
+#define GST_WEBRTC_DTLS_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_DTLS_TRANSPORT,GstWebRTCDTLSTransportClass))
+
+struct _GstWebRTCDTLSTransport
+{
+ GstObject parent;
+
+ GstWebRTCICETransport *transport;
+ GstWebRTCDTLSTransportState state;
+
+ gboolean is_rtcp;
+ gboolean client;
+ guint session_id;
+ GstElement *dtlssrtpenc;
+ GstElement *dtlssrtpdec;
+
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstWebRTCDTLSTransportClass
+{
+ GstBinClass parent_class;
+
+ gpointer _padding[GST_PADDING];
+};
+
+GST_EXPORT
+GstWebRTCDTLSTransport * gst_webrtc_dtls_transport_new (guint session_id, gboolean rtcp);
+
+GST_EXPORT
+void gst_webrtc_dtls_transport_set_transport (GstWebRTCDTLSTransport * transport,
+ GstWebRTCICETransport * ice);
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_DTLS_TRANSPORT_H__ */
diff --git a/gst-libs/gst/webrtc/icetransport.c b/gst-libs/gst/webrtc/icetransport.c
new file mode 100644
index 000000000..d5ed0605e
--- /dev/null
+++ b/gst-libs/gst/webrtc/icetransport.c
@@ -0,0 +1,204 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-icetransport
+ * @short_description: RTCIceTransport object
+ * @title: GstWebRTCICETransport
+ * @see_also: #GstWebRTCRTPSender, #GstWebRTCRTPReceiver, #GstWebRTCDTLSTransport
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcicetransport">https://www.w3.org/TR/webrtc/#rtcicetransport</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "icetransport.h"
+#include "webrtc-enumtypes.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_ice_transport_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define gst_webrtc_ice_transport_parent_class parent_class
+/* We would inherit from GstBin however when combined with the dtls transport,
+ * this causes loops in the graph. */
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCICETransport,
+ gst_webrtc_ice_transport, GST_TYPE_OBJECT,
+ GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_transport_debug,
+ "webrtcicetransport", 0, "webrtcicetransport"););
+
+enum
+{
+ SIGNAL_0,
+ ON_SELECTED_CANDIDATE_PAIR_CHANGE_SIGNAL,
+ ON_NEW_CANDIDATE_SIGNAL,
+ LAST_SIGNAL,
+};
+
+enum
+{
+ PROP_0,
+ PROP_COMPONENT,
+ PROP_STATE,
+ PROP_GATHERING_STATE,
+};
+
+static guint gst_webrtc_ice_transport_signals[LAST_SIGNAL] = { 0 };
+
+void
+gst_webrtc_ice_transport_connection_state_change (GstWebRTCICETransport * ice,
+ GstWebRTCICEConnectionState new_state)
+{
+ ice->state = new_state;
+ g_object_notify (G_OBJECT (ice), "state");
+}
+
+void
+gst_webrtc_ice_transport_gathering_state_change (GstWebRTCICETransport * ice,
+ GstWebRTCICEGatheringState new_state)
+{
+ ice->gathering_state = new_state;
+ g_object_notify (G_OBJECT (ice), "gathering-state");
+}
+
+void
+gst_webrtc_ice_transport_selected_pair_change (GstWebRTCICETransport * ice)
+{
+ g_signal_emit (ice,
+ gst_webrtc_ice_transport_signals
+ [ON_SELECTED_CANDIDATE_PAIR_CHANGE_SIGNAL], 0);
+}
+
+void
+gst_webrtc_ice_transport_new_candidate (GstWebRTCICETransport * ice,
+ guint stream_id, GstWebRTCICEComponent component, gchar * attr)
+{
+ g_signal_emit (ice, gst_webrtc_ice_transport_signals[ON_NEW_CANDIDATE_SIGNAL],
+ stream_id, component, attr);
+}
+
+static void
+gst_webrtc_ice_transport_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCICETransport *webrtc = GST_WEBRTC_ICE_TRANSPORT (object);
+
+ switch (prop_id) {
+ case PROP_COMPONENT:
+ webrtc->component = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_ice_transport_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCICETransport *webrtc = GST_WEBRTC_ICE_TRANSPORT (object);
+
+ switch (prop_id) {
+ case PROP_COMPONENT:
+ g_value_set_enum (value, webrtc->component);
+ break;
+ case PROP_STATE:
+ g_value_set_enum (value, webrtc->state);
+ break;
+ case PROP_GATHERING_STATE:
+ g_value_set_enum (value, webrtc->gathering_state);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_ice_transport_finalize (GObject * object)
+{
+// GstWebRTCICETransport *webrtc = GST_WEBRTC_ICE_TRANSPORT (object);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_webrtc_ice_transport_constructed (GObject * object)
+{
+// GstWebRTCICETransport *webrtc = GST_WEBRTC_ICE_TRANSPORT (object);
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+}
+
+static void
+gst_webrtc_ice_transport_class_init (GstWebRTCICETransportClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->constructed = gst_webrtc_ice_transport_constructed;
+ gobject_class->get_property = gst_webrtc_ice_transport_get_property;
+ gobject_class->set_property = gst_webrtc_ice_transport_set_property;
+ gobject_class->finalize = gst_webrtc_ice_transport_finalize;
+
+ g_object_class_install_property (gobject_class,
+ PROP_COMPONENT,
+ g_param_spec_enum ("component",
+ "ICE component", "The ICE component of this transport",
+ GST_TYPE_WEBRTC_ICE_COMPONENT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STATE,
+ g_param_spec_enum ("state",
+ "ICE connection state", "The ICE connection state of this transport",
+ GST_TYPE_WEBRTC_ICE_CONNECTION_STATE, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_GATHERING_STATE,
+ g_param_spec_enum ("gathering-state",
+ "ICE gathering state", "The ICE gathering state of this transport",
+ GST_TYPE_WEBRTC_ICE_GATHERING_STATE, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstWebRTC::on-selected_candidate-pair-change:
+ * @object: the #GstWebRTCICETransport
+ */
+ gst_webrtc_ice_transport_signals[ON_SELECTED_CANDIDATE_PAIR_CHANGE_SIGNAL] =
+ g_signal_new ("on-selected-candidate-pair-change",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_generic, G_TYPE_NONE, 0);
+
+ /**
+ * GstWebRTC::on-new-candidate:
+ * @object: the #GstWebRTCICETransport
+ */
+ gst_webrtc_ice_transport_signals[ON_NEW_CANDIDATE_SIGNAL] =
+ g_signal_new ("on-new-candidate",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+gst_webrtc_ice_transport_init (GstWebRTCICETransport * webrtc)
+{
+}
diff --git a/gst-libs/gst/webrtc/icetransport.h b/gst-libs/gst/webrtc/icetransport.h
new file mode 100644
index 000000000..30730fa9b
--- /dev/null
+++ b/gst-libs/gst/webrtc/icetransport.h
@@ -0,0 +1,76 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_ICE_TRANSPORT_H__
+#define __GST_WEBRTC_ICE_TRANSPORT_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+GType gst_webrtc_ice_transport_get_type(void);
+#define GST_TYPE_WEBRTC_ICE_TRANSPORT (gst_webrtc_ice_transport_get_type())
+#define GST_WEBRTC_ICE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_ICE_TRANSPORT,GstWebRTCICETransport))
+#define GST_IS_WEBRTC_ICE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_ICE_TRANSPORT))
+#define GST_WEBRTC_ICE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_ICE_TRANSPORT,GstWebRTCICETransportClass))
+#define GST_IS_WEBRTC_ICE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_ICE_TRANSPORT))
+#define GST_WEBRTC_ICE_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_ICE_TRANSPORT,GstWebRTCICETransportClass))
+
+struct _GstWebRTCICETransport
+{
+ GstObject parent;
+
+ GstWebRTCIceRole role;
+ GstWebRTCICEComponent component;
+
+ GstWebRTCICEConnectionState state;
+ GstWebRTCICEGatheringState gathering_state;
+
+ /* Filled by subclasses */
+ GstElement *src;
+ GstElement *sink;
+
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstWebRTCICETransportClass
+{
+ GstBinClass parent_class;
+
+ gboolean (*gather_candidates) (GstWebRTCICETransport * transport);
+
+ gpointer _padding[GST_PADDING];
+};
+
+GST_EXPORT
+void gst_webrtc_ice_transport_connection_state_change (GstWebRTCICETransport * ice,
+ GstWebRTCICEConnectionState new_state);
+GST_EXPORT
+void gst_webrtc_ice_transport_gathering_state_change (GstWebRTCICETransport * ice,
+ GstWebRTCICEGatheringState new_state);
+GST_EXPORT
+void gst_webrtc_ice_transport_selected_pair_change (GstWebRTCICETransport * ice);
+GST_EXPORT
+void gst_webrtc_ice_transport_new_candidate (GstWebRTCICETransport * ice, guint stream_id, GstWebRTCICEComponent component, gchar * attr);
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_ICE_TRANSPORT_H__ */
diff --git a/gst-libs/gst/webrtc/meson.build b/gst-libs/gst/webrtc/meson.build
new file mode 100644
index 000000000..c670eadb5
--- /dev/null
+++ b/gst-libs/gst/webrtc/meson.build
@@ -0,0 +1,59 @@
+webrtc_sources = [
+ 'dtlstransport.c',
+ 'icetransport.c',
+ 'rtcsessiondescription.c',
+ 'rtpreceiver.c',
+ 'rtpsender.c',
+ 'rtptransceiver.c',
+]
+
+webrtc_headers = [
+ 'dtlstransport.h',
+ 'icetransport.h',
+ 'rtcsessiondescription.h',
+ 'rtpreceiver.h',
+ 'rtpsender.h',
+ 'rtptransceiver.h',
+ 'webrtc_fwd.h',
+ 'webrtc.h',
+]
+
+webrtc_enumtypes_headers = [
+ 'dtlstransport.h',
+ 'icetransport.h',
+ 'rtptransceiver.h',
+ 'webrtc_fwd.h',
+]
+
+mkenums = find_program('webrtc_mkenum.py')
+gstwebrtc_h = custom_target('gstwebrtcenum_h',
+ output : 'webrtc-enumtypes.h',
+ input : webrtc_enumtypes_headers,
+ install : true,
+ install_dir : 'include/gstreamer-1.0/gst/webrtc/',
+ command : [mkenums, glib_mkenums, '@OUTPUT@', '@INPUT@'])
+
+gstwebrtc_c = custom_target('gstwebrtcenum_c',
+ output : 'webrtc-enumtypes.c',
+ input : webrtc_enumtypes_headers,
+ depends : [gstwebrtc_h],
+ command : [mkenums, glib_mkenums, '@OUTPUT@', '@INPUT@'])
+webrtc_gen_sources = [gstwebrtc_h]
+
+gstwebrtc_dependencies = [gstbase_dep, gstpbutils_dep, gstsdp_dep]
+
+gstwebrtc = library('gstwebrtc-' + api_version,
+ webrtc_sources, gstwebrtc_c, gstwebrtc_h,
+ c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'],
+ include_directories : [configinc, libsinc],
+ version : libversion,
+ soversion : soversion,
+ install : true,
+ dependencies : gstwebrtc_dependencies,
+)
+
+install_headers(webrtc_headers, subdir : 'gstreamer-1.0/gst/webrtc')
+
+gstwebrtc_dep = declare_dependency(link_with: gstwebrtc,
+ include_directories : libsinc,
+ dependencies: gstwebrtc_dependencies)
diff --git a/gst-libs/gst/webrtc/rtcsessiondescription.c b/gst-libs/gst/webrtc/rtcsessiondescription.c
new file mode 100644
index 000000000..3987ab63f
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtcsessiondescription.c
@@ -0,0 +1,123 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-sessiondescription
+ * @short_description: RTCSessionDescription object
+ * @title: GstWebRTCSessionDescription
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcsessiondescription-class">https://www.w3.org/TR/webrtc/#rtcsessiondescription-class</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rtcsessiondescription.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_peerconnection_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+/**
+ * gst_webrtc_sdp_type_to_string:
+ * @type: a #GstWebRTCSDPType
+ *
+ * Returns: the string representation of @type or "unknown" when @type is not
+ * recognized.
+ */
+const gchar *
+gst_webrtc_sdp_type_to_string (GstWebRTCSDPType type)
+{
+ switch (type) {
+ case GST_WEBRTC_SDP_TYPE_OFFER:
+ return "offer";
+ case GST_WEBRTC_SDP_TYPE_PRANSWER:
+ return "pranswer";
+ case GST_WEBRTC_SDP_TYPE_ANSWER:
+ return "answer";
+ case GST_WEBRTC_SDP_TYPE_ROLLBACK:
+ return "rollback";
+ default:
+ return "unknown";
+ }
+}
+
+/**
+ * gst_webrtc_session_description_copy:
+ * @src: (transfer none): a #GstWebRTCSessionDescription
+ *
+ * Returns: (transfer full): a new copy of @src
+ */
+GstWebRTCSessionDescription *
+gst_webrtc_session_description_copy (const GstWebRTCSessionDescription * src)
+{
+ GstWebRTCSessionDescription *ret;
+
+ if (!src)
+ return NULL;
+
+ ret = g_new0 (GstWebRTCSessionDescription, 1);
+
+ ret->type = src->type;
+ gst_sdp_message_copy (src->sdp, &ret->sdp);
+
+ return ret;
+}
+
+/**
+ * gst_webrtc_session_description_free:
+ * @desc: (transfer full): a #GstWebRTCSessionDescription
+ *
+ * Free @desc and all associated resources
+ */
+void
+gst_webrtc_session_description_free (GstWebRTCSessionDescription * desc)
+{
+ g_return_if_fail (desc != NULL);
+
+ gst_sdp_message_free (desc->sdp);
+ g_free (desc);
+}
+
+/**
+ * gst_webrtc_session_description_new:
+ * @type: a #GstWebRTCSDPType
+ * @sdp: a #GstSDPMessage
+ *
+ * Returns: (transfer full): a new #GstWebRTCSessionDescription from @type
+ * and @sdp
+ */
+GstWebRTCSessionDescription *
+gst_webrtc_session_description_new (GstWebRTCSDPType type, GstSDPMessage * sdp)
+{
+ GstWebRTCSessionDescription *ret;
+
+ ret = g_new0 (GstWebRTCSessionDescription, 1);
+
+ ret->type = type;
+ ret->sdp = sdp;
+
+ return ret;
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (GstWebRTCSessionDescription,
+ gst_webrtc_session_description, gst_webrtc_session_description_copy,
+ gst_webrtc_session_description_free,
+ GST_DEBUG_CATEGORY_INIT (gst_webrtc_peerconnection_debug,
+ "webrtcsessiondescription", 0, "webrtcsessiondescription"));
diff --git a/gst-libs/gst/webrtc/rtcsessiondescription.h b/gst-libs/gst/webrtc/rtcsessiondescription.h
new file mode 100644
index 000000000..080d21c7e
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtcsessiondescription.h
@@ -0,0 +1,58 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_SESSION_DESCRIPTION_H__
+#define __GST_WEBRTC_SESSION_DESCRIPTION_H__
+
+#include <gst/gst.h>
+#include <gst/sdp/sdp.h>
+#include <gst/webrtc/webrtc_fwd.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+const gchar * gst_webrtc_sdp_type_to_string (GstWebRTCSDPType type);
+
+#define GST_TYPE_WEBRTC_SESSION_DESCRIPTION (gst_webrtc_session_description_get_type())
+GST_EXPORT
+GType gst_webrtc_session_description_get_type (void);
+
+/**
+ * GstWebRTCSessionDescription:
+ * type: the #GstWebRTCSDPType of the description
+ * sdp: the #GstSDPMessage of the description
+ *
+ * See <ulink url="https://www.w3.org/TR/webrtc/#rtcsessiondescription-class">https://www.w3.org/TR/webrtc/#rtcsessiondescription-class</ulink>
+ */
+struct _GstWebRTCSessionDescription
+{
+ GstWebRTCSDPType type;
+ GstSDPMessage *sdp;
+};
+
+GST_EXPORT
+GstWebRTCSessionDescription * gst_webrtc_session_description_new (GstWebRTCSDPType type, GstSDPMessage *sdp);
+GST_EXPORT
+GstWebRTCSessionDescription * gst_webrtc_session_description_copy (const GstWebRTCSessionDescription * src);
+GST_EXPORT
+void gst_webrtc_session_description_free (GstWebRTCSessionDescription * desc);
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_PEERCONNECTION_H__ */
diff --git a/gst-libs/gst/webrtc/rtpreceiver.c b/gst-libs/gst/webrtc/rtpreceiver.c
new file mode 100644
index 000000000..edf6e201b
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtpreceiver.c
@@ -0,0 +1,135 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-receiver
+ * @short_description: RTCRtpReceiver object
+ * @title: GstWebRTCRTPReceiver
+ * @see_also: #GstWebRTCRTPSender, #GstWebRTCRTPTransceiver
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcrtpreceiver-interface">https://www.w3.org/TR/webrtc/#rtcrtpreceiver-interface</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rtpreceiver.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_rtp_receiver_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define gst_webrtc_rtp_receiver_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstWebRTCRTPReceiver, gst_webrtc_rtp_receiver,
+ GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_rtp_receiver_debug,
+ "webrtcreceiver", 0, "webrtcreceiver"););
+
+enum
+{
+ SIGNAL_0,
+ LAST_SIGNAL,
+};
+
+enum
+{
+ PROP_0,
+};
+
+//static guint gst_webrtc_rtp_receiver_signals[LAST_SIGNAL] = { 0 };
+
+void
+gst_webrtc_rtp_receiver_set_transport (GstWebRTCRTPReceiver * receiver,
+ GstWebRTCDTLSTransport * transport)
+{
+ g_return_if_fail (GST_IS_WEBRTC_RTP_RECEIVER (receiver));
+ g_return_if_fail (GST_IS_WEBRTC_DTLS_TRANSPORT (transport));
+
+ gst_object_replace ((GstObject **) & receiver->transport,
+ GST_OBJECT (transport));
+}
+
+void
+gst_webrtc_rtp_receiver_set_rtcp_transport (GstWebRTCRTPReceiver * receiver,
+ GstWebRTCDTLSTransport * transport)
+{
+ g_return_if_fail (GST_IS_WEBRTC_RTP_RECEIVER (receiver));
+ g_return_if_fail (GST_IS_WEBRTC_DTLS_TRANSPORT (transport));
+
+ gst_object_replace ((GstObject **) & receiver->rtcp_transport,
+ GST_OBJECT (transport));
+}
+
+static void
+gst_webrtc_rtp_receiver_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_receiver_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_receiver_finalize (GObject * object)
+{
+ GstWebRTCRTPReceiver *webrtc = GST_WEBRTC_RTP_RECEIVER (object);
+
+ if (webrtc->transport)
+ gst_object_unref (webrtc->transport);
+ webrtc->transport = NULL;
+
+ if (webrtc->rtcp_transport)
+ gst_object_unref (webrtc->rtcp_transport);
+ webrtc->rtcp_transport = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_webrtc_rtp_receiver_class_init (GstWebRTCRTPReceiverClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->get_property = gst_webrtc_rtp_receiver_get_property;
+ gobject_class->set_property = gst_webrtc_rtp_receiver_set_property;
+ gobject_class->finalize = gst_webrtc_rtp_receiver_finalize;
+}
+
+static void
+gst_webrtc_rtp_receiver_init (GstWebRTCRTPReceiver * webrtc)
+{
+}
+
+GstWebRTCRTPReceiver *
+gst_webrtc_rtp_receiver_new (void)
+{
+ return g_object_new (GST_TYPE_WEBRTC_RTP_RECEIVER, NULL);
+}
diff --git a/gst-libs/gst/webrtc/rtpreceiver.h b/gst-libs/gst/webrtc/rtpreceiver.h
new file mode 100644
index 000000000..969c4de65
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtpreceiver.h
@@ -0,0 +1,76 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_RTP_RECEIVER_H__
+#define __GST_WEBRTC_RTP_RECEIVER_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+#include <gst/webrtc/dtlstransport.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+GType gst_webrtc_rtp_receiver_get_type(void);
+#define GST_TYPE_WEBRTC_RTP_RECEIVER (gst_webrtc_rtp_receiver_get_type())
+#define GST_WEBRTC_RTP_RECEIVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_RTP_RECEIVER,GstWebRTCRTPReceiver))
+#define GST_IS_WEBRTC_RTP_RECEIVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_RTP_RECEIVER))
+#define GST_WEBRTC_RTP_RECEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_RTP_RECEIVER,GstWebRTCRTPReceiverClass))
+#define GST_IS_WEBRTC_RTP_RECEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_RTP_RECEIVER))
+#define GST_WEBRTC_RTP_RECEIVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_RTP_RECEIVER,GstWebRTCRTPReceiverClass))
+
+typedef struct _GstWebRTCRTPReceiver GstWebRTCRTPReceiver;
+typedef struct _GstWebRTCRTPReceiverClass GstWebRTCRTPReceiverClass;
+
+struct _GstWebRTCRTPReceiver
+{
+ GstObject parent;
+
+ /* The MediStreamTrack is represented by the stream and is output into @transport/@rtcp_transport as necessary */
+ GstWebRTCDTLSTransport *transport;
+ GstWebRTCDTLSTransport *rtcp_transport;
+
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstWebRTCRTPReceiverClass
+{
+ GstObjectClass parent_class;
+
+ gpointer _padding[GST_PADDING];
+};
+
+GST_EXPORT
+GstWebRTCRTPReceiver * gst_webrtc_rtp_receiver_new (void);
+GST_EXPORT
+GstStructure * gst_webrtc_rtp_receiver_get_parameters (GstWebRTCRTPReceiver * receiver, gchar * kind);
+/* FIXME: promise? */
+GST_EXPORT
+gboolean gst_webrtc_rtp_receiver_set_parameters (GstWebRTCRTPReceiver * receiver,
+ GstStructure * parameters);
+GST_EXPORT
+void gst_webrtc_rtp_receiver_set_transport (GstWebRTCRTPReceiver * receiver,
+ GstWebRTCDTLSTransport * transport);
+GST_EXPORT
+void gst_webrtc_rtp_receiver_set_rtcp_transport (GstWebRTCRTPReceiver * receiver,
+ GstWebRTCDTLSTransport * transport);
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_RTP_RECEIVER_H__ */
diff --git a/gst-libs/gst/webrtc/rtpsender.c b/gst-libs/gst/webrtc/rtpsender.c
new file mode 100644
index 000000000..b4dfe6ed8
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtpsender.c
@@ -0,0 +1,141 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-sender
+ * @short_description: RTCRtpSender object
+ * @title: GstWebRTCRTPSender
+ * @see_also: #GstWebRTCRTPReceiver, #GstWebRTCRTPTransceiver
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcrtpsender-interface">https://www.w3.org/TR/webrtc/#rtcrtpsender-interface</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rtpsender.h"
+#include "rtptransceiver.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_rtp_sender_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define gst_webrtc_rtp_sender_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstWebRTCRTPSender, gst_webrtc_rtp_sender,
+ GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_rtp_sender_debug,
+ "webrtcsender", 0, "webrtcsender");
+ );
+
+enum
+{
+ SIGNAL_0,
+ LAST_SIGNAL,
+};
+
+enum
+{
+ PROP_0,
+ PROP_MID,
+ PROP_SENDER,
+ PROP_STOPPED,
+ PROP_DIRECTION,
+};
+
+//static guint gst_webrtc_rtp_sender_signals[LAST_SIGNAL] = { 0 };
+
+void
+gst_webrtc_rtp_sender_set_transport (GstWebRTCRTPSender * sender,
+ GstWebRTCDTLSTransport * transport)
+{
+ g_return_if_fail (GST_IS_WEBRTC_RTP_SENDER (sender));
+ g_return_if_fail (GST_IS_WEBRTC_DTLS_TRANSPORT (transport));
+
+ gst_object_replace ((GstObject **) & sender->transport,
+ GST_OBJECT (transport));
+}
+
+void
+gst_webrtc_rtp_sender_set_rtcp_transport (GstWebRTCRTPSender * sender,
+ GstWebRTCDTLSTransport * transport)
+{
+ g_return_if_fail (GST_IS_WEBRTC_RTP_SENDER (sender));
+ g_return_if_fail (GST_IS_WEBRTC_DTLS_TRANSPORT (transport));
+
+ gst_object_replace ((GstObject **) & sender->rtcp_transport,
+ GST_OBJECT (transport));
+}
+
+static void
+gst_webrtc_rtp_sender_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_sender_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_sender_finalize (GObject * object)
+{
+ GstWebRTCRTPSender *webrtc = GST_WEBRTC_RTP_SENDER (object);
+
+ if (webrtc->transport)
+ gst_object_unref (webrtc->transport);
+ webrtc->transport = NULL;
+
+ if (webrtc->rtcp_transport)
+ gst_object_unref (webrtc->rtcp_transport);
+ webrtc->rtcp_transport = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_webrtc_rtp_sender_class_init (GstWebRTCRTPSenderClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->get_property = gst_webrtc_rtp_sender_get_property;
+ gobject_class->set_property = gst_webrtc_rtp_sender_set_property;
+ gobject_class->finalize = gst_webrtc_rtp_sender_finalize;
+}
+
+static void
+gst_webrtc_rtp_sender_init (GstWebRTCRTPSender * webrtc)
+{
+}
+
+GstWebRTCRTPSender *
+gst_webrtc_rtp_sender_new (GArray * send_encodings /* FIXME */ )
+{
+ return g_object_new (GST_TYPE_WEBRTC_RTP_SENDER, NULL);
+}
diff --git a/gst-libs/gst/webrtc/rtpsender.h b/gst-libs/gst/webrtc/rtpsender.h
new file mode 100644
index 000000000..8308a0b44
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtpsender.h
@@ -0,0 +1,77 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_RTP_SENDER_H__
+#define __GST_WEBRTC_RTP_SENDER_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+#include <gst/webrtc/dtlstransport.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+GType gst_webrtc_rtp_sender_get_type(void);
+#define GST_TYPE_WEBRTC_RTP_SENDER (gst_webrtc_rtp_sender_get_type())
+#define GST_WEBRTC_RTP_SENDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_RTP_SENDER,GstWebRTCRTPSender))
+#define GST_IS_WEBRTC_RTP_SENDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_RTP_SENDER))
+#define GST_WEBRTC_RTP_SENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_RTP_SENDER,GstWebRTCRTPSenderClass))
+#define GST_IS_WEBRTC_RTP_SENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_RTP_SENDER))
+#define GST_WEBRTC_RTP_SENDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_RTP_SENDER,GstWebRTCRTPSenderClass))
+
+struct _GstWebRTCRTPSender
+{
+ GstObject parent;
+
+ /* The MediStreamTrack is represented by the stream and is output into @transport/@rtcp_transport as necessary */
+ GstWebRTCDTLSTransport *transport;
+ GstWebRTCDTLSTransport *rtcp_transport;
+
+ GArray *send_encodings;
+
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstWebRTCRTPSenderClass
+{
+ GstObjectClass parent_class;
+
+ gpointer _padding[GST_PADDING];
+};
+
+GST_EXPORT
+GstWebRTCRTPSender * gst_webrtc_rtp_sender_new (GArray * send_encodings);
+GST_EXPORT
+GstStructure * gst_webrtc_rtp_sender_get_parameters (GstWebRTCRTPSender * sender, gchar * kind);
+/* FIXME: promise? */
+GST_EXPORT
+gboolean gst_webrtc_rtp_sender_set_parameters (GstWebRTCRTPSender * sender,
+ GstStructure * parameters);
+
+GST_EXPORT
+void gst_webrtc_rtp_sender_set_transport (GstWebRTCRTPSender * sender,
+ GstWebRTCDTLSTransport * transport);
+GST_EXPORT
+void gst_webrtc_rtp_sender_set_rtcp_transport (GstWebRTCRTPSender * sender,
+ GstWebRTCDTLSTransport * transport);
+
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_RTP_SENDER_H__ */
diff --git a/gst-libs/gst/webrtc/rtptransceiver.c b/gst-libs/gst/webrtc/rtptransceiver.c
new file mode 100644
index 000000000..d0d9628d0
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtptransceiver.c
@@ -0,0 +1,186 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstwebrtc-transceiver
+ * @short_description: RTCRtpTransceiver object
+ * @title: GstWebRTCRTPTransceiver
+ * @see_also: #GstWebRTCRTPSender, #GstWebRTCRTPReceiver
+ *
+ * <ulink url="https://www.w3.org/TR/webrtc/#rtcrtptransceiver-interface">https://www.w3.org/TR/webrtc/#rtcrtptransceiver-interface</ulink>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "rtptransceiver.h"
+
+#define GST_CAT_DEFAULT gst_webrtc_rtp_transceiver_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+#define gst_webrtc_rtp_transceiver_parent_class parent_class
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCRTPTransceiver,
+ gst_webrtc_rtp_transceiver, GST_TYPE_OBJECT,
+ GST_DEBUG_CATEGORY_INIT (gst_webrtc_rtp_transceiver_debug,
+ "webrtctransceiver", 0, "webrtctransceiver");
+ );
+
+enum
+{
+ SIGNAL_0,
+ LAST_SIGNAL,
+};
+
+enum
+{
+ PROP_0,
+ PROP_MID,
+ PROP_SENDER,
+ PROP_RECEIVER,
+ PROP_STOPPED, // FIXME
+ PROP_DIRECTION, // FIXME
+ PROP_MLINE,
+};
+
+//static guint gst_webrtc_rtp_transceiver_signals[LAST_SIGNAL] = { 0 };
+
+static void
+gst_webrtc_rtp_transceiver_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCRTPTransceiver *webrtc = GST_WEBRTC_RTP_TRANSCEIVER (object);
+
+ switch (prop_id) {
+ case PROP_SENDER:
+ webrtc->sender = g_value_dup_object (value);
+ break;
+ case PROP_RECEIVER:
+ webrtc->receiver = g_value_dup_object (value);
+ break;
+ case PROP_MLINE:
+ webrtc->mline = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_transceiver_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstWebRTCRTPTransceiver *webrtc = GST_WEBRTC_RTP_TRANSCEIVER (object);
+
+ switch (prop_id) {
+ case PROP_SENDER:
+ g_value_set_object (value, webrtc->sender);
+ break;
+ case PROP_RECEIVER:
+ g_value_set_object (value, webrtc->receiver);
+ break;
+ case PROP_MLINE:
+ g_value_set_uint (value, webrtc->mline);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_webrtc_rtp_transceiver_constructed (GObject * object)
+{
+ GstWebRTCRTPTransceiver *webrtc = GST_WEBRTC_RTP_TRANSCEIVER (object);
+
+ gst_object_set_parent (GST_OBJECT (webrtc->sender), GST_OBJECT (webrtc));
+ gst_object_set_parent (GST_OBJECT (webrtc->receiver), GST_OBJECT (webrtc));
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+}
+
+static void
+gst_webrtc_rtp_transceiver_dispose (GObject * object)
+{
+ GstWebRTCRTPTransceiver *webrtc = GST_WEBRTC_RTP_TRANSCEIVER (object);
+
+ if (webrtc->sender) {
+ GST_OBJECT_PARENT (webrtc->sender) = NULL;
+ gst_object_unref (webrtc->sender);
+ }
+ webrtc->sender = NULL;
+ if (webrtc->receiver) {
+ GST_OBJECT_PARENT (webrtc->receiver) = NULL;
+ gst_object_unref (webrtc->receiver);
+ }
+ webrtc->receiver = NULL;
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_webrtc_rtp_transceiver_finalize (GObject * object)
+{
+ GstWebRTCRTPTransceiver *webrtc = GST_WEBRTC_RTP_TRANSCEIVER (object);
+
+ g_free (webrtc->mid);
+ if (webrtc->codec_preferences)
+ gst_caps_unref (webrtc->codec_preferences);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_webrtc_rtp_transceiver_class_init (GstWebRTCRTPTransceiverClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->get_property = gst_webrtc_rtp_transceiver_get_property;
+ gobject_class->set_property = gst_webrtc_rtp_transceiver_set_property;
+ gobject_class->constructed = gst_webrtc_rtp_transceiver_constructed;
+ gobject_class->dispose = gst_webrtc_rtp_transceiver_dispose;
+ gobject_class->finalize = gst_webrtc_rtp_transceiver_finalize;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SENDER,
+ g_param_spec_object ("sender", "Sender",
+ "The RTP sender for this transceiver",
+ GST_TYPE_WEBRTC_RTP_SENDER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_RECEIVER,
+ g_param_spec_object ("receiver", "Receiver",
+ "The RTP receiver for this transceiver",
+ GST_TYPE_WEBRTC_RTP_RECEIVER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MLINE,
+ g_param_spec_uint ("mlineindex", "Media Line Index",
+ "Index in the SDP of the Media",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_webrtc_rtp_transceiver_init (GstWebRTCRTPTransceiver * webrtc)
+{
+}
diff --git a/gst-libs/gst/webrtc/rtptransceiver.h b/gst-libs/gst/webrtc/rtptransceiver.h
new file mode 100644
index 000000000..1bb819752
--- /dev/null
+++ b/gst-libs/gst/webrtc/rtptransceiver.h
@@ -0,0 +1,69 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_RTP_TRANSCEIVER_H__
+#define __GST_WEBRTC_RTP_TRANSCEIVER_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+#include <gst/webrtc/rtpsender.h>
+#include <gst/webrtc/rtpreceiver.h>
+
+G_BEGIN_DECLS
+
+GST_EXPORT
+GType gst_webrtc_rtp_transceiver_get_type(void);
+#define GST_TYPE_WEBRTC_RTP_TRANSCEIVER (gst_webrtc_rtp_transceiver_get_type())
+#define GST_WEBRTC_RTP_TRANSCEIVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_RTP_TRANSCEIVER,GstWebRTCRTPTransceiver))
+#define GST_IS_WEBRTC_RTP_TRANSCEIVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_RTP_TRANSCEIVER))
+#define GST_WEBRTC_RTP_TRANSCEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_RTP_TRANSCEIVER,GstWebRTCRTPTransceiverClass))
+#define GST_IS_WEBRTC_RTP_TRANSCEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_RTP_TRANSCEIVER))
+#define GST_WEBRTC_RTP_TRANSCEIVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_RTP_TRANSCEIVER,GstWebRTCRTPTransceiverClass))
+
+struct _GstWebRTCRTPTransceiver
+{
+ GstObject parent;
+ guint mline;
+ gchar *mid;
+ gboolean stopped;
+
+ GstWebRTCRTPSender *sender;
+ GstWebRTCRTPReceiver *receiver;
+
+ GstWebRTCRTPTransceiverDirection direction;
+ GstWebRTCRTPTransceiverDirection current_direction;
+
+ GstCaps *codec_preferences;
+
+ gpointer _padding[GST_PADDING];
+};
+
+struct _GstWebRTCRTPTransceiverClass
+{
+ GstObjectClass parent_class;
+
+ gpointer _padding[GST_PADDING];
+};
+
+GST_EXPORT
+void gst_webrtc_rtp_transceiver_stop (GstWebRTCRTPTransceiver * transceiver);
+
+G_END_DECLS
+
+#endif /* __GST_WEBRTC_RTP_TRANSCEIVER_H__ */
diff --git a/gst-libs/gst/webrtc/webrtc.h b/gst-libs/gst/webrtc/webrtc.h
new file mode 100644
index 000000000..354c15c19
--- /dev/null
+++ b/gst-libs/gst/webrtc/webrtc.h
@@ -0,0 +1,33 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_WEBRTC_H__
+#define __GST_WEBRTC_WEBRTC_H__
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc_fwd.h>
+#include <gst/webrtc/webrtc-enumtypes.h>
+#include <gst/webrtc/dtlstransport.h>
+#include <gst/webrtc/icetransport.h>
+#include <gst/webrtc/rtcsessiondescription.h>
+#include <gst/webrtc/rtpreceiver.h>
+#include <gst/webrtc/rtpsender.h>
+#include <gst/webrtc/rtptransceiver.h>
+
+#endif /* __GST_WEBRTC_WEBRTC_H__ */
diff --git a/gst-libs/gst/webrtc/webrtc_fwd.h b/gst-libs/gst/webrtc/webrtc_fwd.h
new file mode 100644
index 000000000..48c9bdab1
--- /dev/null
+++ b/gst-libs/gst/webrtc/webrtc_fwd.h
@@ -0,0 +1,251 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WEBRTC_FWD_H__
+#define __GST_WEBRTC_FWD_H__
+
+#ifndef GST_USE_UNSTABLE_API
+#warning "The WebRTC library from gst-plugins-bad is unstable API and may change in future."
+#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
+#endif
+
+#include <gst/gst.h>
+#include <gst/webrtc/webrtc-enumtypes.h>
+
+typedef struct _GstWebRTCDTLSTransport GstWebRTCDTLSTransport;
+typedef struct _GstWebRTCDTLSTransportClass GstWebRTCDTLSTransportClass;
+
+typedef struct _GstWebRTCICETransport GstWebRTCICETransport;
+typedef struct _GstWebRTCICETransportClass GstWebRTCICETransportClass;
+
+typedef struct _GstWebRTCRTPReceiver GstWebRTCRTPReceiver;
+typedef struct _GstWebRTCRTPReceiverClass GstWebRTCRTPReceiverClass;
+
+typedef struct _GstWebRTCRTPSender GstWebRTCRTPSender;
+typedef struct _GstWebRTCRTPSenderClass GstWebRTCRTPSenderClass;
+
+typedef struct _GstWebRTCSessionDescription GstWebRTCSessionDescription;
+
+typedef struct _GstWebRTCRTPTransceiver GstWebRTCRTPTransceiver;
+typedef struct _GstWebRTCRTPTransceiverClass GstWebRTCRTPTransceiverClass;
+
+/**
+ * GstWebRTCDTLSTransportState:
+ * GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW: new
+ * GST_WEBRTC_DTLS_TRANSPORT_STATE_CLOSED: closed
+ * GST_WEBRTC_DTLS_TRANSPORT_STATE_FAILED: failed
+ * GST_WEBRTC_DTLS_TRANSPORT_STATE_CONNECTING: connecting
+ * GST_WEBRTC_DTLS_TRANSPORT_STATE_CONNECTED: connected
+ */
+typedef enum /*< underscore_name=gst_webrtc_dtls_transport_state >*/
+{
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW,
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_CLOSED,
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_FAILED,
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_CONNECTING,
+ GST_WEBRTC_DTLS_TRANSPORT_STATE_CONNECTED,
+} GstWebRTCDTLSTransportState;
+
+/**
+ * GstWebRTCICEGatheringState:
+ * GST_WEBRTC_ICE_GATHERING_STATE_NEW: new
+ * GST_WEBRTC_ICE_GATHERING_STATE_GATHERING: gathering
+ * GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE: complete
+ *
+ * See <ulink url="http://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate">http://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate</ulink>
+ */
+typedef enum /*< underscore_name=gst_webrtc_ice_gathering_state >*/
+{
+ GST_WEBRTC_ICE_GATHERING_STATE_NEW,
+ GST_WEBRTC_ICE_GATHERING_STATE_GATHERING,
+ GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE,
+} GstWebRTCICEGatheringState; /*< underscore_name=gst_webrtc_ice_gathering_state >*/
+
+/**
+ * GstWebRTCICEConnectionState:
+ * GST_WEBRTC_ICE_CONNECTION_STATE_NEW: new
+ * GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING: checking
+ * GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED: connected
+ * GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED: completed
+ * GST_WEBRTC_ICE_CONNECTION_STATE_FAILED: failed
+ * GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED: disconnected
+ * GST_WEBRTC_ICE_CONNECTION_STATE_CLOSED: closed
+ *
+ * See <ulink url="http://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate">http://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate</ulink>
+ */
+typedef enum /*< underscore_name=gst_webrtc_ice_connection_state >*/
+{
+ GST_WEBRTC_ICE_CONNECTION_STATE_NEW,
+ GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING,
+ GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED,
+ GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED,
+ GST_WEBRTC_ICE_CONNECTION_STATE_FAILED,
+ GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED,
+ GST_WEBRTC_ICE_CONNECTION_STATE_CLOSED,
+} GstWebRTCICEConnectionState;
+
+/**
+ * GstWebRTCSignalingState:
+ * GST_WEBRTC_SIGNALING_STATE_STABLE: stable
+ * GST_WEBRTC_SIGNALING_STATE_CLOSED: closed
+ * GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_OFFER: have-local-offer
+ * GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER: have-remote-offer
+ * GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_PRANSWER: have-local-pranswer
+ * GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_PRANSWER: have-remote-pranswer
+ *
+ * See <ulink url="http://w3c.github.io/webrtc-pc/#dom-rtcsignalingstate">http://w3c.github.io/webrtc-pc/#dom-rtcsignalingstate</ulink>
+ */
+typedef enum /*< underscore_name=gst_webrtc_signaling_state >*/
+{
+ GST_WEBRTC_SIGNALING_STATE_STABLE,
+ GST_WEBRTC_SIGNALING_STATE_CLOSED,
+ GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_OFFER,
+ GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER,
+ GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_PRANSWER,
+ GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_PRANSWER,
+} GstWebRTCSignalingState;
+
+/**
+ * GstWebRTCPeerConnectionState:
+ * GST_WEBRTC_PEER_CONNECTION_STATE_NEW: new
+ * GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTING: connecting
+ * GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTED: connected
+ * GST_WEBRTC_PEER_CONNECTION_STATE_DISCONNECTED: disconnected
+ * GST_WEBRTC_PEER_CONNECTION_STATE_FAILED: failed
+ * GST_WEBRTC_PEER_CONNECTION_STATE_CLOSED: closed
+ *
+ * See <ulink url="http://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectionstate">http://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectionstate</ulink>
+ */
+typedef enum /*< underscore_name=gst_webrtc_peer_connection_state >*/
+{
+ GST_WEBRTC_PEER_CONNECTION_STATE_NEW,
+ GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTING,
+ GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTED,
+ GST_WEBRTC_PEER_CONNECTION_STATE_DISCONNECTED,
+ GST_WEBRTC_PEER_CONNECTION_STATE_FAILED,
+ GST_WEBRTC_PEER_CONNECTION_STATE_CLOSED,
+} GstWebRTCPeerConnectionState;
+
+/**
+ * GstWebRTCIceRole:
+ * GST_WEBRTC_ICE_ROLE_CONTROLLED: controlled
+ * GST_WEBRTC_ICE_ROLE_CONTROLLING: controlling
+ */
+typedef enum /*< underscore_name=gst_webrtc_ice_role >*/
+{
+ GST_WEBRTC_ICE_ROLE_CONTROLLED,
+ GST_WEBRTC_ICE_ROLE_CONTROLLING,
+} GstWebRTCIceRole;
+
+/**
+ * GstWebRTCIceComponent:
+ * GST_WEBRTC_ICE_COMPONENT_RTP,
+ * GST_WEBRTC_ICE_COMPONENT_RTCP,
+ */
+typedef enum /*< underscore_name=gst_webrtc_ice_component >*/
+{
+ GST_WEBRTC_ICE_COMPONENT_RTP,
+ GST_WEBRTC_ICE_COMPONENT_RTCP,
+} GstWebRTCICEComponent;
+
+/**
+ * GstWebRTCSDPType:
+ * GST_WEBRTC_SDP_TYPE_OFFER: offer
+ * GST_WEBRTC_SDP_TYPE_PRANSWER: pranswer
+ * GST_WEBRTC_SDP_TYPE_ANSWER: answer
+ * GST_WEBRTC_SDP_TYPE_ROLLBACK: rollback
+ *
+ * See <ulink url="http://w3c.github.io/webrtc-pc/#rtcsdptype">http://w3c.github.io/webrtc-pc/#rtcsdptype</ulink>
+ */
+typedef enum /*< underscore_name=gst_webrtc_sdp_type >*/
+{
+ GST_WEBRTC_SDP_TYPE_OFFER = 1,
+ GST_WEBRTC_SDP_TYPE_PRANSWER,
+ GST_WEBRTC_SDP_TYPE_ANSWER,
+ GST_WEBRTC_SDP_TYPE_ROLLBACK,
+} GstWebRTCSDPType;
+
+/**
+ * GstWebRTCRtpTransceiverDirection:
+ * GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE: none
+ * GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE: inactive
+ * GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY: sendonly
+ * GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY: recvonly
+ * GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV: sendrecv
+ */
+typedef enum /*< underscore_name=gst_webrtc_rtp_transceiver_direction >*/
+{
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE,
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE,
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY,
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY,
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV,
+} GstWebRTCRTPTransceiverDirection;
+
+/**
+ * GstWebRTCDTLSSetup:
+ * GST_WEBRTC_DTLS_SETUP_NONE: none
+ * GST_WEBRTC_DTLS_SETUP_ACTPASS: actpass
+ * GST_WEBRTC_DTLS_SETUP_ACTIVE: sendonly
+ * GST_WEBRTC_DTLS_SETUP_PASSIVE: recvonly
+ */
+typedef enum /*< underscore_name=gst_webrtc_dtls_setup >*/
+{
+ GST_WEBRTC_DTLS_SETUP_NONE,
+ GST_WEBRTC_DTLS_SETUP_ACTPASS,
+ GST_WEBRTC_DTLS_SETUP_ACTIVE,
+ GST_WEBRTC_DTLS_SETUP_PASSIVE,
+} GstWebRTCDTLSSetup;
+
+/**
+ * GstWebRTCStatsType:
+ * GST_WEBRTC_STATS_CODEC: codec
+ * GST_WEBRTC_STATS_INBOUND_RTP: inbound-rtp
+ * GST_WEBRTC_STATS_OUTBOUND_RTP: outbound-rtp
+ * GST_WEBRTC_STATS_REMOTE_INBOUND_RTP: remote-inbound-rtp
+ * GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP: remote-outbound-rtp
+ * GST_WEBRTC_STATS_CSRC: csrc
+ * GST_WEBRTC_STATS_PEER_CONNECTION: peer-connectiion
+ * GST_WEBRTC_STATS_DATA_CHANNEL: data-channel
+ * GST_WEBRTC_STATS_STREAM: stream
+ * GST_WEBRTC_STATS_TRANSPORT: transport
+ * GST_WEBRTC_STATS_CANDIDATE_PAIR: candidate-pair
+ * GST_WEBRTC_STATS_LOCAL_CANDIDATE: local-candidate
+ * GST_WEBRTC_STATS_REMOTE_CANDIDATE: remote-candidate
+ * GST_WEBRTC_STATS_CERTIFICATE: certificate
+ */
+typedef enum /*< underscore_name=gst_webrtc_stats_type >*/
+{
+ GST_WEBRTC_STATS_CODEC = 1,
+ GST_WEBRTC_STATS_INBOUND_RTP,
+ GST_WEBRTC_STATS_OUTBOUND_RTP,
+ GST_WEBRTC_STATS_REMOTE_INBOUND_RTP,
+ GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP,
+ GST_WEBRTC_STATS_CSRC,
+ GST_WEBRTC_STATS_PEER_CONNECTION,
+ GST_WEBRTC_STATS_DATA_CHANNEL,
+ GST_WEBRTC_STATS_STREAM,
+ GST_WEBRTC_STATS_TRANSPORT,
+ GST_WEBRTC_STATS_CANDIDATE_PAIR,
+ GST_WEBRTC_STATS_LOCAL_CANDIDATE,
+ GST_WEBRTC_STATS_REMOTE_CANDIDATE,
+ GST_WEBRTC_STATS_CERTIFICATE,
+} GstWebRTCStatsType;
+
+#endif /* __GST_WEBRTC_FWD_H__ */
diff --git a/gst-libs/gst/webrtc/webrtc_mkenum.py b/gst-libs/gst/webrtc/webrtc_mkenum.py
new file mode 100755
index 000000000..fb6c2cba6
--- /dev/null
+++ b/gst-libs/gst/webrtc/webrtc_mkenum.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+
+# This is in its own file rather than inside meson.build
+# because a) mixing the two is ugly and b) trying to
+# make special characters such as \n go through all
+# backends is a fool's errand.
+
+import sys, os, shutil, subprocess
+
+h_array = ['--fhead',
+ "#ifndef __GST_WEBRTC_ENUM_TYPES_H__\n#define __GST_WEBRTC_ENUM_TYPES_H__\n\n#include <gst/gst.h>\n\nG_BEGIN_DECLS\n",
+ '--fprod',
+ "\n/* enumerations from \"@filename@\" */\n",
+ '--vhead',
+ "GST_EXPORT GType @enum_name@_get_type (void);\n#define GST_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n",
+ '--ftail',
+ "G_END_DECLS\n\n#endif /* __GST_WEBRTC_ENUM_TYPES_H__ */"
+]
+
+c_array = ['--fhead',
+ "#include \"webrtc-enumtypes.h\"\n\n#include \"webrtc.h\"",
+ '--fprod',
+ "\n/* enumerations from \"@filename@\" */",
+ '--vhead',
+ "GType\n@enum_name@_get_type (void)\n{\n static volatile gsize g_define_type_id__volatile = 0;\n if (g_once_init_enter (&g_define_type_id__volatile)) {\n static const G@Type@Value values[] = {",
+ '--vprod',
+ " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" },",
+ '--vtail',
+ " { 0, NULL, NULL }\n };\n GType g_define_type_id = g_@type@_register_static (\"@EnumName@\", values);\n g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);\n }\n return g_define_type_id__volatile;\n}\n"
+]
+
+cmd = []
+argn = 1
+# Find the full command needed to run glib-mkenums
+# On UNIX-like, this is just the full path to glib-mkenums
+# On Windows, this is the full path to interpreter + full path to glib-mkenums
+for arg in sys.argv[1:]:
+ cmd.append(arg)
+ argn += 1
+ if arg.endswith('glib-mkenums'):
+ break
+ofilename = sys.argv[argn]
+headers = sys.argv[argn + 1:]
+
+if ofilename.endswith('.h'):
+ arg_array = h_array
+else:
+ arg_array = c_array
+
+cmd_array = cmd + arg_array + headers
+pc = subprocess.Popen(cmd_array, stdout=subprocess.PIPE)
+(stdo, _) = pc.communicate()
+if pc.returncode != 0:
+ sys.exit(pc.returncode)
+open(ofilename, 'wb').write(stdo)