webrtc: Split WebRTCICE into base classes and implementation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2398>
This commit is contained in:
yatinmaan 2022-04-18 23:25:13 +05:30 committed by GStreamer Marge Bot
parent e0564b04c6
commit 2c1e61ea16
32 changed files with 1742 additions and 635 deletions

View file

@ -18498,6 +18498,11 @@
"GstWebRTCError", "GstWebRTCError",
"GstWebRTCFECType", "GstWebRTCFECType",
"GstWebRTCICE", "GstWebRTCICE",
"GstWebRTCICE.ice_connection_state",
"GstWebRTCICE.ice_gathering_state",
"GstWebRTCICE.max_rtp_port",
"GstWebRTCICE.min_rtp_port",
"GstWebRTCICE.parent",
"GstWebRTCICE::add-local-ip-address", "GstWebRTCICE::add-local-ip-address",
"GstWebRTCICE::on-ice-candidate", "GstWebRTCICE::on-ice-candidate",
"GstWebRTCICE:agent", "GstWebRTCICE:agent",
@ -18509,10 +18514,46 @@
"GstWebRTCICE:min-rtp-port", "GstWebRTCICE:min-rtp-port",
"GstWebRTCICE:stun-server", "GstWebRTCICE:stun-server",
"GstWebRTCICE:turn-server", "GstWebRTCICE:turn-server",
"GstWebRTCICECandidateStats",
"GstWebRTCICECandidateStats.ipaddr",
"GstWebRTCICECandidateStats.port",
"GstWebRTCICECandidateStats.prio",
"GstWebRTCICECandidateStats.proto",
"GstWebRTCICECandidateStats.relay_proto",
"GstWebRTCICECandidateStats.stream_id",
"GstWebRTCICECandidateStats.type",
"GstWebRTCICECandidateStats.url",
"GstWebRTCICEClass.parent_class",
"GstWebRTCICEClass::add_candidate",
"GstWebRTCICEClass::add_stream",
"GstWebRTCICEClass::add_turn_server",
"GstWebRTCICEClass::find_transport",
"GstWebRTCICEClass::gather_candidates",
"GstWebRTCICEClass::get_is_controller",
"GstWebRTCICEClass::get_local_candidates",
"GstWebRTCICEClass::get_remote_candidates",
"GstWebRTCICEClass::get_selected_pair",
"GstWebRTCICEClass::get_stun_server",
"GstWebRTCICEClass::get_turn_server",
"GstWebRTCICEClass::set_force_relay",
"GstWebRTCICEClass::set_is_controller",
"GstWebRTCICEClass::set_local_credentials",
"GstWebRTCICEClass::set_on_ice_candidate",
"GstWebRTCICEClass::set_remote_credentials",
"GstWebRTCICEClass::set_stun_server",
"GstWebRTCICEClass::set_tos",
"GstWebRTCICEClass::set_turn_server",
"GstWebRTCICEComponent", "GstWebRTCICEComponent",
"GstWebRTCICEConnectionState", "GstWebRTCICEConnectionState",
"GstWebRTCICEGatheringState", "GstWebRTCICEGatheringState",
"GstWebRTCICERole", "GstWebRTCICERole",
"GstWebRTCICEStream",
"GstWebRTCICEStream.parent",
"GstWebRTCICEStream.stream_id",
"GstWebRTCICEStream:stream-id",
"GstWebRTCICEStreamClass.parent_class",
"GstWebRTCICEStreamClass::find_transport",
"GstWebRTCICEStreamClass::gather_candidates",
"GstWebRTCICETransport", "GstWebRTCICETransport",
"GstWebRTCICETransport._padding", "GstWebRTCICETransport._padding",
"GstWebRTCICETransport.component", "GstWebRTCICETransport.component",
@ -42534,6 +42575,24 @@
"gst_webrtc_dtls_transport_new", "gst_webrtc_dtls_transport_new",
"gst_webrtc_dtls_transport_set_transport", "gst_webrtc_dtls_transport_set_transport",
"gst_webrtc_error_quark", "gst_webrtc_error_quark",
"gst_webrtc_ice_add_candidate",
"gst_webrtc_ice_add_turn_server",
"gst_webrtc_ice_gather_candidates",
"gst_webrtc_ice_get_is_controller",
"gst_webrtc_ice_get_local_candidates",
"gst_webrtc_ice_get_remote_candidates",
"gst_webrtc_ice_get_stun_server",
"gst_webrtc_ice_get_turn_server",
"gst_webrtc_ice_set_force_relay",
"gst_webrtc_ice_set_is_controller",
"gst_webrtc_ice_set_local_credentials",
"gst_webrtc_ice_set_on_ice_candidate",
"gst_webrtc_ice_set_remote_credentials",
"gst_webrtc_ice_set_stun_server",
"gst_webrtc_ice_set_tos",
"gst_webrtc_ice_set_turn_server",
"gst_webrtc_ice_stream_find_transport",
"gst_webrtc_ice_stream_gather_candidates",
"gst_webrtc_ice_transport_connection_state_change", "gst_webrtc_ice_transport_connection_state_change",
"gst_webrtc_ice_transport_gathering_state_change", "gst_webrtc_ice_transport_gathering_state_change",
"gst_webrtc_ice_transport_new_candidate", "gst_webrtc_ice_transport_new_candidate",

View file

@ -12,6 +12,8 @@ if not libsoup_dep.found() or not json_glib_dep.found()
subdir_done() subdir_done()
endif endif
libgstwebrtcnice_dep = dependency('gstreamer-webrtc-nice-1.0', version : gst_req)
py3_mod = import('python3') py3_mod = import('python3')
py3 = py3_mod.find_python() py3 = py3_mod.find_python()

View file

@ -1,6 +1,6 @@
CC := gcc CC := gcc
LIBS := $(shell pkg-config --libs --cflags glib-2.0 gstreamer-1.0 gstreamer-rtp-1.0 gstreamer-sdp-1.0 gstreamer-webrtc-1.0 json-glib-1.0 libsoup-2.4) LIBS := $(shell pkg-config --libs --cflags glib-2.0 gstreamer-1.0 gstreamer-rtp-1.0 gstreamer-sdp-1.0 gstreamer-webrtc-1.0 json-glib-1.0 libsoup-2.4 gstreamer-webrtc-nice-1.0)
CFLAGS := -O0 -ggdb -Wall -fno-omit-frame-pointer \ CFLAGS := -O0 -ggdb -Wall -fno-omit-frame-pointer \
$(shell pkg-config --cflags glib-2.0 gstreamer-1.0 gstreamer-rtp-1.0 gstreamer-sdp-1.0 gstreamer-webrtc-1.0 json-glib-1.0 libsoup-2.4) $(shell pkg-config --cflags glib-2.0 gstreamer-1.0 gstreamer-rtp-1.0 gstreamer-sdp-1.0 gstreamer-webrtc-1.0 json-glib-1.0 libsoup-2.4)
webrtc-sendrecv: webrtc-sendrecv.c webrtc-sendrecv: webrtc-sendrecv.c custom_agent.c custom_agent.h
"$(CC)" $(CFLAGS) $^ $(LIBS) -o $@ "$(CC)" $(CFLAGS) $^ $(LIBS) -o $@

View file

@ -0,0 +1,170 @@
#include "custom_agent.h"
#include <gst/webrtc/nice/nice.h>
struct _CustomICEAgent
{
GstWebRTCICE parent;
GstWebRTCNice *nice_agent;
};
/* *INDENT-OFF* */
G_DEFINE_TYPE (CustomICEAgent, customice_agent, GST_TYPE_WEBRTC_ICE)
/* *INDENT-ON* */
GstWebRTCICEStream *
customice_agent_add_stream (GstWebRTCICE * ice, guint session_id)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_add_stream (c_ice, session_id);
}
GstWebRTCICETransport *
customice_agent_find_transport (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEComponent component)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_find_transport (c_ice, stream, component);
}
void
customice_agent_add_candidate (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, const gchar * candidate)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_add_candidate (c_ice, stream, candidate);
}
gboolean
customice_agent_set_remote_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_set_remote_credentials (c_ice, stream, ufrag, pwd);
}
gboolean
customice_agent_add_turn_server (GstWebRTCICE * ice, const gchar * uri)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_add_turn_server (c_ice, uri);
}
gboolean
customice_agent_set_local_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_set_local_credentials (c_ice, stream, ufrag, pwd);
}
gboolean
customice_agent_gather_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_gather_candidates (c_ice, stream);
}
void
customice_agent_set_is_controller (GstWebRTCICE * ice, gboolean controller)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_is_controller (c_ice, controller);
}
gboolean
customice_agent_get_is_controller (GstWebRTCICE * ice)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_get_is_controller (c_ice);
}
void
customice_agent_set_force_relay (GstWebRTCICE * ice, gboolean force_relay)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_force_relay (c_ice, force_relay);
}
void
customice_agent_set_tos (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
guint tos)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_tos (c_ice, stream, tos);
}
void
customice_agent_set_on_ice_candidate (GstWebRTCICE * ice,
GstWebRTCICEOnCandidateFunc func, gpointer user_data, GDestroyNotify notify)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_on_ice_candidate (c_ice, func, user_data, notify);
}
void
customice_agent_set_stun_server (GstWebRTCICE * ice, const gchar * uri_s)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_stun_server (c_ice, uri_s);
}
gchar *
customice_agent_get_stun_server (GstWebRTCICE * ice)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_get_stun_server (c_ice);
}
void
customice_agent_set_turn_server (GstWebRTCICE * ice, const gchar * uri_s)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
gst_webrtc_ice_set_turn_server (c_ice, uri_s);
}
gchar *
customice_agent_get_turn_server (GstWebRTCICE * ice)
{
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
return gst_webrtc_ice_get_turn_server (c_ice);
}
static void
customice_agent_class_init (CustomICEAgentClass * klass)
{
GstWebRTCICEClass *gst_webrtc_ice_class = GST_WEBRTC_ICE_CLASS (klass);
// override virtual functions
gst_webrtc_ice_class->add_candidate = customice_agent_add_candidate;
gst_webrtc_ice_class->add_stream = customice_agent_add_stream;
gst_webrtc_ice_class->add_turn_server = customice_agent_add_turn_server;
gst_webrtc_ice_class->find_transport = customice_agent_find_transport;
gst_webrtc_ice_class->gather_candidates = customice_agent_gather_candidates;
gst_webrtc_ice_class->get_is_controller = customice_agent_get_is_controller;
gst_webrtc_ice_class->get_stun_server = customice_agent_get_stun_server;
gst_webrtc_ice_class->get_turn_server = customice_agent_get_turn_server;
gst_webrtc_ice_class->set_force_relay = customice_agent_set_force_relay;
gst_webrtc_ice_class->set_is_controller = customice_agent_set_is_controller;
gst_webrtc_ice_class->set_local_credentials =
customice_agent_set_local_credentials;
gst_webrtc_ice_class->set_remote_credentials =
customice_agent_set_remote_credentials;
gst_webrtc_ice_class->set_stun_server = customice_agent_set_stun_server;
gst_webrtc_ice_class->set_tos = customice_agent_set_tos;
gst_webrtc_ice_class->set_turn_server = customice_agent_set_turn_server;
gst_webrtc_ice_class->set_on_ice_candidate =
customice_agent_set_on_ice_candidate;
}
static void
customice_agent_init (CustomICEAgent * ice)
{
ice->nice_agent = gst_webrtc_nice_new ("nice_agent");
}
CustomICEAgent *
customice_agent_new (const gchar * name)
{
return g_object_new (GST_TYPE_WEBRTC_NICE, "name", name, NULL);
}

