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 <stdlib.h>
25
26 #include "utils.h"
27 #include "gstwebrtcbin.h"
28
29 GstPadTemplate *
_find_pad_template(GstElement * element,GstPadDirection direction,GstPadPresence presence,const gchar * name)30 _find_pad_template (GstElement * element, GstPadDirection direction,
31 GstPadPresence presence, const gchar * name)
32 {
33 GstElementClass *element_class = GST_ELEMENT_GET_CLASS (element);
34 const GList *l = gst_element_class_get_pad_template_list (element_class);
35 GstPadTemplate *templ = NULL;
36
37 for (; l; l = l->next) {
38 templ = l->data;
39 if (templ->direction != direction)
40 continue;
41 if (templ->presence != presence)
42 continue;
43 if (g_strcmp0 (templ->name_template, name) == 0) {
44 return templ;
45 }
46 }
47
48 return NULL;
49 }
50
51 GstSDPMessage *
_get_latest_offer(GstWebRTCBin * webrtc)52 _get_latest_offer (GstWebRTCBin * webrtc)
53 {
54 if (webrtc->current_local_description &&
55 webrtc->current_local_description->type == GST_WEBRTC_SDP_TYPE_OFFER) {
56 return webrtc->current_local_description->sdp;
57 }
58 if (webrtc->current_remote_description &&
59 webrtc->current_remote_description->type == GST_WEBRTC_SDP_TYPE_OFFER) {
60 return webrtc->current_remote_description->sdp;
61 }
62
63 return NULL;
64 }
65
66 GstSDPMessage *
_get_latest_answer(GstWebRTCBin * webrtc)67 _get_latest_answer (GstWebRTCBin * webrtc)
68 {
69 if (webrtc->current_local_description &&
70 webrtc->current_local_description->type == GST_WEBRTC_SDP_TYPE_ANSWER) {
71 return webrtc->current_local_description->sdp;
72 }
73 if (webrtc->current_remote_description &&
74 webrtc->current_remote_description->type == GST_WEBRTC_SDP_TYPE_ANSWER) {
75 return webrtc->current_remote_description->sdp;
76 }
77
78 return NULL;
79 }
80
81 GstSDPMessage *
_get_latest_sdp(GstWebRTCBin * webrtc)82 _get_latest_sdp (GstWebRTCBin * webrtc)
83 {
84 GstSDPMessage *ret = NULL;
85
86 if ((ret = _get_latest_answer (webrtc)))
87 return ret;
88 if ((ret = _get_latest_offer (webrtc)))
89 return ret;
90
91 return NULL;
92 }
93
94 GstSDPMessage *
_get_latest_self_generated_sdp(GstWebRTCBin * webrtc)95 _get_latest_self_generated_sdp (GstWebRTCBin * webrtc)
96 {
97 if (webrtc->priv->last_generated_answer)
98 return webrtc->priv->last_generated_answer->sdp;
99 if (webrtc->priv->last_generated_offer)
100 return webrtc->priv->last_generated_offer->sdp;
101
102 return NULL;
103 }
104
105 struct pad_block *
_create_pad_block(GstElement * element,GstPad * pad,gulong block_id,gpointer user_data,GDestroyNotify notify)106 _create_pad_block (GstElement * element, GstPad * pad, gulong block_id,
107 gpointer user_data, GDestroyNotify notify)
108 {
109 struct pad_block *ret = g_new0 (struct pad_block, 1);
110
111 ret->element = gst_object_ref (element);
112 ret->pad = gst_object_ref (pad);
113 ret->block_id = block_id;
114 ret->user_data = user_data;
115 ret->notify = notify;
116
117 return ret;
118 }
119
120 void
_free_pad_block(struct pad_block * block)121 _free_pad_block (struct pad_block *block)
122 {
123 if (!block)
124 return;
125
126 if (block->block_id)
127 gst_pad_remove_probe (block->pad, block->block_id);
128 gst_object_unref (block->element);
129 gst_object_unref (block->pad);
130 if (block->notify)
131 block->notify (block->user_data);
132 g_free (block);
133 }
134
135 gchar *
_enum_value_to_string(GType type,guint value)136 _enum_value_to_string (GType type, guint value)
137 {
138 GEnumClass *enum_class;
139 GEnumValue *enum_value;
140 gchar *str = NULL;
141
142 enum_class = g_type_class_ref (type);
143 enum_value = g_enum_get_value (enum_class, value);
144
145 if (enum_value)
146 str = g_strdup (enum_value->value_nick);
147
148 g_type_class_unref (enum_class);
149
150 return str;
151 }
152
153 const gchar *
_g_checksum_to_webrtc_string(GChecksumType type)154 _g_checksum_to_webrtc_string (GChecksumType type)
155 {
156 switch (type) {
157 case G_CHECKSUM_SHA1:
158 return "sha-1";
159 case G_CHECKSUM_SHA256:
160 return "sha-256";
161 #ifdef G_CHECKSUM_SHA384
162 case G_CHECKSUM_SHA384:
163 return "sha-384";
164 #endif
165 case G_CHECKSUM_SHA512:
166 return "sha-512";
167 default:
168 g_warning ("unknown GChecksumType!");
169 return NULL;
170 }
171 }
172
173 GstCaps *
_rtp_caps_from_media(const GstSDPMedia * media)174 _rtp_caps_from_media (const GstSDPMedia * media)
175 {
176 GstCaps *ret;
177 int i, j;
178
179 ret = gst_caps_new_empty ();
180 for (i = 0; i < gst_sdp_media_formats_len (media); i++) {
181 guint pt = atoi (gst_sdp_media_get_format (media, i));
182 GstCaps *caps;
183
184 caps = gst_sdp_media_get_caps_from_media (media, pt);
185 if (!caps)
186 continue;
187
188 /* gst_sdp_media_get_caps_from_media() produces caps with name
189 * "application/x-unknown" which will fail intersection with
190 * "application/x-rtp" caps so mangle the returns caps to have the
191 * correct name here */
192 for (j = 0; j < gst_caps_get_size (caps); j++) {
193 GstStructure *s = gst_caps_get_structure (caps, j);
194 gst_structure_set_name (s, "application/x-rtp");
195 }
196
197 gst_caps_append (ret, caps);
198 }
199
200 return ret;
201 }
202
203 GstWebRTCKind
webrtc_kind_from_caps(const GstCaps * caps)204 webrtc_kind_from_caps (const GstCaps * caps)
205 {
206 GstStructure *s;
207 const gchar *media;
208
209 if (!caps || gst_caps_get_size (caps) == 0)
210 return GST_WEBRTC_KIND_UNKNOWN;
211
212 s = gst_caps_get_structure (caps, 0);
213
214 media = gst_structure_get_string (s, "media");
215 if (media == NULL)
216 return GST_WEBRTC_KIND_UNKNOWN;
217
218 if (!g_strcmp0 (media, "audio"))
219 return GST_WEBRTC_KIND_AUDIO;
220
221 if (!g_strcmp0 (media, "video"))
222 return GST_WEBRTC_KIND_VIDEO;
223
224 return GST_WEBRTC_KIND_UNKNOWN;
225 }
226