summaryrefslogtreecommitdiff
path: root/gst-libs/gst
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst')
-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)