View file

@ -0,0 +1,15 @@
#ifndef __CUSTOM_AGENT_H__
#define __CUSTOM_AGENT_H__
#include <gst/webrtc/ice.h>
G_BEGIN_DECLS
#define CUSTOMICE_TYPE_AGENT (customice_agent_get_type ())
G_DECLARE_FINAL_TYPE (CustomICEAgent, customice_agent, CUSTOMICE, AGENT, GstWebRTCICE)
CustomICEAgent * customice_agent_new (const gchar * name);
G_END_DECLS
#endif /* __CUSTOM_AGENT_H__ */

View file

@ -1,5 +1,9 @@
executable('webrtc-sendrecv', executable('webrtc-sendrecv',
'webrtc-sendrecv.c', 'webrtc-sendrecv.c',
dependencies : [gst_dep, gstsdp_dep, gstwebrtc_dep, gstrtp_dep, libsoup_dep, json_glib_dep]) 'custom_agent.h',
'custom_agent.c',
c_args : ['-DGST_USE_UNSTABLE_API'],
dependencies : [gst_dep, gstsdp_dep, gstwebrtc_dep, gstrtp_dep,
libsoup_dep, json_glib_dep, libgstwebrtcnice_dep])
webrtc_py = files('webrtc_sendrecv.py') webrtc_py = files('webrtc_sendrecv.py')

View file

