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 "transportstream.h"
25 #include "transportsendbin.h"
26 #include "transportreceivebin.h"
27 #include "gstwebrtcice.h"
28 #include "gstwebrtcbin.h"
31 #define transport_stream_parent_class parent_class
32 G_DEFINE_TYPE (TransportStream, transport_stream, GST_TYPE_OBJECT);
44 transport_stream_set_property (GObject * object, guint prop_id,
45 const GValue * value, GParamSpec * pspec)
47 TransportStream *stream = TRANSPORT_STREAM (object);
51 gst_object_set_parent (GST_OBJECT (stream), g_value_get_object (value));
55 GST_OBJECT_LOCK (stream);
60 stream->session_id = g_value_get_uint (value);
63 stream->rtcp_mux = g_value_get_boolean (value);
65 case PROP_DTLS_CLIENT:
66 stream->dtls_client = g_value_get_boolean (value);
69 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
72 GST_OBJECT_UNLOCK (stream);
76 transport_stream_get_property (GObject * object, guint prop_id,
77 GValue * value, GParamSpec * pspec)
79 TransportStream *stream = TRANSPORT_STREAM (object);
81 GST_OBJECT_LOCK (stream);
84 g_value_set_uint (value, stream->session_id);
87 g_value_set_boolean (value, stream->rtcp_mux);
89 case PROP_DTLS_CLIENT:
90 g_value_set_boolean (value, stream->dtls_client);
93 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
96 GST_OBJECT_UNLOCK (stream);
100 transport_stream_dispose (GObject * object)
102 TransportStream *stream = TRANSPORT_STREAM (object);
104 if (stream->send_bin)
105 gst_object_unref (stream->send_bin);
106 stream->send_bin = NULL;
108 if (stream->receive_bin)
109 gst_object_unref (stream->receive_bin);
110 stream->receive_bin = NULL;
112 if (stream->transport)
113 gst_object_unref (stream->transport);
114 stream->transport = NULL;
116 if (stream->rtcp_transport)
117 gst_object_unref (stream->rtcp_transport);
118 stream->rtcp_transport = NULL;
120 GST_OBJECT_PARENT (object) = NULL;
122 G_OBJECT_CLASS (parent_class)->dispose (object);
126 transport_stream_finalize (GObject * object)
128 TransportStream *stream = TRANSPORT_STREAM (object);
130 g_array_free (stream->ptmap, TRUE);
132 G_OBJECT_CLASS (parent_class)->finalize (object);
136 transport_stream_constructed (GObject * object)
138 TransportStream *stream = TRANSPORT_STREAM (object);
139 GstWebRTCBin *webrtc;
140 GstWebRTCICETransport *ice_trans;
142 stream->transport = gst_webrtc_dtls_transport_new (stream->session_id, FALSE);
143 stream->rtcp_transport =
144 gst_webrtc_dtls_transport_new (stream->session_id, TRUE);
146 webrtc = GST_WEBRTC_BIN (gst_object_get_parent (GST_OBJECT (object)));
148 g_object_bind_property (stream->transport, "client", stream, "dtls-client",
149 G_BINDING_BIDIRECTIONAL);
150 g_object_bind_property (stream->rtcp_transport, "client", stream,
151 "dtls-client", G_BINDING_BIDIRECTIONAL);
153 g_object_bind_property (stream->transport, "certificate",
154 stream->rtcp_transport, "certificate", G_BINDING_BIDIRECTIONAL);
156 /* Need to go full Java and have a transport manager?
157 * Or make the caller set the ICE transport up? */
159 stream->stream = _find_ice_stream_for_session (webrtc, stream->session_id);
160 if (stream->stream == NULL) {
161 stream->stream = gst_webrtc_ice_add_stream (webrtc->priv->ice,
163 _add_ice_stream_item (webrtc, stream->session_id, stream->stream);
166 gst_webrtc_ice_find_transport (webrtc->priv->ice, stream->stream,
167 GST_WEBRTC_ICE_COMPONENT_RTP);
168 gst_webrtc_dtls_transport_set_transport (stream->transport, ice_trans);
169 gst_object_unref (ice_trans);
172 gst_webrtc_ice_find_transport (webrtc->priv->ice, stream->stream,
173 GST_WEBRTC_ICE_COMPONENT_RTCP);
174 gst_webrtc_dtls_transport_set_transport (stream->rtcp_transport, ice_trans);
175 gst_object_unref (ice_trans);
177 stream->send_bin = g_object_new (transport_send_bin_get_type (), "stream",
179 gst_object_ref_sink (stream->send_bin);
180 stream->receive_bin = g_object_new (transport_receive_bin_get_type (),
181 "stream", stream, NULL);
182 gst_object_ref_sink (stream->receive_bin);
184 gst_object_unref (webrtc);
186 G_OBJECT_CLASS (parent_class)->constructed (object);
190 transport_stream_class_init (TransportStreamClass * klass)
192 GObjectClass *gobject_class = (GObjectClass *) klass;
194 gobject_class->constructed = transport_stream_constructed;
195 gobject_class->get_property = transport_stream_get_property;
196 gobject_class->set_property = transport_stream_set_property;
197 gobject_class->dispose = transport_stream_dispose;
198 gobject_class->finalize = transport_stream_finalize;
200 /* some acrobatics are required to set the parent before _constructed()
202 g_object_class_install_property (gobject_class,
204 g_param_spec_object ("webrtc", "Parent webrtcbin",
207 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
209 g_object_class_install_property (gobject_class,
211 g_param_spec_uint ("session-id", "Session ID",
212 "Session ID used for this transport",
214 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
216 g_object_class_install_property (gobject_class,
218 g_param_spec_boolean ("rtcp-mux", "RTCP Mux",
219 "Whether RTCP packets are muxed with RTP packets",
220 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222 g_object_class_install_property (gobject_class,
224 g_param_spec_boolean ("dtls-client", "DTLS client",
225 "Whether we take the client role in DTLS negotiation",
226 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
230 clear_ptmap_item (PtMapItem * item)
233 gst_caps_unref (item->caps);
237 transport_stream_init (TransportStream * stream)
239 stream->ptmap = g_array_new (FALSE, TRUE, sizeof (PtMapItem));
240 g_array_set_clear_func (stream->ptmap, (GDestroyNotify) clear_ptmap_item);
244 transport_stream_new (GstWebRTCBin * webrtc, guint session_id)
246 TransportStream *stream;
248 stream = g_object_new (transport_stream_get_type (), "webrtc", webrtc,
249 "session-id", session_id, NULL);