2 * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
24 #include "nicetransport.h"
25 #include "icestream.h"
27 #define GST_CAT_DEFAULT gst_webrtc_nice_transport_debug
28 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
30 #define gst_webrtc_nice_transport_parent_class parent_class
31 G_DEFINE_TYPE_WITH_CODE (GstWebRTCNiceTransport, gst_webrtc_nice_transport,
32 GST_TYPE_WEBRTC_ICE_TRANSPORT,
33 GST_DEBUG_CATEGORY_INIT (gst_webrtc_nice_transport_debug,
34 "webrtcnicetransport", 0, "webrtcnicetransport");
49 //static guint gst_webrtc_nice_transport_signals[LAST_SIGNAL] = { 0 };
51 struct _GstWebRTCNiceTransportPrivate
56 static NiceComponentType
57 _gst_component_to_nice (GstWebRTCICEComponent component)
60 case GST_WEBRTC_ICE_COMPONENT_RTP:
61 return NICE_COMPONENT_TYPE_RTP;
62 case GST_WEBRTC_ICE_COMPONENT_RTCP:
63 return NICE_COMPONENT_TYPE_RTCP;
65 g_assert_not_reached ();
70 static GstWebRTCICEComponent
71 _nice_component_to_gst (NiceComponentType component)
74 case NICE_COMPONENT_TYPE_RTP:
75 return GST_WEBRTC_ICE_COMPONENT_RTP;
76 case NICE_COMPONENT_TYPE_RTCP:
77 return GST_WEBRTC_ICE_COMPONENT_RTCP;
79 g_assert_not_reached ();
84 static GstWebRTCICEConnectionState
85 _nice_component_state_to_gst (NiceComponentState state)
88 case NICE_COMPONENT_STATE_DISCONNECTED:
89 return GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED;
90 case NICE_COMPONENT_STATE_GATHERING:
91 return GST_WEBRTC_ICE_CONNECTION_STATE_NEW;
92 case NICE_COMPONENT_STATE_CONNECTING:
93 return GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING;
94 case NICE_COMPONENT_STATE_CONNECTED:
95 return GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED;
96 case NICE_COMPONENT_STATE_READY:
97 return GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED;
98 case NICE_COMPONENT_STATE_FAILED:
99 return GST_WEBRTC_ICE_CONNECTION_STATE_FAILED;
101 g_assert_not_reached ();
107 gst_webrtc_nice_transport_set_property (GObject * object, guint prop_id,
108 const GValue * value, GParamSpec * pspec)
110 GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object);
115 gst_object_unref (nice->stream);
116 nice->stream = g_value_dup_object (value);
119 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
125 gst_webrtc_nice_transport_get_property (GObject * object, guint prop_id,
126 GValue * value, GParamSpec * pspec)
128 GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object);
132 g_value_set_object (value, nice->stream);
135 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
141 gst_webrtc_nice_transport_finalize (GObject * object)
143 GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object);
145 gst_object_unref (nice->stream);
147 G_OBJECT_CLASS (parent_class)->finalize (object);
151 _on_new_selected_pair (NiceAgent * agent, guint stream_id,
152 NiceComponentType component, NiceCandidate * lcandidate,
153 NiceCandidate * rcandidate, GstWebRTCNiceTransport * nice)
155 GstWebRTCICETransport *ice = GST_WEBRTC_ICE_TRANSPORT (nice);
156 GstWebRTCICEComponent comp = _nice_component_to_gst (component);
159 g_object_get (nice->stream, "stream-id", &our_stream_id, NULL);
161 if (stream_id != our_stream_id)
163 if (comp != ice->component)
166 gst_webrtc_ice_transport_selected_pair_change (ice);
170 _on_component_state_changed (NiceAgent * agent, guint stream_id,
171 NiceComponentType component, NiceComponentState state,
172 GstWebRTCNiceTransport * nice)
174 GstWebRTCICETransport *ice = GST_WEBRTC_ICE_TRANSPORT (nice);
175 GstWebRTCICEComponent comp = _nice_component_to_gst (component);
178 g_object_get (nice->stream, "stream-id", &our_stream_id, NULL);
180 if (stream_id != our_stream_id)
182 if (comp != ice->component)
185 GST_DEBUG_OBJECT (ice, "%u %u %s", stream_id, component,
186 nice_component_state_to_string (state));
188 gst_webrtc_ice_transport_connection_state_change (ice,
189 _nice_component_state_to_gst (state));
193 gst_webrtc_nice_transport_constructed (GObject * object)
195 GstWebRTCNiceTransport *nice = GST_WEBRTC_NICE_TRANSPORT (object);
196 GstWebRTCICETransport *ice = GST_WEBRTC_ICE_TRANSPORT (object);
197 NiceComponentType component = _gst_component_to_nice (ice->component);
198 gboolean controlling_mode;
202 g_object_get (nice->stream, "stream-id", &our_stream_id, NULL);
203 g_object_get (nice->stream->ice, "agent", &agent, NULL);
205 g_object_get (agent, "controlling-mode", &controlling_mode, NULL);
207 controlling_mode ? GST_WEBRTC_ICE_ROLE_CONTROLLING :
208 GST_WEBRTC_ICE_ROLE_CONTROLLED;
210 g_signal_connect (agent, "component-state-changed",
211 G_CALLBACK (_on_component_state_changed), nice);
212 g_signal_connect (agent, "new-selected-pair-full",
213 G_CALLBACK (_on_new_selected_pair), nice);
215 ice->src = gst_element_factory_make ("nicesrc", NULL);
217 g_object_set (ice->src, "agent", agent, "stream", our_stream_id,
218 "component", component, NULL);
220 ice->sink = gst_element_factory_make ("nicesink", NULL);
222 g_object_set (ice->sink, "agent", agent, "stream", our_stream_id,
223 "component", component, "async", FALSE, "enable-last-sample", FALSE,
225 if (ice->component == GST_WEBRTC_ICE_COMPONENT_RTCP)
226 g_object_set (ice->sink, "sync", FALSE, NULL);
229 g_object_unref (agent);
231 G_OBJECT_CLASS (parent_class)->constructed (object);
235 gst_webrtc_nice_transport_class_init (GstWebRTCNiceTransportClass * klass)
237 GObjectClass *gobject_class = (GObjectClass *) klass;
239 g_type_class_add_private (klass, sizeof (GstWebRTCNiceTransportPrivate));
241 gobject_class->constructed = gst_webrtc_nice_transport_constructed;
242 gobject_class->get_property = gst_webrtc_nice_transport_get_property;
243 gobject_class->set_property = gst_webrtc_nice_transport_set_property;
244 gobject_class->finalize = gst_webrtc_nice_transport_finalize;
246 g_object_class_install_property (gobject_class,
248 g_param_spec_object ("stream",
249 "WebRTC ICE Stream", "ICE stream associated with this transport",
250 GST_TYPE_WEBRTC_ICE_STREAM,
251 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
255 gst_webrtc_nice_transport_init (GstWebRTCNiceTransport * nice)
258 G_TYPE_INSTANCE_GET_PRIVATE ((nice), GST_TYPE_WEBRTC_NICE_TRANSPORT,
259 GstWebRTCNiceTransportPrivate);
262 GstWebRTCNiceTransport *
263 gst_webrtc_nice_transport_new (GstWebRTCICEStream * stream,
264 GstWebRTCICEComponent component)
266 return g_object_new (GST_TYPE_WEBRTC_NICE_TRANSPORT, "stream", stream,
267 "component", component, NULL);