@ -10,8 +10,10 @@
#include <gst/sdp/sdp.h> #include <gst/sdp/sdp.h>
#include <gst/rtp/rtp.h> #include <gst/rtp/rtp.h>
#define GST_USE_UNSTABLE_API
#include <gst/webrtc/webrtc.h> #include <gst/webrtc/webrtc.h>
#include <gst/webrtc/nice/nice.h>
#include "custom_agent.h"
/* For signalling */ /* For signalling */
#include <libsoup/soup.h> #include <libsoup/soup.h>
@ -44,7 +46,7 @@ enum AppState
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static GMainLoop *loop; static GMainLoop *loop;
static GstElement *pipe1, *webrtc1 = NULL; static GstElement *pipe1, *webrtc1, *audio_bin, *video_bin = NULL;
static GObject *send_channel, *receive_channel; static GObject *send_channel, *receive_channel;
static SoupWebsocketConnection *ws_conn = NULL; static SoupWebsocketConnection *ws_conn = NULL;
@ -54,6 +56,7 @@ static gchar *our_id = NULL;
static const gchar *server_url = "wss://webrtc.nirbheek.in:8443"; static const gchar *server_url = "wss://webrtc.nirbheek.in:8443";
static gboolean disable_ssl = FALSE; static gboolean disable_ssl = FALSE;
static gboolean remote_is_offerer = FALSE; static gboolean remote_is_offerer = FALSE;
static gboolean custom_ice = FALSE;
static GOptionEntry entries[] = { static GOptionEntry entries[] = {
{"peer-id", 0, 0, G_OPTION_ARG_STRING, &peer_id, {"peer-id", 0, 0, G_OPTION_ARG_STRING, &peer_id,
@ -65,6 +68,8 @@ static GOptionEntry entries[] = {
{"disable-ssl", 0, 0, G_OPTION_ARG_NONE, &disable_ssl, "Disable ssl", NULL}, {"disable-ssl", 0, 0, G_OPTION_ARG_NONE, &disable_ssl, "Disable ssl", NULL},
{"remote-offerer", 0, 0, G_OPTION_ARG_NONE, &remote_is_offerer, {"remote-offerer", 0, 0, G_OPTION_ARG_NONE, &remote_is_offerer,
"Request that the peer generate the offer and we'll answer", NULL}, "Request that the peer generate the offer and we'll answer", NULL},
{"custom-ice", 0, 0, G_OPTION_ARG_NONE, &custom_ice,
"Use a custom ice agent", NULL},
{NULL}, {NULL},
}; };
@ -418,24 +423,37 @@ webrtcbin_get_stats (GstElement * webrtcbin)
} }
#define STUN_SERVER " stun-server=stun://stun.l.google.com:19302 " #define STUN_SERVER "stun://stun.l.google.com:19302"
#define RTP_TWCC_URI "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01" #define RTP_TWCC_URI "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
#define RTP_CAPS_OPUS "application/x-rtp,media=audio,encoding-name=OPUS"
#define RTP_OPUS_DEFAULT_PT 97 #define RTP_OPUS_DEFAULT_PT 97
#define RTP_CAPS_VP8 "application/x-rtp,media=video,encoding-name=VP8"
#define RTP_VP8_DEFAULT_PT 96 #define RTP_VP8_DEFAULT_PT 96
static gboolean static gboolean
start_pipeline (gboolean create_offer, guint opus_pt, guint vp8_pt) start_pipeline (gboolean create_offer, guint opus_pt, guint vp8_pt)
{ {
char *pipeline; char *audio_desc, *video_desc;
GstStateChangeReturn ret; GstStateChangeReturn ret;
GError *error = NULL; GstWebRTCICE *custom_agent;
GError *audio_error = NULL;
GError *video_error = NULL;
pipeline = pipe1 = gst_pipeline_new ("webrtc-pipeline");
g_strdup_printf ("webrtcbin bundle-policy=max-bundle name=sendrecv "
STUN_SERVER audio_desc =
"videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! " g_strdup_printf
("audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample"
"! queue ! opusenc ! rtpopuspay name=audiopay ! queue");
audio_bin = gst_parse_bin_from_description (audio_desc, TRUE, &audio_error);
g_free (audio_desc);
if (audio_error) {
gst_printerr ("Failed to parse audio_bin: %s\n", audio_error->message);
g_error_free (audio_error);
goto err;
}
video_desc =
g_strdup_printf
("videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! "
/* increase the default keyframe distance, browsers have really long /* increase the default keyframe distance, browsers have really long
* periods between keyframes and rely on PLI events on packet loss to * periods between keyframes and rely on PLI events on packet loss to
* fix corrupted video. * fix corrupted video.
@ -443,23 +461,35 @@ start_pipeline (gboolean create_offer, guint opus_pt, guint vp8_pt)
"vp8enc deadline=1 keyframe-max-dist=2000 ! " "vp8enc deadline=1 keyframe-max-dist=2000 ! "
/* picture-id-mode=15-bit seems to make TWCC stats behave better, and /* picture-id-mode=15-bit seems to make TWCC stats behave better, and
* fixes stuttery video playback in Chrome */ * fixes stuttery video playback in Chrome */
"rtpvp8pay name=videopay picture-id-mode=15-bit ! " "rtpvp8pay name=videopay picture-id-mode=15-bit ! queue");
"queue ! %s,payload=%u ! sendrecv. " video_bin = gst_parse_bin_from_description (video_desc, TRUE, &video_error);
"audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay name=audiopay ! " g_free (video_desc);
"queue ! %s,payload=%u ! sendrecv. ", RTP_CAPS_VP8, vp8_pt, if (video_error) {
RTP_CAPS_OPUS, opus_pt); gst_printerr ("Failed to parse video_bin: %s\n", video_error->message);
g_error_free (video_error);
pipe1 = gst_parse_launch (pipeline, &error);
g_free (pipeline);
if (error) {
gst_printerr ("Failed to parse launch: %s\n", error->message);
g_error_free (error);
goto err; goto err;
} }
webrtc1 = gst_bin_get_by_name (GST_BIN (pipe1), "sendrecv"); if (custom_ice) {
custom_agent = GST_WEBRTC_ICE (customice_agent_new ("custom"));
webrtc1 = gst_element_factory_make_full ("webrtcbin", "name", "sendrecv",
"bundle-policy", "max-bundle",
"stun-server", STUN_SERVER, "ice-agent", custom_agent, NULL);
} else {
webrtc1 = gst_element_factory_make_full ("webrtcbin", "name", "sendrecv",
"bundle-policy", "max-bundle", "stun-server", STUN_SERVER, NULL);
}
g_assert_nonnull (webrtc1); g_assert_nonnull (webrtc1);
gst_bin_add_many (GST_BIN (pipe1), audio_bin, video_bin, webrtc1, NULL);
if (!gst_element_link (audio_bin, webrtc1)) {
gst_printerr ("Failed to link audio_bin \n");
}
if (!gst_element_link (video_bin, webrtc1)) {
gst_printerr ("Failed to link video_bin \n");
}
if (!create_offer) { if (!create_offer) {
/* XXX: this will fail when the remote offers twcc as the extension id /* XXX: this will fail when the remote offers twcc as the extension id
* cannot currently be negotiated when receiving an offer. * cannot currently be negotiated when receiving an offer.

View file

@ -230906,12 +230906,12 @@
"blurb": "The WebRTC ICE agent", "blurb": "The WebRTC ICE agent",
"conditionally-available": false, "conditionally-available": false,
"construct": false, "construct": false,
"construct-only": false, "construct-only": true,
"controllable": false, "controllable": false,
"mutable": "null", "mutable": "null",
"readable": true, "readable": true,
"type": "GstWebRTCICE", "type": "GstWebRTCICE",
"writable": false "writable": true
}, },
"ice-connection-state": { "ice-connection-state": {
"blurb": "The collective connection state of all ICETransport's", "blurb": "The collective connection state of all ICETransport's",
@ -231298,93 +231298,6 @@
"writable": false "writable": false
} }
} }
},
"GstWebRTCICE": {
"hierarchy": [
"GstWebRTCICE",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
"kind": "object",
"properties": {
"agent": {
"blurb": "ICE agent in use by this object. WARNING! Accessing this property may have disastrous consequences for the operation of webrtcbin. Other ICE implementations may not have the same interface.",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"mutable": "null",
"readable": true,
"type": "NiceAgent",
"writable": false
},
"ice-tcp": {
"blurb": "Whether the agent should use ICE-TCP when gathering candidates",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"ice-udp": {
"blurb": "Whether the agent should use ICE-UDP when gathering candidates",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"max-rtp-port": {
"blurb": "Maximum port for local rtp port range. max-rtp-port must be >= min-rtp-port",
"conditionally-available": false,
"construct": true,
"construct-only": false,
"controllable": false,
"default": "65535",
"max": "65535",
"min": "0",
"mutable": "null",
"readable": true,
"type": "guint",
"writable": true
},
"min-rtp-port": {
"blurb": "Minimum port for local rtp port range. min-rtp-port must be <= max-rtp-port",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "0",
"max": "65535",
"min": "0",
"mutable": "null",
"readable": true,
"type": "guint",
"writable": true
}
},
"signals": {
"add-local-ip-address": {
"action": true,
"args": [
{
"name": "arg0",
"type": "gchararray"
}
],
"return-type": "gboolean",
"when": "last"
}
}
} }
}, },
"package": "GStreamer Bad Plug-ins", "package": "GStreamer Bad Plug-ins",

View file

@ -29,18 +29,6 @@ typedef struct _GstWebRTCBin GstWebRTCBin;
typedef struct _GstWebRTCBinClass GstWebRTCBinClass; typedef struct _GstWebRTCBinClass GstWebRTCBinClass;
typedef struct _GstWebRTCBinPrivate GstWebRTCBinPrivate; typedef struct _GstWebRTCBinPrivate GstWebRTCBinPrivate;
typedef struct _GstWebRTCICE GstWebRTCICE;
typedef struct _GstWebRTCICEClass GstWebRTCICEClass;
typedef struct _GstWebRTCICEPrivate GstWebRTCICEPrivate;
typedef struct _GstWebRTCICEStream GstWebRTCICEStream;
typedef struct _GstWebRTCICEStreamClass GstWebRTCICEStreamClass;
typedef struct _GstWebRTCICEStreamPrivate GstWebRTCICEStreamPrivate;
typedef struct _GstWebRTCNiceTransport GstWebRTCNiceTransport;
typedef struct _GstWebRTCNiceTransportClass GstWebRTCNiceTransportClass;
typedef struct _GstWebRTCNiceTransportPrivate GstWebRTCNiceTransportPrivate;
typedef struct _GstWebRTCSCTPTransport GstWebRTCSCTPTransport; typedef struct _GstWebRTCSCTPTransport GstWebRTCSCTPTransport;
typedef struct _GstWebRTCSCTPTransportClass GstWebRTCSCTPTransportClass; typedef struct _GstWebRTCSCTPTransportClass GstWebRTCSCTPTransportClass;
typedef struct _GstWebRTCSCTPTransportPrivate GstWebRTCSCTPTransportPrivate; typedef struct _GstWebRTCSCTPTransportPrivate GstWebRTCSCTPTransportPrivate;
@ -57,8 +45,6 @@ typedef struct _TransportReceiveBinClass TransportReceiveBinClass;
typedef struct _WebRTCTransceiver WebRTCTransceiver; typedef struct _WebRTCTransceiver WebRTCTransceiver;
typedef struct _WebRTCTransceiverClass WebRTCTransceiverClass; typedef struct _WebRTCTransceiverClass WebRTCTransceiverClass;
typedef struct _GstWebRTCICECandidateStats GstWebRTCICECandidateStats;
G_END_DECLS G_END_DECLS
#endif /* __WEBRTC_FWD_H__ */ #endif /* __WEBRTC_FWD_H__ */

View file

@ -32,7 +32,7 @@
#include "webrtcsctptransport.h" #include "webrtcsctptransport.h"
#include "gst/webrtc/webrtc-priv.h" #include "gst/webrtc/webrtc-priv.h"
#include <gst/webrtc/nice/nice.h>
#include <gst/rtp/rtp.h> #include <gst/rtp/rtp.h>
#include <stdio.h> #include <stdio.h>
@ -8053,6 +8053,9 @@ gst_webrtc_bin_set_property (GObject * object, guint prop_id,
webrtc->priv->jb_latency = g_value_get_uint (value); webrtc->priv->jb_latency = g_value_get_uint (value);
_update_rtpstorage_latency (webrtc); _update_rtpstorage_latency (webrtc);
break; break;
case PROP_ICE_AGENT:
webrtc->priv->ice = g_value_get_object (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -8143,13 +8146,13 @@ gst_webrtc_bin_constructed (GObject * object)
GstWebRTCBin *webrtc = GST_WEBRTC_BIN (object); GstWebRTCBin *webrtc = GST_WEBRTC_BIN (object);
gchar *name; gchar *name;
if (!webrtc->priv->ice) {
name = g_strdup_printf ("%s:ice", GST_OBJECT_NAME (webrtc)); name = g_strdup_printf ("%s:ice", GST_OBJECT_NAME (webrtc));
webrtc->priv->ice = gst_webrtc_ice_new (name); webrtc->priv->ice = GST_WEBRTC_ICE (gst_webrtc_nice_new (name));
gst_webrtc_ice_set_on_ice_candidate (webrtc->priv->ice,
(GstWebRTCIceOnCandidateFunc) _on_local_ice_candidate_cb, webrtc, NULL);
g_free (name); g_free (name);
}
gst_webrtc_ice_set_on_ice_candidate (webrtc->priv->ice,
(GstWebRTCICEOnCandidateFunc) _on_local_ice_candidate_cb, webrtc, NULL);
G_OBJECT_CLASS (parent_class)->constructed (object); G_OBJECT_CLASS (parent_class)->constructed (object);
} }
@ -8392,7 +8395,8 @@ gst_webrtc_bin_class_init (GstWebRTCBinClass * klass)
PROP_ICE_AGENT, PROP_ICE_AGENT,
g_param_spec_object ("ice-agent", "WebRTC ICE agent", g_param_spec_object ("ice-agent", "WebRTC ICE agent",
"The WebRTC ICE agent", "The WebRTC ICE agent",
GST_TYPE_WEBRTC_ICE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); GST_TYPE_WEBRTC_ICE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
/** /**
* GstWebRTCBin:latency: * GstWebRTCBin:latency:
@ -8736,7 +8740,6 @@ gst_webrtc_bin_class_init (GstWebRTCBinClass * klass)
NULL, GST_TYPE_WEBRTC_DATA_CHANNEL, 2, G_TYPE_STRING, GST_TYPE_STRUCTURE); NULL, GST_TYPE_WEBRTC_DATA_CHANNEL, 2, G_TYPE_STRING, GST_TYPE_STRUCTURE);
gst_type_mark_as_plugin_api (GST_TYPE_WEBRTC_BIN_PAD, 0); gst_type_mark_as_plugin_api (GST_TYPE_WEBRTC_BIN_PAD, 0);
gst_type_mark_as_plugin_api (GST_TYPE_WEBRTC_ICE, 0);
} }
static void static void

View file

@ -22,7 +22,6 @@
#include <gst/sdp/sdp.h> #include <gst/sdp/sdp.h>
#include "fwd.h" #include "fwd.h"
#include "gstwebrtcice.h"
#include "transportstream.h" #include "transportstream.h"
#include "webrtcsctptransport.h" #include "webrtcsctptransport.h"

View file

@ -26,7 +26,6 @@
#include "gstwebrtcstats.h" #include "gstwebrtcstats.h"
#include "gstwebrtcbin.h" #include "gstwebrtcbin.h"
#include "icestream.h"
#include "transportstream.h" #include "transportstream.h"
#include "transportreceivebin.h" #include "transportreceivebin.h"
#include "utils.h" #include "utils.h"

View file

@ -1,9 +1,6 @@
webrtc_sources = [ webrtc_sources = [
'gstwebrtc.c', 'gstwebrtc.c',
'gstwebrtcice.c',
'gstwebrtcstats.c', 'gstwebrtcstats.c',
'icestream.c',
'nicetransport.c',
'webrtcsctptransport.c', 'webrtcsctptransport.c',
'gstwebrtcbin.c', 'gstwebrtcbin.c',
'transportreceivebin.c', 'transportreceivebin.c',
@ -15,37 +12,15 @@ webrtc_sources = [
'webrtcdatachannel.c', 'webrtcdatachannel.c',
] ]
libnice_dep = dependency('nice', version : '>=0.1.17', required : get_option('webrtc'), gstwebrtc_plugin = library('gstwebrtc',
fallback : ['libnice', 'libnice_dep'],
default_options: ['tests=disabled'])
if libnice_dep.found()
libnice_version = libnice_dep.version()
libnice_c_args = []
if libnice_version.version_compare('<0.1.20') or libnice_version.version_compare('<0.1.19.1')
version_arr = libnice_version.split('.')
libnice_version_major = version_arr[0]
libnice_version_minor = version_arr[1]
libnice_version_micro = version_arr[2]
if version_arr.length() == 4
libnice_version_nano = version_arr[3]
else
libnice_version_nano = '0'
endif
libnice_c_args = ['-DNICE_VERSION_MAJOR=' + libnice_version_major,
'-DNICE_VERSION_MINOR=' + libnice_version_minor,
'-DNICE_VERSION_MICRO=' + libnice_version_micro,
'-DNICE_VERSION_NANO=' + libnice_version_nano ]
endif
gstwebrtc_plugin = library('gstwebrtc',
webrtc_sources, webrtc_sources,
c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'] + libnice_c_args, c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'],
include_directories : [configinc], include_directories : [configinc],
dependencies : [gstbase_dep, gstsdp_dep, dependencies : [gstbase_dep, gstsdp_dep,
gstapp_dep, gstwebrtc_dep, gstsctp_dep, gstrtp_dep, libnice_dep, gio_dep], gstapp_dep, gstwebrtc_dep, gstsctp_dep, gstrtp_dep, gio_dep, libgstwebrtcnice_dep],
install : true, install : true,
install_dir : plugins_install_dir, install_dir : plugins_install_dir,
) )
pkgconfig.generate(gstwebrtc_plugin, install_dir : plugins_pkgconfig_install_dir) pkgconfig.generate(gstwebrtc_plugin, install_dir : plugins_pkgconfig_install_dir)
plugins += [gstwebrtc_plugin] plugins += [gstwebrtc_plugin]
endif

View file

@ -24,7 +24,6 @@
#include "transportstream.h" #include "transportstream.h"
#include "transportsendbin.h" #include "transportsendbin.h"
#include "transportreceivebin.h" #include "transportreceivebin.h"
#include "gstwebrtcice.h"
#include "gstwebrtcbin.h" #include "gstwebrtcbin.h"
#include "utils.h" #include "utils.h"
#include "gst/webrtc/webrtc-priv.h" #include "gst/webrtc/webrtc-priv.h"

View file

@ -23,7 +23,7 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/webrtc/webrtc.h> #include <gst/webrtc/webrtc.h>
#include <gst/webrtc/sctptransport.h> #include <gst/webrtc/sctptransport.h>
#include "gstwebrtcice.h" #include "fwd.h"
#include "gst/webrtc/webrtc-priv.h" #include "gst/webrtc/webrtc-priv.h"

View file

@ -0,0 +1,523 @@
/* 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "ice.h"
#include "icestream.h"
#include "webrtc-priv.h"
#define GST_CAT_DEFAULT gst_webrtc_ice_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum
{
SIGNAL_0,
ADD_LOCAL_IP_ADDRESS_SIGNAL,
LAST_SIGNAL,
};
enum
{
PROP_0,
PROP_MIN_RTP_PORT,
PROP_MAX_RTP_PORT,
};
static guint gst_webrtc_ice_signals[LAST_SIGNAL] = { 0 };
#define gst_webrtc_ice_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCICE, gst_webrtc_ice,
GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_debug,
"webrtcice", 0, "webrtcice"););
/**
* gst_webrtc_ice_add_stream:
* @ice: The #GstWebRTCICE
* @session_id: The session id
*
* Returns: (transfer full) (nullable): The #GstWebRTCICEStream, or %NULL
* Since: 1.22
*/
GstWebRTCICEStream *
gst_webrtc_ice_add_stream (GstWebRTCICE * ice, guint session_id)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream);
return GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream (ice, session_id);
}
/**
* gst_webrtc_ice_find_transport:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @component: The #GstWebRTCICEComponent
*
* Returns: (transfer full) (nullable): The #GstWebRTCICETransport, or %NULL
* Since: 1.22
*/
GstWebRTCICETransport *
gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEComponent component)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport);
return GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport (ice, stream,
component);
}
/**
* gst_webrtc_ice_add_candidate:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @candidate: The ICE candidate
* Since: 1.22
*/
void
gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, const gchar * candidate)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate);
GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate);
}
/**
* gst_webrtc_ice_set_remote_credentials:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @ufrag: ICE username
* @pwd: ICE password
* Returns: FALSE on error, TRUE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials);
return GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials (ice, stream,
ufrag, pwd);
}
/**
* gst_webrtc_ice_add_turn_server:
* @ice: The #GstWebRTCICE
* @uri: URI of the TURN server
* Returns: FALSE on error, TRUE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice, const gchar * uri)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server);
return GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server (ice, uri);
}
/**
* gst_webrtc_ice_set_local_credentials:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @ufrag: ICE username
* @pwd: ICE password
* Returns: FALSE on error, TRUE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials);
return GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials (ice, stream,
ufrag, pwd);
}
/**
* gst_webrtc_ice_gather_candidates:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* Returns: FALSE on error, TRUE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates);
return GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates (ice, stream);
}
/**
* gst_webrtc_ice_set_is_controller:
* @ice: The #GstWebRTCICE
* @controller: TRUE to set as controller
* Since: 1.22
*/
void
gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice, gboolean controller)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller (ice, controller);
}
/**
* gst_webrtc_ice_get_is_controller:
* @ice: The #GstWebRTCICE
* Returns: TRUE if set as controller, FALSE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller (ice);
}
/**
* gst_webrtc_ice_set_force_relay:
* @ice: The #GstWebRTCICE
* @force_relay: TRUE to enable force relay
* Since: 1.22
*/
void
gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice, gboolean force_relay)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay (ice, force_relay);
}
/**
* gst_webrtc_ice_set_tos:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @tos: ToS to be set
* Since: 1.22
*/
void
gst_webrtc_ice_set_tos (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
guint tos)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos (ice, stream, tos);
}
/**
* gst_webrtc_ice_get_local_candidates:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* Returns: (transfer full) (element-type GstWebRTCICECandidateStats): List of local candidates
* Since: 1.22
*/
GArray *
gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates (ice, stream);
}
/**
* gst_webrtc_ice_get_remote_candidates:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* Returns: (transfer full) (element-type GstWebRTCICECandidateStats): List of remote candidates
* Since: 1.22
*/
GArray *
gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates (ice, stream);
}
/**
* gst_webrtc_ice_get_selected_pair:
* @ice: The #GstWebRTCICE
* @stream: The #GstWebRTCICEStream
* @local_stats: A pointer to #GstWebRTCICECandidateStats for local candidate
* @remote_stats: A pointer to #GstWebRTCICECandidateStats for remote candidate
*
* Returns: FALSE on failure, otherwise @local_stats @remote_stats will be set
* Since: 1.22
*/
gboolean
gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICECandidateStats ** local_stats,
GstWebRTCICECandidateStats ** remote_stats)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair (ice, stream,
local_stats, remote_stats);
}
/**
* gst_webrtc_ice_candidate_stats_free:
* @stats: The #GstWebRTCICECandidateStats to be free'd
*
* Helper function to free #GstWebRTCICECandidateStats
* Since: 1.22
*/
void
gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats)
{
if (stats) {
g_free (stats->ipaddr);
g_free (stats->url);
}
g_free (stats);
}
/**
* gst_webrtc_ice_set_on_ice_candidate:
* @ice: The #GstWebRTCICE
* @func: The #GstWebRTCICEOnCandidateFunc callback function
* @user_data: User data passed to the callback function
* @notify: a #GDestroyNotify when the candidate is no longer needed
* Since: 1.22
*/
void
gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice,
GstWebRTCICEOnCandidateFunc func, gpointer user_data, GDestroyNotify notify)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate (ice, func, user_data,
notify);
}
/**
* gst_webrtc_ice_set_stun_server:
* @ice: The #GstWebRTCICE
* @uri: URI of the STUN server
* Since: 1.22
*/
void
gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice, const gchar * uri_s)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server (ice, uri_s);
}
/**
* gst_webrtc_ice_get_stun_server:
* @ice: The #GstWebRTCICE
* Returns: URI of the STUN sever
* Since: 1.22
*/
gchar *
gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server (ice);
}
/**
* gst_webrtc_ice_set_turn_server:
* @ice: The #GstWebRTCICE
* @uri: URI of the TURN sever
* Since: 1.22
*/
void
gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice, const gchar * uri_s)
{
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server);
GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server (ice, uri_s);
}
/**
* gst_webrtc_ice_get_turn_server:
* @ice: The #GstWebRTCICE
* Returns: URI of the TURN sever
* Since: 1.22
*/
gchar *
gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server);
return GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server (ice);
}
static void
gst_webrtc_ice_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
switch (prop_id) {
case PROP_MIN_RTP_PORT:
ice->min_rtp_port = g_value_get_uint (value);
if (ice->min_rtp_port > ice->max_rtp_port)
g_warning ("Set min-rtp-port to %u which is larger than"
" max-rtp-port %u", ice->min_rtp_port, ice->max_rtp_port);
break;
case PROP_MAX_RTP_PORT:
ice->max_rtp_port = g_value_get_uint (value);
if (ice->min_rtp_port > ice->max_rtp_port)
g_warning ("Set max-rtp-port to %u which is smaller than"
" min-rtp-port %u", ice->max_rtp_port, ice->min_rtp_port);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_webrtc_ice_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
switch (prop_id) {
case PROP_MIN_RTP_PORT:
g_value_set_uint (value, ice->min_rtp_port);
break;
case PROP_MAX_RTP_PORT:
g_value_set_uint (value, ice->max_rtp_port);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_webrtc_ice_class_init (GstWebRTCICEClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
klass->add_stream = NULL;
klass->find_transport = NULL;
klass->gather_candidates = NULL;
klass->add_candidate = NULL;
klass->set_local_credentials = NULL;
klass->set_remote_credentials = NULL;
klass->add_turn_server = NULL;
klass->set_is_controller = NULL;
klass->get_is_controller = NULL;
klass->set_force_relay = NULL;
klass->set_stun_server = NULL;
klass->get_stun_server = NULL;
klass->set_turn_server = NULL;
klass->get_turn_server = NULL;
klass->set_tos = NULL;
klass->set_on_ice_candidate = NULL;
klass->get_local_candidates = NULL;
klass->get_remote_candidates = NULL;
klass->get_selected_pair = NULL;
gobject_class->get_property = gst_webrtc_ice_get_property;
gobject_class->set_property = gst_webrtc_ice_set_property;
/**
* GstWebRTCICE:min-rtp-port:
*
* Minimum port for local rtp port range.
* min-rtp-port must be <= max-rtp-port
*
* Since: 1.20
*/
g_object_class_install_property (gobject_class,
PROP_MIN_RTP_PORT,
g_param_spec_uint ("min-rtp-port", "ICE RTP candidate min port",
"Minimum port for local rtp port range. "
"min-rtp-port must be <= max-rtp-port",
0, 65535, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
/**
* GstWebRTCICE:max-rtp-port:
*
* Maximum port for local rtp port range.
* min-rtp-port must be <= max-rtp-port
*
* Since: 1.20
*/
g_object_class_install_property (gobject_class,
PROP_MAX_RTP_PORT,
g_param_spec_uint ("max-rtp-port", "ICE RTP candidate max port",
"Maximum port for local rtp port range. "
"max-rtp-port must be >= min-rtp-port",
0, 65535, 65535,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
/**
* GstWebRTCICE::add-local-ip-address:
* @object: the #GstWebRTCICE
* @address: The local IP address
*
* Add a local IP address to use for ICE candidate gathering. If none
* are supplied, they will be discovered automatically. Calling this signal
* stops automatic ICE gathering.
*
* Returns: whether the address could be added.
*/
gst_webrtc_ice_signals[ADD_LOCAL_IP_ADDRESS_SIGNAL] =
g_signal_new_class_handler ("add-local-ip-address",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
NULL, NULL, NULL,
g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
}
static void
gst_webrtc_ice_init (GstWebRTCICE * ice)
{
}

View file

@ -20,16 +20,11 @@
#ifndef __GST_WEBRTC_ICE_H__ #ifndef __GST_WEBRTC_ICE_H__
#define __GST_WEBRTC_ICE_H__ #define __GST_WEBRTC_ICE_H__
#include <gst/gst.h> #include <gst/webrtc/webrtc_fwd.h>
#include <gst/sdp/sdp.h>
#include <gst/webrtc/webrtc.h>
#include "fwd.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_WEBRTC_ICE_ERROR gst_webrtc_ice_error_quark () GST_WEBRTC_API
GQuark gst_webrtc_ice_error_quark (void);
GType gst_webrtc_ice_get_type(void); GType gst_webrtc_ice_get_type(void);
#define GST_TYPE_WEBRTC_ICE (gst_webrtc_ice_get_type()) #define GST_TYPE_WEBRTC_ICE (gst_webrtc_ice_get_type())
#define GST_WEBRTC_ICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_ICE,GstWebRTCICE)) #define GST_WEBRTC_ICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_ICE,GstWebRTCICE))
@ -44,14 +39,6 @@ struct _GstWebRTCICE
GstWebRTCICEGatheringState ice_gathering_state; GstWebRTCICEGatheringState ice_gathering_state;
GstWebRTCICEConnectionState ice_connection_state; GstWebRTCICEConnectionState ice_connection_state;
GstUri *stun_server;
GstUri *turn_server;
GHashTable *turn_servers;
GstWebRTCICEPrivate *priv;
guint min_rtp_port; guint min_rtp_port;
guint max_rtp_port; guint max_rtp_port;
}; };
@ -68,69 +55,160 @@ struct _GstWebRTCICECandidateStats
gchar *url; gchar *url;
}; };
struct _GstWebRTCICEClass /**
{ * GstWebRTCICEOnCandidateFunc:
GstObjectClass parent_class; * @ice: The #GstWebRTCICE
* @stream_id: The stream id
* @candidate: The discovered candidate
* @user_data: User data that was set by #gst_webrtc_ice_set_on_ice_candidate
*
* Callback function to be triggered on discovery of a new candidate
* Since: 1.22
*/
typedef void (*GstWebRTCICEOnCandidateFunc) (GstWebRTCICE * ice, guint stream_id, gchar * candidate, gpointer user_data);
struct _GstWebRTCICEClass {
GObjectClass parent_class;
GstWebRTCICEStream * (*add_stream) (GstWebRTCICE * ice,
guint session_id);
GstWebRTCICETransport * (*find_transport) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
GstWebRTCICEComponent component);
gboolean (*gather_candidates) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream);
void (*add_candidate) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
const gchar * candidate);
gboolean (*set_local_credentials) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
gchar * ufrag,
gchar * pwd);
gboolean (*set_remote_credentials) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
gchar * ufrag,
gchar * pwd);
gboolean (*add_turn_server) (GstWebRTCICE * ice,
const gchar * uri);
void (*set_is_controller) (GstWebRTCICE * ice,
gboolean controller);
gboolean (*get_is_controller) (GstWebRTCICE * ice);
void (*set_force_relay) (GstWebRTCICE * ice,
gboolean force_relay);
void (*set_stun_server) (GstWebRTCICE * ice,
const gchar * uri);
gchar * (*get_stun_server) (GstWebRTCICE * ice);
void (*set_turn_server) (GstWebRTCICE * ice,
const gchar * uri);
gchar * (*get_turn_server) (GstWebRTCICE * ice);
void (*set_tos) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
guint tos);
void (*set_on_ice_candidate) (GstWebRTCICE * ice,
GstWebRTCICEOnCandidateFunc func,
gpointer user_data,
GDestroyNotify notify);
GArray * (*get_local_candidates) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream);
GArray * (*get_remote_candidates) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream);
gboolean (*get_selected_pair) (GstWebRTCICE * ice,
GstWebRTCICEStream * stream,
GstWebRTCICECandidateStats ** local_stats,
GstWebRTCICECandidateStats ** remote_stats);
}; };
GstWebRTCICE * gst_webrtc_ice_new (const gchar * name); GST_WEBRTC_API
GstWebRTCICEStream * gst_webrtc_ice_add_stream (GstWebRTCICE * ice, GstWebRTCICEStream * gst_webrtc_ice_add_stream (GstWebRTCICE * ice,
guint session_id); guint session_id);
GST_WEBRTC_API
GstWebRTCICETransport * gst_webrtc_ice_find_transport (GstWebRTCICE * ice, GstWebRTCICETransport * gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
GstWebRTCICEComponent component); GstWebRTCICEComponent component);
GST_WEBRTC_API
gboolean gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice, gboolean gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream); GstWebRTCICEStream * stream);
/* FIXME: GstStructure-ize the candidate */ /* FIXME: GstStructure-ize the candidate */
GST_WEBRTC_API
void gst_webrtc_ice_add_candidate (GstWebRTCICE * ice, void gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
const gchar * candidate); const gchar * candidate);
GST_WEBRTC_API
gboolean gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice, gboolean gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
gchar * ufrag, gchar * ufrag,
gchar * pwd); gchar * pwd);
GST_WEBRTC_API
gboolean gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice, gboolean gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
gchar * ufrag, gchar * ufrag,
gchar * pwd); gchar * pwd);
GST_WEBRTC_API
gboolean gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice, gboolean gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice,
const gchar * uri); const gchar * uri);
GST_WEBRTC_API
void gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice, void gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice,
gboolean controller); gboolean controller);
GST_WEBRTC_API
gboolean gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice); gboolean gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice);
GST_WEBRTC_API
void gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice, void gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice,
gboolean force_relay); gboolean force_relay);
GST_WEBRTC_API
void gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice, void gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice,
const gchar * uri); const gchar * uri);
GST_WEBRTC_API
gchar * gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice); gchar * gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice);
GST_WEBRTC_API
void gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice, void gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice,
const gchar * uri); const gchar * uri);
GST_WEBRTC_API
gchar * gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice); gchar * gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice);
typedef void (*GstWebRTCIceOnCandidateFunc) (GstWebRTCICE * ice, guint stream_id, gchar * candidate, gpointer user_data); GST_WEBRTC_API
void gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice, void gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice,
GstWebRTCIceOnCandidateFunc func, GstWebRTCICEOnCandidateFunc func,
gpointer user_data, gpointer user_data,
GDestroyNotify notify); GDestroyNotify notify);
GST_WEBRTC_API
void gst_webrtc_ice_set_tos (GstWebRTCICE * ice, void gst_webrtc_ice_set_tos (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
guint tos); guint tos);
GST_WEBRTC_API
GArray * gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice, GArray * gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream); GstWebRTCICEStream * stream);
GST_WEBRTC_API
GArray * gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice, GArray * gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice,
GstWebRTCICEStream * stream); GstWebRTCICEStream * stream);
GST_WEBRTC_API
gboolean gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice, gboolean gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice,
GstWebRTCICEStream * stream, GstWebRTCICEStream * stream,
GstWebRTCICECandidateStats ** local_stats, GstWebRTCICECandidateStats ** local_stats,
GstWebRTCICECandidateStats ** remote_stats); GstWebRTCICECandidateStats ** remote_stats);
GST_WEBRTC_API
void gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats); void gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCICE, gst_object_unref)
G_END_DECLS G_END_DECLS
#endif /* __GST_WEBRTC_ICE_H__ */ #endif /* __GST_WEBRTC_ICE_H__ */

