1 /* GStreamer
2 * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
3 *
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.
8 *
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.
13 *
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.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include "gstwebrtcbin.h"
25 #include "utils.h"
26 #include "webrtctransceiver.h"
27
28 #define webrtc_transceiver_parent_class parent_class
29 G_DEFINE_TYPE (WebRTCTransceiver, webrtc_transceiver,
30 GST_TYPE_WEBRTC_RTP_TRANSCEIVER);
31
32 #define DEFAULT_FEC_TYPE GST_WEBRTC_FEC_TYPE_NONE
33 #define DEFAULT_DO_NACK FALSE
34 #define DEFAULT_FEC_PERCENTAGE 100
35
36 enum
37 {
38 PROP_0,
39 PROP_WEBRTC,
40 PROP_FEC_TYPE,
41 PROP_FEC_PERCENTAGE,
42 PROP_DO_NACK,
43 };
44
45 void
webrtc_transceiver_set_transport(WebRTCTransceiver * trans,TransportStream * stream)46 webrtc_transceiver_set_transport (WebRTCTransceiver * trans,
47 TransportStream * stream)
48 {
49 GstWebRTCRTPTransceiver *rtp_trans;
50
51 g_return_if_fail (WEBRTC_IS_TRANSCEIVER (trans));
52
53 rtp_trans = GST_WEBRTC_RTP_TRANSCEIVER (trans);
54
55 gst_object_replace ((GstObject **) & trans->stream, (GstObject *) stream);
56
57 if (rtp_trans->sender)
58 gst_object_replace ((GstObject **) & rtp_trans->sender->transport,
59 (GstObject *) stream->transport);
60 if (rtp_trans->receiver)
61 gst_object_replace ((GstObject **) & rtp_trans->receiver->transport,
62 (GstObject *) stream->transport);
63
64 if (rtp_trans->sender)
65 gst_object_replace ((GstObject **) & rtp_trans->sender->rtcp_transport,
66 (GstObject *) stream->rtcp_transport);
67 if (rtp_trans->receiver)
68 gst_object_replace ((GstObject **) & rtp_trans->receiver->rtcp_transport,
69 (GstObject *) stream->rtcp_transport);
70 }
71
72 GstWebRTCDTLSTransport *
webrtc_transceiver_get_dtls_transport(GstWebRTCRTPTransceiver * trans)73 webrtc_transceiver_get_dtls_transport (GstWebRTCRTPTransceiver * trans)
74 {
75 g_return_val_if_fail (WEBRTC_IS_TRANSCEIVER (trans), NULL);
76
77 if (trans->sender) {
78 return trans->sender->transport;
79 } else if (trans->receiver) {
80 return trans->receiver->transport;
81 }
82
83 return NULL;
84 }
85
86 GstWebRTCDTLSTransport *
webrtc_transceiver_get_rtcp_dtls_transport(GstWebRTCRTPTransceiver * trans)87 webrtc_transceiver_get_rtcp_dtls_transport (GstWebRTCRTPTransceiver * trans)
88 {
89 g_return_val_if_fail (WEBRTC_IS_TRANSCEIVER (trans), NULL);
90
91 if (trans->sender) {
92 return trans->sender->rtcp_transport;
93 } else if (trans->receiver) {
94 return trans->receiver->rtcp_transport;
95 }
96
97 return NULL;
98 }
99
100 static void
webrtc_transceiver_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)101 webrtc_transceiver_set_property (GObject * object, guint prop_id,
102 const GValue * value, GParamSpec * pspec)
103 {
104 WebRTCTransceiver *trans = WEBRTC_TRANSCEIVER (object);
105
106 switch (prop_id) {
107 case PROP_WEBRTC:
108 gst_object_set_parent (GST_OBJECT (trans), g_value_get_object (value));
109 break;
110 }
111
112 GST_OBJECT_LOCK (trans);
113 switch (prop_id) {
114 case PROP_WEBRTC:
115 break;
116 case PROP_FEC_TYPE:
117 trans->fec_type = g_value_get_enum (value);
118 break;
119 case PROP_DO_NACK:
120 trans->do_nack = g_value_get_boolean (value);
121 break;
122 case PROP_FEC_PERCENTAGE:
123 trans->fec_percentage = g_value_get_uint (value);
124 break;
125 default:
126 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
127 break;
128 }
129 GST_OBJECT_UNLOCK (trans);
130 }
131
132 static void
webrtc_transceiver_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)133 webrtc_transceiver_get_property (GObject * object, guint prop_id,
134 GValue * value, GParamSpec * pspec)
135 {
136 WebRTCTransceiver *trans = WEBRTC_TRANSCEIVER (object);
137
138 GST_OBJECT_LOCK (trans);
139 switch (prop_id) {
140 case PROP_FEC_TYPE:
141 g_value_set_enum (value, trans->fec_type);
142 break;
143 case PROP_DO_NACK:
144 g_value_set_boolean (value, trans->do_nack);
145 break;
146 case PROP_FEC_PERCENTAGE:
147 g_value_set_uint (value, trans->fec_percentage);
148 break;
149 default:
150 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
151 break;
152 }
153 GST_OBJECT_UNLOCK (trans);
154 }
155
156 static void
webrtc_transceiver_finalize(GObject * object)157 webrtc_transceiver_finalize (GObject * object)
158 {
159 WebRTCTransceiver *trans = WEBRTC_TRANSCEIVER (object);
160
161 if (trans->stream)
162 gst_object_unref (trans->stream);
163 trans->stream = NULL;
164
165 if (trans->local_rtx_ssrc_map)
166 gst_structure_free (trans->local_rtx_ssrc_map);
167 trans->local_rtx_ssrc_map = NULL;
168
169 G_OBJECT_CLASS (parent_class)->finalize (object);
170 }
171
172 static void
webrtc_transceiver_class_init(WebRTCTransceiverClass * klass)173 webrtc_transceiver_class_init (WebRTCTransceiverClass * klass)
174 {
175 GObjectClass *gobject_class = (GObjectClass *) klass;
176
177 gobject_class->get_property = webrtc_transceiver_get_property;
178 gobject_class->set_property = webrtc_transceiver_set_property;
179 gobject_class->finalize = webrtc_transceiver_finalize;
180
181 /* some acrobatics are required to set the parent before _constructed()
182 * has been called */
183 g_object_class_install_property (gobject_class,
184 PROP_WEBRTC,
185 g_param_spec_object ("webrtc", "Parent webrtcbin",
186 "Parent webrtcbin",
187 GST_TYPE_WEBRTC_BIN,
188 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
189
190 g_object_class_install_property (gobject_class,
191 PROP_FEC_TYPE,
192 g_param_spec_enum ("fec-type", "FEC type",
193 "The type of Forward Error Correction to use",
194 GST_TYPE_WEBRTC_FEC_TYPE,
195 DEFAULT_FEC_TYPE,
196 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
197
198 g_object_class_install_property (gobject_class,
199 PROP_DO_NACK,
200 g_param_spec_boolean ("do-nack", "Do nack",
201 "Whether to send negative acknowledgements for feedback",
202 DEFAULT_DO_NACK,
203 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
204
205 g_object_class_install_property (gobject_class,
206 PROP_FEC_PERCENTAGE,
207 g_param_spec_uint ("fec-percentage", "FEC percentage",
208 "The amount of Forward Error Correction to apply",
209 0, 100, DEFAULT_FEC_PERCENTAGE,
210 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
211 }
212
213 static void
webrtc_transceiver_init(WebRTCTransceiver * trans)214 webrtc_transceiver_init (WebRTCTransceiver * trans)
215 {
216 }
217
218 WebRTCTransceiver *
webrtc_transceiver_new(GstWebRTCBin * webrtc,GstWebRTCRTPSender * sender,GstWebRTCRTPReceiver * receiver)219 webrtc_transceiver_new (GstWebRTCBin * webrtc, GstWebRTCRTPSender * sender,
220 GstWebRTCRTPReceiver * receiver)
221 {
222 WebRTCTransceiver *trans;
223
224 trans = g_object_new (webrtc_transceiver_get_type (), "sender", sender,
225 "receiver", receiver, "webrtc", webrtc, NULL);
226
227 return trans;
228 }
229