• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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