View file

@ -0,0 +1,130 @@
/* 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "icestream.h"
#include "webrtc-priv.h"
#define GST_CAT_DEFAULT gst_webrtc_ice_stream_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum
{
PROP_0,
PROP_STREAM_ID,
};
#define gst_webrtc_ice_stream_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCICEStream, gst_webrtc_ice_stream,
GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_stream_debug,
"webrtcicestream", 0, "webrtcicestream"););
static void
gst_webrtc_ice_stream_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object);
switch (prop_id) {
case PROP_STREAM_ID:
stream->stream_id = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_webrtc_ice_stream_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object);
switch (prop_id) {
case PROP_STREAM_ID:
g_value_set_uint (value, stream->stream_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* gst_webrtc_ice_stream_find_transport:
* @stream: the #GstWebRTCICEStream
* @component: The #GstWebRTCICEComponent
*
* Returns: (transfer full) (nullable): the #GstWebRTCICETransport, or %NULL
* Since: 1.22
*/
GstWebRTCICETransport *
gst_webrtc_ice_stream_find_transport (GstWebRTCICEStream * stream,
GstWebRTCICEComponent component)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE_STREAM (stream), NULL);
g_assert (GST_WEBRTC_ICE_STREAM_GET_CLASS (stream)->find_transport);
return GST_WEBRTC_ICE_STREAM_GET_CLASS (stream)->find_transport (stream,
component);
}
/**
* gst_webrtc_ice_stream_gather_candidates:
* @ice: the #GstWebRTCICEStream
* Returns: FALSE on error, TRUE otherwise
* Since: 1.22
*/
gboolean
gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * stream)
{
g_return_val_if_fail (GST_IS_WEBRTC_ICE_STREAM (stream), FALSE);
g_assert (GST_WEBRTC_ICE_STREAM_GET_CLASS (stream)->gather_candidates);
return GST_WEBRTC_ICE_STREAM_GET_CLASS (stream)->gather_candidates (stream);
}
static void
gst_webrtc_ice_stream_class_init (GstWebRTCICEStreamClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
klass->find_transport = NULL;
klass->gather_candidates = NULL;
gobject_class->get_property = gst_webrtc_ice_stream_get_property;
gobject_class->set_property = gst_webrtc_ice_stream_set_property;
g_object_class_install_property (gobject_class,
PROP_STREAM_ID,
g_param_spec_uint ("stream-id",
"ICE stream id", "ICE stream id associated with this stream",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
static void
gst_webrtc_ice_stream_init (GstWebRTCICEStream * stream)
{
}

View file

@ -20,14 +20,11 @@
#ifndef __GST_WEBRTC_ICE_STREAM_H__ #ifndef __GST_WEBRTC_ICE_STREAM_H__
#define __GST_WEBRTC_ICE_STREAM_H__ #define __GST_WEBRTC_ICE_STREAM_H__
#include <gst/gst.h> #include "ice.h"
/* libice */
#include <agent.h>
#include <gst/webrtc/webrtc.h>
#include "gstwebrtcice.h"
G_BEGIN_DECLS G_BEGIN_DECLS
GST_WEBRTC_API
GType gst_webrtc_ice_stream_get_type(void); GType gst_webrtc_ice_stream_get_type(void);
#define GST_TYPE_WEBRTC_ICE_STREAM (gst_webrtc_ice_stream_get_type()) #define GST_TYPE_WEBRTC_ICE_STREAM (gst_webrtc_ice_stream_get_type())
#define GST_WEBRTC_ICE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_ICE_STREAM,GstWebRTCICEStream)) #define GST_WEBRTC_ICE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_ICE_STREAM,GstWebRTCICEStream))
@ -39,25 +36,26 @@ GType gst_webrtc_ice_stream_get_type(void);
struct _GstWebRTCICEStream struct _GstWebRTCICEStream
{ {
GstObject parent; GstObject parent;
GWeakRef ice_weak;
guint stream_id; guint stream_id;
GstWebRTCICEStreamPrivate *priv;
}; };
struct _GstWebRTCICEStreamClass struct _GstWebRTCICEStreamClass
{ {
GstObjectClass parent_class; GstObjectClass parent_class;
GstWebRTCICETransport * (*find_transport) (GstWebRTCICEStream * stream,
GstWebRTCICEComponent component);
gboolean (*gather_candidates) (GstWebRTCICEStream * ice);
}; };
GstWebRTCICEStream * gst_webrtc_ice_stream_new (GstWebRTCICE * ice,
guint stream_id); GST_WEBRTC_API
GstWebRTCICETransport * gst_webrtc_ice_stream_find_transport (GstWebRTCICEStream * stream, GstWebRTCICETransport * gst_webrtc_ice_stream_find_transport (GstWebRTCICEStream * stream,
GstWebRTCICEComponent component); GstWebRTCICEComponent component);
GST_WEBRTC_API
gboolean gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * ice); gboolean gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * ice);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCICEStream, gst_object_unref)
G_END_DECLS G_END_DECLS
#endif /* __GST_WEBRTC_ICE_STREAM_H__ */ #endif /* __GST_WEBRTC_ICE_STREAM_H__ */

View file

@ -20,7 +20,6 @@
#ifndef __GST_WEBRTC_ICE_TRANSPORT_H__ #ifndef __GST_WEBRTC_ICE_TRANSPORT_H__
#define __GST_WEBRTC_ICE_TRANSPORT_H__ #define __GST_WEBRTC_ICE_TRANSPORT_H__
#include <gst/gst.h>
#include <gst/webrtc/webrtc_fwd.h> #include <gst/webrtc/webrtc_fwd.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -33,6 +32,42 @@ GType gst_webrtc_ice_transport_get_type(void);
#define GST_WEBRTC_ICE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_ICE_TRANSPORT,GstWebRTCICETransportClass)) #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_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)) #define GST_WEBRTC_ICE_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_ICE_TRANSPORT,GstWebRTCICETransportClass))
struct _GstWebRTCICETransport
{
GstObject parent;
/* <protected> */
GstWebRTCICERole role;
GstWebRTCICEComponent component;
GstWebRTCICEConnectionState state;
GstWebRTCICEGatheringState gathering_state;
/* Filled by subclasses */
GstElement *src;
GstElement *sink;
gpointer _padding[GST_PADDING];
};
struct _GstWebRTCICETransportClass
{
GstObjectClass parent_class;
gboolean (*gather_candidates) (GstWebRTCICETransport * transport);
gpointer _padding[GST_PADDING];
};
GST_WEBRTC_API
void gst_webrtc_ice_transport_connection_state_change (GstWebRTCICETransport * ice,
GstWebRTCICEConnectionState new_state);
GST_WEBRTC_API
void gst_webrtc_ice_transport_gathering_state_change (GstWebRTCICETransport * ice,
GstWebRTCICEGatheringState new_state);
GST_WEBRTC_API
void gst_webrtc_ice_transport_selected_pair_change (GstWebRTCICETransport * ice);
GST_WEBRTC_API
void gst_webrtc_ice_transport_new_candidate (GstWebRTCICETransport * ice, guint stream_id, GstWebRTCICEComponent component, gchar * attr);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCICETransport, gst_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCICETransport, gst_object_unref)

View file

@ -1,5 +1,7 @@
webrtc_sources = files([ webrtc_sources = files([
'dtlstransport.c', 'dtlstransport.c',
'ice.c',
'icestream.c',
'icetransport.c', 'icetransport.c',
'rtcsessiondescription.c', 'rtcsessiondescription.c',
'rtpreceiver.c', 'rtpreceiver.c',
@ -12,6 +14,8 @@ webrtc_sources = files([
webrtc_headers = files([ webrtc_headers = files([
'dtlstransport.h', 'dtlstransport.h',
'ice.h',
'icestream.h',
'icetransport.h', 'icetransport.h',
'rtcsessiondescription.h', 'rtcsessiondescription.h',
'rtpreceiver.h', 'rtpreceiver.h',
@ -25,6 +29,8 @@ webrtc_headers = files([
webrtc_enumtypes_headers = files([ webrtc_enumtypes_headers = files([
'dtlstransport.h', 'dtlstransport.h',
'ice.h',
'icestream.h',
'icetransport.h', 'icetransport.h',
'rtptransceiver.h', 'rtptransceiver.h',
'webrtc_fwd.h', 'webrtc_fwd.h',
@ -95,3 +101,5 @@ gstwebrtc_dep = declare_dependency(link_with: gstwebrtc,
dependencies: gstwebrtc_dependencies) dependencies: gstwebrtc_dependencies)
meson.override_dependency(pkg_name, gstwebrtc_dep) meson.override_dependency(pkg_name, gstwebrtc_dep)
subdir('nice')

View file

@ -0,0 +1,64 @@
libgstwebrtcnice_sources = files([
'nice.c',
'nicestream.c',
'nicetransport.c',
])
libgstwebrtcnice_headers = files([
'nice_fwd.h',
'nice.h',
'nicestream.h',
'nicetransport.h',
])
libnice_dep = dependency('nice', version : '>=0.1.17', required : get_option('webrtc'),
fallback : ['libnice', 'libnice_dep'],
default_options: ['tests=disabled'])
deps = [gstwebrtc_dep, libnice_dep]
if libnice_dep.found()
libnice_version = libnice_dep.version()
libnice_c_args = []
if libnice_version.version_compare('<0.1.20') or libnice_version.version_compare('<0.1.19.1')
version_arr = libnice_version.split('.')
libnice_version_major = version_arr[0]
libnice_version_minor = version_arr[1]
libnice_version_micro = version_arr[2]
if version_arr.length() == 4
libnice_version_nano = version_arr[3]
else
libnice_version_nano = '0'
endif
libnice_c_args = ['-DNICE_VERSION_MAJOR=' + libnice_version_major,
'-DNICE_VERSION_MINOR=' + libnice_version_minor,
'-DNICE_VERSION_MICRO=' + libnice_version_micro,
'-DNICE_VERSION_NANO=' + libnice_version_nano ]
endif
libgstwebrtcnice = library('gstwebrtcnice-' + api_version,
libgstwebrtcnice_sources, libgstwebrtcnice_headers,
c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API', '-DBUILDING_GST_WEBRTCNICE', '-DG_LOG_DOMAIN="GStreamer-webrtcnice"'] + libnice_c_args,
include_directories: [configinc],
version : libversion,
soversion : soversion,
darwin_versions : osxversion,
dependencies: deps,
install: true,
)
pkg_name = 'gstreamer-webrtc-nice-1.0'
libraries += [[pkg_name, {'lib': libgstwebrtcnice}]]
pkgconfig.generate(libgstwebrtcnice,
libraries : [deps],
variables : pkgconfig_variables,
subdirs : pkgconfig_subdirs,
name : pkg_name,
description : 'libnice based implementaion for GstWebRTCICE',
)
libgstwebrtcnice_dep = declare_dependency(link_with: libgstwebrtcnice,
dependencies: [deps])
install_headers(libgstwebrtcnice_headers, subdir : 'gstreamer-1.0/gst/webrtc/nice')
meson.override_dependency(pkg_name, libgstwebrtcnice_dep)
endif

View file

@ -0,0 +1,67 @@
/* 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_NICE_H__
#define __GST_WEBRTC_NICE_H__
#include "gst/webrtc/ice.h"
#include "nicestream.h"
#include "nicetransport.h"
#include "nice_fwd.h"
G_BEGIN_DECLS
GST_WEBRTCNICE_API
GType gst_webrtc_nice_get_type(void);
#define GST_TYPE_WEBRTC_NICE (gst_webrtc_nice_get_type())
#define GST_WEBRTC_NICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_NICE,GstWebRTCNice))
#define GST_IS_WEBRTC_NICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_NICE))
#define GST_WEBRTC_NICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_NICE,GstWebRTCNiceClass))
#define GST_IS_WEBRTC_NICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_NICE))
#define GST_WEBRTC_NICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_NICE,GstWebRTCNiceClass))
/**
* GstWebRTCNice:
*/
typedef struct _GstWebRTCNice GstWebRTCNice;
typedef struct _GstWebRTCNiceClass GstWebRTCNiceClass;
typedef struct _GstWebRTCNicePrivate GstWebRTCNicePrivate;
struct _GstWebRTCNice
{
GstWebRTCICE parent;
GstWebRTCNicePrivate *priv;
};
struct _GstWebRTCNiceClass
{
GstWebRTCICEClass parent_class;
};
GST_WEBRTCNICE_API
GstWebRTCNice * gst_webrtc_nice_new (const gchar * name);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCNice, gst_object_unref)
G_END_DECLS
#endif /* __GST_WEBRTC_NICE_H__ */

View file

@ -0,0 +1,17 @@
#ifndef __GST_WEBRTCNICE_FWD_H__
#define __GST_WEBRTCNICE_FWD_H__
#ifndef GST_USE_UNSTABLE_API
#warning "The GstWebRTCNice 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
#ifndef GST_WEBRTCNICE_API
# ifdef BUILDING_GST_WEBRTCNICE
# define GST_WEBRTCNICE_API GST_API_EXPORT /* from config.h */
# else
# define GST_WEBRTCNICE_API GST_API_IMPORT
# endif
#endif
#endif /* __GST_WEBRTCNICE_FWD_H__ */

View file

@ -21,53 +21,42 @@
# include "config.h" # include "config.h"
#endif #endif
#include "icestream.h" #include "nicestream.h"
#include "nicetransport.h" #include "nicetransport.h"
#define GST_CAT_DEFAULT gst_webrtc_ice_stream_debug #define GST_CAT_DEFAULT gst_webrtc_nice_stream_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum
{
SIGNAL_0,
LAST_SIGNAL,
};
enum enum
{ {
PROP_0, PROP_0,
PROP_ICE, PROP_ICE,
PROP_STREAM_ID,
}; };
//static guint gst_webrtc_ice_stream_signals[LAST_SIGNAL] = { 0 }; struct _GstWebRTCNiceStreamPrivate
struct _GstWebRTCICEStreamPrivate
{ {
gboolean gathered; gboolean gathered;
GList *transports; GList *transports;
gboolean gathering_started; gboolean gathering_started;
gulong candidate_gathering_done_id; gulong candidate_gathering_done_id;
GWeakRef ice_weak;
}; };
#define gst_webrtc_ice_stream_parent_class parent_class #define gst_webrtc_nice_stream_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstWebRTCICEStream, gst_webrtc_ice_stream, G_DEFINE_TYPE_WITH_CODE (GstWebRTCNiceStream, gst_webrtc_nice_stream,
GST_TYPE_OBJECT, G_ADD_PRIVATE (GstWebRTCICEStream) GST_TYPE_WEBRTC_ICE_STREAM, G_ADD_PRIVATE (GstWebRTCNiceStream)
GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_stream_debug, GST_DEBUG_CATEGORY_INIT (gst_webrtc_nice_stream_debug,
"webrtcicestream", 0, "webrtcicestream");); "webrtcnicestream", 0, "webrtcnicestream"););
static void static void
gst_webrtc_ice_stream_set_property (GObject * object, guint prop_id, gst_webrtc_nice_stream_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec) const GValue * value, GParamSpec * pspec)
{ {
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object); GstWebRTCNiceStream *stream = GST_WEBRTC_NICE_STREAM (object);
switch (prop_id) { switch (prop_id) {
case PROP_ICE: case PROP_ICE:
g_weak_ref_set (&stream->ice_weak, g_value_get_object (value)); g_weak_ref_set (&stream->priv->ice_weak, g_value_get_object (value));
break;
case PROP_STREAM_ID:
stream->stream_id = g_value_get_uint (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -76,17 +65,14 @@ gst_webrtc_ice_stream_set_property (GObject * object, guint prop_id,
} }
static void static void
gst_webrtc_ice_stream_get_property (GObject * object, guint prop_id, gst_webrtc_nice_stream_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec) GValue * value, GParamSpec * pspec)
{ {
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object); GstWebRTCNiceStream *stream = GST_WEBRTC_NICE_STREAM (object);
switch (prop_id) { switch (prop_id) {
case PROP_ICE: case PROP_ICE:
g_value_take_object (value, g_weak_ref_get (&stream->ice_weak)); g_value_take_object (value, g_weak_ref_get (&stream->priv->ice_weak));
break;
case PROP_STREAM_ID:
g_value_set_uint (value, stream->stream_id);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -95,10 +81,10 @@ gst_webrtc_ice_stream_get_property (GObject * object, guint prop_id,
} }
static void static void
gst_webrtc_ice_stream_finalize (GObject * object) gst_webrtc_nice_stream_finalize (GObject * object)
{ {
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object); GstWebRTCNiceStream *stream = GST_WEBRTC_NICE_STREAM (object);
GstWebRTCICE *ice = g_weak_ref_get (&stream->ice_weak); GstWebRTCNice *ice = g_weak_ref_get (&stream->priv->ice_weak);
if (ice) { if (ice) {
NiceAgent *agent; NiceAgent *agent;
@ -116,7 +102,7 @@ gst_webrtc_ice_stream_finalize (GObject * object)
g_list_free (stream->priv->transports); g_list_free (stream->priv->transports);
stream->priv->transports = NULL; stream->priv->transports = NULL;
g_weak_ref_clear (&stream->ice_weak); g_weak_ref_clear (&stream->priv->ice_weak);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -125,13 +111,13 @@ static void
_on_candidate_gathering_done (NiceAgent * agent, guint stream_id, _on_candidate_gathering_done (NiceAgent * agent, guint stream_id,
GWeakRef * ice_weak) GWeakRef * ice_weak)
{ {
GstWebRTCICEStream *ice = g_weak_ref_get (ice_weak); GstWebRTCNiceStream *ice = g_weak_ref_get (ice_weak);
GList *l; GList *l;
if (!ice) if (!ice)
return; return;
if (stream_id != ice->stream_id) if (stream_id != GST_WEBRTC_ICE_STREAM (ice)->stream_id)
goto cleanup; goto cleanup;
GST_DEBUG_OBJECT (ice, "%u gathering done", stream_id); GST_DEBUG_OBJECT (ice, "%u gathering done", stream_id);
@ -149,17 +135,16 @@ cleanup:
gst_object_unref (ice); gst_object_unref (ice);
} }
GstWebRTCICETransport * static GstWebRTCICETransport *
gst_webrtc_ice_stream_find_transport (GstWebRTCICEStream * stream, gst_webrtc_nice_stream_find_transport (GstWebRTCICEStream * stream,
GstWebRTCICEComponent component) GstWebRTCICEComponent component)
{ {
GstWebRTCICEComponent trans_comp; GstWebRTCICEComponent trans_comp;
GstWebRTCICETransport *ret; GstWebRTCICETransport *ret;
GList *l; GList *l;
GstWebRTCNiceStream *nice_stream = GST_WEBRTC_NICE_STREAM (stream);
g_return_val_if_fail (GST_IS_WEBRTC_ICE_STREAM (stream), NULL); for (l = nice_stream->priv->transports; l; l = l->next) {
for (l = stream->priv->transports; l; l = l->next) {
GstWebRTCICETransport *trans = l->data; GstWebRTCICETransport *trans = l->data;
g_object_get (trans, "component", &trans_comp, NULL); g_object_get (trans, "component", &trans_comp, NULL);
@ -168,15 +153,16 @@ gst_webrtc_ice_stream_find_transport (GstWebRTCICEStream * stream,
} }
ret = ret =
GST_WEBRTC_ICE_TRANSPORT (gst_webrtc_nice_transport_new (stream, GST_WEBRTC_ICE_TRANSPORT (gst_webrtc_nice_transport_new (nice_stream,
component)); component));
stream->priv->transports = g_list_prepend (stream->priv->transports, ret); nice_stream->priv->transports =
g_list_prepend (nice_stream->priv->transports, ret);
return ret; return ret;
} }
static GWeakRef * static GWeakRef *
weak_new (GstWebRTCICEStream * stream) weak_new (GstWebRTCNiceStream * stream)
{ {
GWeakRef *weak = g_new0 (GWeakRef, 1); GWeakRef *weak = g_new0 (GWeakRef, 1);
g_weak_ref_init (weak, stream); g_weak_ref_init (weak, stream);
@ -191,11 +177,11 @@ weak_free (GWeakRef * weak)
} }
static void static void
gst_webrtc_ice_stream_constructed (GObject * object) gst_webrtc_nice_stream_constructed (GObject * object)
{ {
GstWebRTCICEStream *stream = GST_WEBRTC_ICE_STREAM (object); GstWebRTCNiceStream *stream = GST_WEBRTC_NICE_STREAM (object);
NiceAgent *agent; NiceAgent *agent;
GstWebRTCICE *ice = g_weak_ref_get (&stream->ice_weak); GstWebRTCNice *ice = g_weak_ref_get (&stream->priv->ice_weak);
g_assert (ice != NULL); g_assert (ice != NULL);
g_object_get (ice, "agent", &agent, NULL); g_object_get (ice, "agent", &agent, NULL);
@ -209,34 +195,33 @@ gst_webrtc_ice_stream_constructed (GObject * object)
G_OBJECT_CLASS (parent_class)->constructed (object); G_OBJECT_CLASS (parent_class)->constructed (object);
} }
gboolean static gboolean
gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * stream) gst_webrtc_nice_stream_gather_candidates (GstWebRTCICEStream * stream)
{ {
NiceAgent *agent; NiceAgent *agent;
GList *l; GList *l;
GstWebRTCICE *ice; GstWebRTCICE *ice;
gboolean ret = TRUE; gboolean ret = TRUE;
GstWebRTCNiceStream *nice_stream = GST_WEBRTC_NICE_STREAM (stream);
g_return_val_if_fail (GST_IS_WEBRTC_ICE_STREAM (stream), FALSE); GST_DEBUG_OBJECT (nice_stream, "start gathering candidates");
GST_DEBUG_OBJECT (stream, "start gathering candidates"); if (nice_stream->priv->gathered)
if (stream->priv->gathered)
return TRUE; return TRUE;
for (l = stream->priv->transports; l; l = l->next) { for (l = nice_stream->priv->transports; l; l = l->next) {
GstWebRTCICETransport *trans = l->data; GstWebRTCICETransport *trans = l->data;
gst_webrtc_ice_transport_gathering_state_change (trans, gst_webrtc_ice_transport_gathering_state_change (trans,
GST_WEBRTC_ICE_GATHERING_STATE_GATHERING); GST_WEBRTC_ICE_GATHERING_STATE_GATHERING);
} }
ice = g_weak_ref_get (&stream->ice_weak); ice = GST_WEBRTC_ICE (g_weak_ref_get (&nice_stream->priv->ice_weak));
g_assert (ice != NULL); g_assert (ice != NULL);
g_object_get (ice, "agent", &agent, NULL); g_object_get (ice, "agent", &agent, NULL);
if (!stream->priv->gathering_started) { if (!nice_stream->priv->gathering_started) {
if (ice->min_rtp_port != 0 || ice->max_rtp_port != 65535) { if (ice->min_rtp_port != 0 || ice->max_rtp_port != 65535) {
if (ice->min_rtp_port > ice->max_rtp_port) { if (ice->min_rtp_port > ice->max_rtp_port) {
GST_ERROR_OBJECT (ice, GST_ERROR_OBJECT (ice,
@ -250,7 +235,7 @@ gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * stream)
NICE_COMPONENT_TYPE_RTP, ice->min_rtp_port, ice->max_rtp_port); NICE_COMPONENT_TYPE_RTP, ice->min_rtp_port, ice->max_rtp_port);
} }
/* mark as gathering started to prevent changing ports again */ /* mark as gathering started to prevent changing ports again */
stream->priv->gathering_started = TRUE; nice_stream->priv->gathering_started = TRUE;
} }
if (!nice_agent_gather_candidates (agent, stream->stream_id)) { if (!nice_agent_gather_candidates (agent, stream->stream_id)) {
@ -258,7 +243,7 @@ gst_webrtc_ice_stream_gather_candidates (GstWebRTCICEStream * stream)
goto cleanup; goto cleanup;
} }
for (l = stream->priv->transports; l; l = l->next) { for (l = nice_stream->priv->transports; l; l = l->next) {
GstWebRTCNiceTransport *trans = l->data; GstWebRTCNiceTransport *trans = l->data;
gst_webrtc_nice_transport_update_buffer_size (trans); gst_webrtc_nice_transport_update_buffer_size (trans);
@ -274,14 +259,21 @@ cleanup:
} }
static void static void
gst_webrtc_ice_stream_class_init (GstWebRTCICEStreamClass * klass) gst_webrtc_nice_stream_class_init (GstWebRTCNiceStreamClass * klass)
{ {
GObjectClass *gobject_class = (GObjectClass *) klass; GObjectClass *gobject_class = (GObjectClass *) klass;
GstWebRTCICEStreamClass *gst_webrtc_ice_stream_class =
GST_WEBRTC_ICE_STREAM_CLASS (klass);
gobject_class->constructed = gst_webrtc_ice_stream_constructed; gst_webrtc_ice_stream_class->find_transport =
gobject_class->get_property = gst_webrtc_ice_stream_get_property; gst_webrtc_nice_stream_find_transport;
gobject_class->set_property = gst_webrtc_ice_stream_set_property; gst_webrtc_ice_stream_class->gather_candidates =
gobject_class->finalize = gst_webrtc_ice_stream_finalize; gst_webrtc_nice_stream_gather_candidates;
gobject_class->constructed = gst_webrtc_nice_stream_constructed;
gobject_class->get_property = gst_webrtc_nice_stream_get_property;
gobject_class->set_property = gst_webrtc_nice_stream_set_property;
gobject_class->finalize = gst_webrtc_nice_stream_finalize;
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_ICE, PROP_ICE,
@ -289,26 +281,19 @@ gst_webrtc_ice_stream_class_init (GstWebRTCICEStreamClass * klass)
"ICE", "ICE agent associated with this stream", "ICE", "ICE agent associated with this stream",
GST_TYPE_WEBRTC_ICE, GST_TYPE_WEBRTC_ICE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_STREAM_ID,
g_param_spec_uint ("stream-id",
"ICE stream id", "ICE stream id associated with this stream",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
} }
static void static void
gst_webrtc_ice_stream_init (GstWebRTCICEStream * stream) gst_webrtc_nice_stream_init (GstWebRTCNiceStream * stream)
{ {
stream->priv = gst_webrtc_ice_stream_get_instance_private (stream); stream->priv = gst_webrtc_nice_stream_get_instance_private (stream);
g_weak_ref_init (&stream->ice_weak, NULL); g_weak_ref_init (&stream->priv->ice_weak, NULL);
} }
GstWebRTCICEStream * GstWebRTCNiceStream *
gst_webrtc_ice_stream_new (GstWebRTCICE * ice, guint stream_id) gst_webrtc_nice_stream_new (GstWebRTCICE * ice, guint stream_id)
{ {
return g_object_new (GST_TYPE_WEBRTC_ICE_STREAM, "ice", ice, return g_object_new (GST_TYPE_WEBRTC_NICE_STREAM, "ice", ice,
"stream-id", stream_id, NULL); "stream-id", stream_id, NULL);
} }

View file

@ -0,0 +1,63 @@
/* 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_NICE_STREAM_H__
#define __GST_WEBRTC_NICE_STREAM_H__
#include "gst/webrtc/icestream.h"
#include "nice_fwd.h"
G_BEGIN_DECLS
GST_WEBRTCNICE_API
GType gst_webrtc_nice_stream_get_type(void);
#define GST_TYPE_WEBRTC_NICE_STREAM (gst_webrtc_nice_stream_get_type())
#define GST_WEBRTC_NICE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_NICE_STREAM,GstWebRTCNiceStream))
#define GST_IS_WEBRTC_NICE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_NICE_STREAM))
#define GST_WEBRTC_NICE_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_NICE_STREAM,GstWebRTCNiceStreamClass))
#define GST_IS_WEBRTC_NICE_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_NICE_STREAM))
#define GST_WEBRTC_NICE_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_NICE_STREAM,GstWebRTCNiceStreamClass))
/**
* GstWebRTCNiceStream:
*/
typedef struct _GstWebRTCNiceStream GstWebRTCNiceStream;
typedef struct _GstWebRTCNiceStreamClass GstWebRTCNiceStreamClass;
typedef struct _GstWebRTCNiceStreamPrivate GstWebRTCNiceStreamPrivate;
struct _GstWebRTCNiceStream
{
GstWebRTCICEStream parent;
GstWebRTCNiceStreamPrivate *priv;
};
struct _GstWebRTCNiceStreamClass
{
GstWebRTCICEStreamClass parent_class;
};
GstWebRTCNiceStream * gst_webrtc_nice_stream_new (GstWebRTCICE * ice,
guint stream_id);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCNiceStream, gst_object_unref)
G_END_DECLS
#endif /* __GST_WEBRTC_NICE_STREAM_H__ */

View file

@ -21,10 +21,8 @@
# include "config.h" # include "config.h"
#endif #endif
#include "nicestream.h"
#include "nicetransport.h" #include "nicetransport.h"
#include "icestream.h"
#include <gio/gnetworking.h>
#define GST_CAT_DEFAULT gst_webrtc_nice_transport_debug #define GST_CAT_DEFAULT gst_webrtc_nice_transport_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@ -165,7 +163,11 @@ gst_webrtc_nice_transport_finalize (GObject * object)
{ {
GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object); GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object);
NiceAgent *agent; NiceAgent *agent;
GstWebRTCICE *webrtc_ice = g_weak_ref_get (&nice->stream->ice_weak); GstWebRTCNice *webrtc_ice;
GWeakRef ice_weak;
g_object_get (GST_WEBRTC_NICE_STREAM (nice->stream), "ice", &ice_weak, NULL);
webrtc_ice = g_weak_ref_get (&ice_weak);
if (webrtc_ice) { if (webrtc_ice) {
g_object_get (webrtc_ice, "agent", &agent, NULL); g_object_get (webrtc_ice, "agent", &agent, NULL);
@ -194,14 +196,20 @@ gst_webrtc_nice_transport_update_buffer_size (GstWebRTCNiceTransport * nice)
NiceAgent *agent = NULL; NiceAgent *agent = NULL;
GPtrArray *sockets; GPtrArray *sockets;
guint i; guint i;
GstWebRTCICE *webrtc_ice = g_weak_ref_get (&nice->stream->ice_weak); GstWebRTCNice *webrtc_ice;
GWeakRef ice_weak;
g_object_get (GST_WEBRTC_NICE_STREAM (nice->stream), "ice", &ice_weak, NULL);
webrtc_ice = g_weak_ref_get (&ice_weak);
g_assert (webrtc_ice != NULL); g_assert (webrtc_ice != NULL);
g_object_get (webrtc_ice, "agent", &agent, NULL); g_object_get (webrtc_ice, "agent", &agent, NULL);
g_assert (agent != NULL); g_assert (agent != NULL);
sockets = nice_agent_get_sockets (agent, nice->stream->stream_id, 1); sockets =
nice_agent_get_sockets (agent,
GST_WEBRTC_ICE_STREAM (nice->stream)->stream_id, 1);
if (sockets == NULL) { if (sockets == NULL) {
g_object_unref (agent); g_object_unref (agent);
gst_object_unref (webrtc_ice); gst_object_unref (webrtc_ice);
@ -320,7 +328,11 @@ gst_webrtc_nice_transport_constructed (GObject * object)
gboolean controlling_mode; gboolean controlling_mode;
guint our_stream_id; guint our_stream_id;
NiceAgent *agent; NiceAgent *agent;
GstWebRTCICE *webrtc_ice = g_weak_ref_get (&nice->stream->ice_weak); GstWebRTCNice *webrtc_ice;
GWeakRef ice_weak;
g_object_get (GST_WEBRTC_NICE_STREAM (nice->stream), "ice", &ice_weak, NULL);
webrtc_ice = g_weak_ref_get (&ice_weak);
g_assert (webrtc_ice != NULL); g_assert (webrtc_ice != NULL);
g_object_get (nice->stream, "stream-id", &our_stream_id, NULL); g_object_get (nice->stream, "stream-id", &our_stream_id, NULL);
@ -370,7 +382,7 @@ gst_webrtc_nice_transport_class_init (GstWebRTCNiceTransportClass * klass)
PROP_STREAM, PROP_STREAM,
g_param_spec_object ("stream", g_param_spec_object ("stream",
"WebRTC ICE Stream", "ICE stream associated with this transport", "WebRTC ICE Stream", "ICE stream associated with this transport",
GST_TYPE_WEBRTC_ICE_STREAM, GST_TYPE_WEBRTC_NICE_STREAM,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
/** /**
@ -409,7 +421,7 @@ gst_webrtc_nice_transport_init (GstWebRTCNiceTransport * nice)
} }
GstWebRTCNiceTransport * GstWebRTCNiceTransport *
gst_webrtc_nice_transport_new (GstWebRTCICEStream * stream, gst_webrtc_nice_transport_new (GstWebRTCNiceStream * stream,
GstWebRTCICEComponent component) GstWebRTCICEComponent component)
{ {
return g_object_new (GST_TYPE_WEBRTC_NICE_TRANSPORT, "stream", stream, return g_object_new (GST_TYPE_WEBRTC_NICE_TRANSPORT, "stream", stream,

View file

@ -20,16 +20,16 @@
#ifndef __GST_WEBRTC_NICE_TRANSPORT_H__ #ifndef __GST_WEBRTC_NICE_TRANSPORT_H__
#define __GST_WEBRTC_NICE_TRANSPORT_H__ #define __GST_WEBRTC_NICE_TRANSPORT_H__
#include <gst/gst.h> #include "nice.h"
#include "gst/webrtc/icetransport.h"
/* libnice */ /* libnice */
#include <agent.h> #include <agent.h>
#include <gst/webrtc/webrtc.h>
#include "gstwebrtcice.h"
#include "gst/webrtc/webrtc-priv.h" #include "nice_fwd.h"
G_BEGIN_DECLS G_BEGIN_DECLS
GST_WEBRTCNICE_API
GType gst_webrtc_nice_transport_get_type(void); GType gst_webrtc_nice_transport_get_type(void);
#define GST_TYPE_WEBRTC_NICE_TRANSPORT (gst_webrtc_nice_transport_get_type()) #define GST_TYPE_WEBRTC_NICE_TRANSPORT (gst_webrtc_nice_transport_get_type())
#define GST_WEBRTC_NICE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_NICE_TRANSPORT,GstWebRTCNiceTransport)) #define GST_WEBRTC_NICE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_NICE_TRANSPORT,GstWebRTCNiceTransport))
@ -38,11 +38,18 @@ GType gst_webrtc_nice_transport_get_type(void);
#define GST_IS_WEBRTC_NICE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_NICE_TRANSPORT)) #define GST_IS_WEBRTC_NICE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_NICE_TRANSPORT))
#define GST_WEBRTC_NICE_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_NICE_TRANSPORT,GstWebRTCNiceTransportClass)) #define GST_WEBRTC_NICE_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_NICE_TRANSPORT,GstWebRTCNiceTransportClass))
/**
* GstWebRTCNiceTransport:
*/
typedef struct _GstWebRTCNiceTransport GstWebRTCNiceTransport;
typedef struct _GstWebRTCNiceTransportClass GstWebRTCNiceTransportClass;
typedef struct _GstWebRTCNiceTransportPrivate GstWebRTCNiceTransportPrivate;
struct _GstWebRTCNiceTransport struct _GstWebRTCNiceTransport
{ {
GstWebRTCICETransport parent; GstWebRTCICETransport parent;
GstWebRTCICEStream *stream; GstWebRTCNiceStream *stream;
GstWebRTCNiceTransportPrivate *priv; GstWebRTCNiceTransportPrivate *priv;
}; };
@ -52,11 +59,12 @@ struct _GstWebRTCNiceTransportClass
GstWebRTCICETransportClass parent_class; GstWebRTCICETransportClass parent_class;
}; };
GstWebRTCNiceTransport * gst_webrtc_nice_transport_new (GstWebRTCICEStream * stream, GstWebRTCNiceTransport * gst_webrtc_nice_transport_new (GstWebRTCNiceStream * stream,
GstWebRTCICEComponent component); GstWebRTCICEComponent component);
void gst_webrtc_nice_transport_update_buffer_size (GstWebRTCNiceTransport * nice); void gst_webrtc_nice_transport_update_buffer_size (GstWebRTCNiceTransport * nice);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCNiceTransport, gst_object_unref)
G_END_DECLS G_END_DECLS

View file

@ -152,47 +152,6 @@ struct _GstWebRTCRTPReceiverClass
GST_WEBRTC_API GST_WEBRTC_API
GstWebRTCRTPReceiver * gst_webrtc_rtp_receiver_new (void); GstWebRTCRTPReceiver * gst_webrtc_rtp_receiver_new (void);
/**
* GstWebRTCICETransport:
*/
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
{
GstObjectClass parent_class;
gboolean (*gather_candidates) (GstWebRTCICETransport * transport);
gpointer _padding[GST_PADDING];
};
GST_WEBRTC_API
void gst_webrtc_ice_transport_connection_state_change (GstWebRTCICETransport * ice,
GstWebRTCICEConnectionState new_state);
GST_WEBRTC_API
void gst_webrtc_ice_transport_gathering_state_change (GstWebRTCICETransport * ice,
GstWebRTCICEGatheringState new_state);
GST_WEBRTC_API
void gst_webrtc_ice_transport_selected_pair_change (GstWebRTCICETransport * ice);
GST_WEBRTC_API
void gst_webrtc_ice_transport_new_candidate (GstWebRTCICETransport * ice, guint stream_id, GstWebRTCICEComponent component, gchar * attr);
/** /**
* GstWebRTCDTLSTransport: * GstWebRTCDTLSTransport:
*/ */

View file

@ -24,6 +24,8 @@
#include <gst/webrtc/webrtc_fwd.h> #include <gst/webrtc/webrtc_fwd.h>
#include <gst/webrtc/webrtc-enumtypes.h> #include <gst/webrtc/webrtc-enumtypes.h>
#include <gst/webrtc/dtlstransport.h> #include <gst/webrtc/dtlstransport.h>
#include <gst/webrtc/ice.h>
#include <gst/webrtc/icestream.h>
#include <gst/webrtc/icetransport.h> #include <gst/webrtc/icetransport.h>
#include <gst/webrtc/rtcsessiondescription.h> #include <gst/webrtc/rtcsessiondescription.h>
#include <gst/webrtc/rtpreceiver.h> #include <gst/webrtc/rtpreceiver.h>

View file

@ -48,6 +48,19 @@
typedef struct _GstWebRTCDTLSTransport GstWebRTCDTLSTransport; typedef struct _GstWebRTCDTLSTransport GstWebRTCDTLSTransport;
typedef struct _GstWebRTCDTLSTransportClass GstWebRTCDTLSTransportClass; typedef struct _GstWebRTCDTLSTransportClass GstWebRTCDTLSTransportClass;
/**
* GstWebRTCICE:
*/
typedef struct _GstWebRTCICE GstWebRTCICE;
typedef struct _GstWebRTCICEClass GstWebRTCICEClass;
typedef struct _GstWebRTCICECandidateStats GstWebRTCICECandidateStats;
/**
* GstWebRTCICEStream:
*/
typedef struct _GstWebRTCICEStream GstWebRTCICEStream;
typedef struct _GstWebRTCICEStreamClass GstWebRTCICEStreamClass;
/** /**
* GstWebRTCICETransport: * GstWebRTCICETransport:
*/ */