2 * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 * Unless otherwise indicated, Source Code is licensed under MIT license.
21 * See further explanation attached in License Statement (distributed in the file
24 * Permission is hereby granted, free of charge, to any person obtaining a copy of
25 * this software and associated documentation files (the "Software"), to deal in
26 * the Software without restriction, including without limitation the rights to
27 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
28 * of the Software, and to permit persons to whom the Software is furnished to do
29 * so, subject to the following conditions:
31 * The above copyright notice and this permission notice shall be included in all
32 * copies or substantial portions of the Software.
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
44 * SECTION:gstsdpmessage
45 * @short_description: Helper methods for dealing with SDP messages
49 * The GstSDPMessage helper functions makes it easy to parse and create SDP
54 * Last reviewed on 2007-07-24 (0.10.14)
61 #include "gstsdpmessage.h"
63 /* FIXME, is currently allocated on the stack */
64 #define MAX_LINE_LEN 1024 * 16
66 #define FREE_STRING(field) g_free ((field)); (field) = NULL;
67 #define FREE_ARRAY(field) \
70 g_array_free (field, TRUE); \
73 #define REPLACE_STRING(field,val) FREE_STRING(field);field=g_strdup (val);
75 #define INIT_ARRAY(field,type,init_func) \
79 for(i=0; i<field->len; i++) \
80 init_func (&g_array_index(field, type, i)); \
81 g_array_set_size (field,0); \
84 field = g_array_new (FALSE, TRUE, sizeof(type)); \
87 #define DEFINE_STRING_SETTER(field) \
88 GstSDPResult gst_sdp_message_set_##field (GstSDPMessage *msg, const gchar *val) { \
89 g_free (msg->field); \
90 msg->field = g_strdup (val); \
93 #define DEFINE_STRING_GETTER(field) \
94 const gchar* gst_sdp_message_get_##field (GstSDPMessage *msg) { \
98 #define DEFINE_ARRAY_LEN(field) \
99 gint gst_sdp_message_##field##_len (GstSDPMessage *msg) { \
100 return ((msg)->field->len); \
102 #define DEFINE_ARRAY_GETTER(method,field,type) \
103 type gst_sdp_message_get_##method (GstSDPMessage *msg, guint idx) { \
104 return g_array_index ((msg)->field, type, idx); \
106 #define DEFINE_ARRAY_P_GETTER(method,field,type) \
107 type * gst_sdp_message_get_##method (GstSDPMessage *msg, guint idx) { \
108 return &g_array_index ((msg)->field, type, idx); \
110 #define DEFINE_ARRAY_ADDER(method,field,type,dup_method) \
111 GstSDPResult gst_sdp_message_add_##method (GstSDPMessage *msg, type val) { \
112 type v = dup_method(val); \
113 g_array_append_val((msg)->field, v); \
118 gst_sdp_origin_init (GstSDPOrigin * origin)
120 FREE_STRING (origin->username);
121 FREE_STRING (origin->sess_id);
122 FREE_STRING (origin->sess_version);
123 FREE_STRING (origin->nettype);
124 FREE_STRING (origin->addrtype);
125 FREE_STRING (origin->addr);
129 gst_sdp_connection_init (GstSDPConnection * connection)
131 FREE_STRING (connection->nettype);
132 FREE_STRING (connection->addrtype);
133 FREE_STRING (connection->address);
135 connection->addr_number = 0;
139 gst_sdp_bandwidth_init (GstSDPBandwidth * bandwidth)
141 FREE_STRING (bandwidth->bwtype);
142 bandwidth->bandwidth = 0;
146 gst_sdp_time_init (GstSDPTime * time)
148 FREE_STRING (time->start);
149 FREE_STRING (time->stop);
154 gst_sdp_zone_init (GstSDPZone * zone)
156 FREE_STRING (zone->time);
157 FREE_STRING (zone->typed_time);
161 gst_sdp_key_init (GstSDPKey * key)
163 FREE_STRING (key->type);
164 FREE_STRING (key->data);
168 gst_sdp_attribute_init (GstSDPAttribute * attr)
170 FREE_STRING (attr->key);
171 FREE_STRING (attr->value);
175 * gst_sdp_message_new:
176 * @msg: pointer to new #GstSDPMessage
178 * Allocate a new GstSDPMessage and store the result in @msg.
180 * Returns: a #GstSDPResult.
183 gst_sdp_message_new (GstSDPMessage ** msg)
185 GstSDPMessage *newmsg;
187 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
189 newmsg = g_new0 (GstSDPMessage, 1);
193 return gst_sdp_message_init (newmsg);
197 * gst_sdp_message_init:
198 * @msg: a #GstSDPMessage
200 * Initialize @msg so that its contents are as if it was freshly allocated
201 * with gst_sdp_message_new(). This function is mostly used to initialize a message
202 * allocated on the stack. gst_sdp_message_uninit() undoes this operation.
204 * When this function is invoked on newly allocated data (with malloc or on the
205 * stack), its contents should be set to 0 before calling this function.
207 * Returns: a #GstSDPResult.
210 gst_sdp_message_init (GstSDPMessage * msg)
212 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
214 FREE_STRING (msg->version);
215 gst_sdp_origin_init (&msg->origin);
216 FREE_STRING (msg->session_name);
217 FREE_STRING (msg->information);
218 FREE_STRING (msg->uri);
219 INIT_ARRAY (msg->emails, gchar *, g_free);
220 INIT_ARRAY (msg->phones, gchar *, g_free);
221 gst_sdp_connection_init (&msg->connection);
222 INIT_ARRAY (msg->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init);
223 INIT_ARRAY (msg->times, GstSDPTime, gst_sdp_time_init);
224 INIT_ARRAY (msg->zones, GstSDPZone, gst_sdp_zone_init);
225 gst_sdp_key_init (&msg->key);
226 INIT_ARRAY (msg->attributes, GstSDPAttribute, gst_sdp_attribute_init);
227 INIT_ARRAY (msg->medias, GstSDPMedia, gst_sdp_media_uninit);
233 * gst_sdp_message_uninit:
234 * @msg: a #GstSDPMessage
236 * Free all resources allocated in @msg. @msg should not be used anymore after
237 * this function. This function should be used when @msg was allocated on the
238 * stack and initialized with gst_sdp_message_init().
240 * Returns: a #GstSDPResult.
243 gst_sdp_message_uninit (GstSDPMessage * msg)
245 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
247 gst_sdp_message_init (msg);
249 FREE_ARRAY (msg->emails);
250 FREE_ARRAY (msg->phones);
251 FREE_ARRAY (msg->bandwidths);
252 FREE_ARRAY (msg->times);
253 FREE_ARRAY (msg->zones);
254 FREE_ARRAY (msg->attributes);
255 FREE_ARRAY (msg->medias);
261 * gst_sdp_message_free:
262 * @msg: a #GstSDPMessage
264 * Free all resources allocated by @msg. @msg should not be used anymore after
265 * this function. This function should be used when @msg was dynamically
266 * allocated with gst_sdp_message_new().
268 * Returns: a #GstSDPResult.
271 gst_sdp_message_free (GstSDPMessage * msg)
273 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
275 gst_sdp_message_uninit (msg);
282 * gst_sdp_message_set_version:
283 * @msg: a #GstSDPMessage
284 * @version: the version
286 * Set the version in @msg.
288 * Returns: a #GstSDPResult.
290 DEFINE_STRING_SETTER (version);
292 * gst_sdp_message_get_version:
293 * @msg: a #GstSDPMessage
295 * Get the version in @msg.
297 * Returns: a #GstSDPResult.
299 DEFINE_STRING_GETTER (version);
302 * gst_sdp_message_set_origin:
303 * @msg: a #GstSDPMessage
304 * @username: the user name
305 * @sess_id: a session id
306 * @sess_version: a session version
307 * @nettype: a network type
308 * @addrtype: an address type
311 * Configure the SDP origin in @msg with the given parameters.
313 * Returns: #GST_SDP_OK.
316 gst_sdp_message_set_origin (GstSDPMessage * msg, const gchar * username,
317 const gchar * sess_id, const gchar * sess_version, const gchar * nettype,
318 const gchar * addrtype, const gchar * addr)
320 REPLACE_STRING (msg->origin.username, username);
321 REPLACE_STRING (msg->origin.sess_id, sess_id);
322 REPLACE_STRING (msg->origin.sess_version, sess_version);
323 REPLACE_STRING (msg->origin.nettype, nettype);
324 REPLACE_STRING (msg->origin.addrtype, addrtype);
325 REPLACE_STRING (msg->origin.addr, addr);
331 * gst_sdp_message_get_origin:
332 * @msg: a #GstSDPMessage
334 * Get the origin of @msg.
336 * Returns: a #GstSDPOrigin. The result remains valid as long as @msg is valid.
339 gst_sdp_message_get_origin (GstSDPMessage * msg)
345 * gst_sdp_message_set_session_name:
346 * @msg: a #GstSDPMessage
347 * @session_name: the session name
349 * Set the session name in @msg.
351 * Returns: a #GstSDPResult.
353 DEFINE_STRING_SETTER (session_name);
355 * gst_sdp_message_get_session_name:
356 * @msg: a #GstSDPMessage
358 * Get the session name in @msg.
360 * Returns: a #GstSDPResult.
362 DEFINE_STRING_GETTER (session_name);
364 * gst_sdp_message_set_information:
365 * @msg: a #GstSDPMessage
366 * @information: the information
368 * Set the information in @msg.
370 * Returns: a #GstSDPResult.
372 DEFINE_STRING_SETTER (information);
374 * gst_sdp_message_get_information:
375 * @msg: a #GstSDPMessage
377 * Get the information in @msg.
379 * Returns: a #GstSDPResult.
381 DEFINE_STRING_GETTER (information);
383 * gst_sdp_message_set_uri:
384 * @msg: a #GstSDPMessage
387 * Set the URI in @msg.
389 * Returns: a #GstSDPResult.
391 DEFINE_STRING_SETTER (uri);
393 * gst_sdp_message_get_uri:
394 * @msg: a #GstSDPMessage
396 * Get the URI in @msg.
398 * Returns: a #GstSDPResult.
400 DEFINE_STRING_GETTER (uri);
403 * gst_sdp_message_emails_len:
404 * @msg: a #GstSDPMessage
406 * Get the number of emails in @msg.
408 * Returns: the number of emails in @msg.
410 DEFINE_ARRAY_LEN (emails);
412 * gst_sdp_message_get_email:
413 * @msg: a #GstSDPMessage
414 * @idx: an email index
416 * Get the email with number @idx from @msg.
418 * Returns: the email at position @idx.
420 DEFINE_ARRAY_GETTER (email, emails, const gchar *);
423 * gst_sdp_message_add_email:
424 * @msg: a #GstSDPMessage
427 * Add @email to the list of emails in @msg.
429 * Returns: a #GstSDPResult.
431 DEFINE_ARRAY_ADDER (email, emails, const gchar *, g_strdup);
434 * gst_sdp_message_phones_len:
435 * @msg: a #GstSDPMessage
437 * Get the number of phones in @msg.
439 * Returns: the number of phones in @msg.
441 DEFINE_ARRAY_LEN (phones);
443 * gst_sdp_message_get_phone:
444 * @msg: a #GstSDPMessage
445 * @idx: a phone index
447 * Get the phone with number @idx from @msg.
449 * Returns: the phone at position @idx.
451 DEFINE_ARRAY_GETTER (phone, phones, const gchar *);
454 * gst_sdp_message_add_phone:
455 * @msg: a #GstSDPMessage
458 * Add @phone to the list of phones in @msg.
460 * Returns: a #GstSDPResult.
462 DEFINE_ARRAY_ADDER (phone, phones, const gchar *, g_strdup);
465 * gst_sdp_message_set_connection:
466 * @msg: a #GstSDPMessage
467 * @nettype: the type of network. "IN" is defined to have the meaning
469 * @addrtype: the type of address.
470 * @address: the address
471 * @ttl: the time to live of the address
472 * @addr_number: the number of layers
474 * Configure the SDP connection in @msg with the given parameters.
476 * Returns: a #GstSDPResult.
479 gst_sdp_message_set_connection (GstSDPMessage * msg, const gchar * nettype,
480 const gchar * addrtype, const gchar * address, gint ttl, gint addr_number)
482 REPLACE_STRING (msg->connection.nettype, nettype);
483 REPLACE_STRING (msg->connection.addrtype, addrtype);
484 REPLACE_STRING (msg->connection.address, address);
485 msg->connection.ttl = ttl;
486 msg->connection.addr_number = addr_number;
492 * gst_sdp_message_get_connection:
493 * @msg: a #GstSDPMessage
495 * Get the connection of @msg.
497 * Returns: a #GstSDPConnection. The result remains valid as long as @msg is valid.
499 const GstSDPConnection *
500 gst_sdp_message_get_connection (GstSDPMessage * msg)
502 return &msg->connection;
506 * gst_sdp_message_bandwidths_len:
507 * @msg: a #GstSDPMessage
509 * Get the number of bandwidth information in @msg.
511 * Returns: the number of bandwidth information in @msg.
513 DEFINE_ARRAY_LEN (bandwidths);
515 * gst_sdp_message_get_bandwidth:
516 * @msg: a #GstSDPMessage
517 * @idx: the bandwidth index
519 * Get the bandwidth at index @idx from @msg.
521 * Returns: a #GstSDPBandwidth.
523 DEFINE_ARRAY_P_GETTER (bandwidth, bandwidths, const GstSDPBandwidth);
526 * gst_sdp_message_add_bandwidth:
527 * @msg: a #GstSDPMessage
528 * @bwtype: the bandwidth modifier type
529 * @bandwidth: the bandwidth in kilobits per second
531 * Add the specified bandwidth information to @msg.
533 * Returns: a #GstSDPResult.
536 gst_sdp_message_add_bandwidth (GstSDPMessage * msg, const gchar * bwtype,
541 bw.bwtype = g_strdup (bwtype);
542 bw.bandwidth = bandwidth;
544 g_array_append_val (msg->bandwidths, bw);
550 * gst_sdp_message_times_len:
551 * @msg: a #GstSDPMessage
553 * Get the number of time information entries in @msg.
555 * Returns: the number of time information entries in @msg.
557 DEFINE_ARRAY_LEN (times);
560 * gst_sdp_message_get_time:
561 * @msg: a #GstSDPMessage
562 * @idx: the time index
564 * Get time information with index @idx from @msg.
566 * Returns: a #GstSDPTime.
568 DEFINE_ARRAY_P_GETTER (time, times, const GstSDPTime);
571 * gst_sdp_message_add_time:
572 * @msg: a #GstSDPMessage
573 * @time: a time information
575 * Add time information @time to @msg.
577 * Returns: a #GstSDPResult.
580 gst_sdp_message_add_time (GstSDPMessage * msg, const gchar * time)
586 * gst_sdp_message_zones_len:
587 * @msg: a #GstSDPMessage
589 * Get the number of time zone information entries in @msg.
591 * Returns: the number of time zone information entries in @msg.
593 DEFINE_ARRAY_LEN (zones);
595 * gst_sdp_message_get_zone:
596 * @msg: a #GstSDPMessage
597 * @idx: the zone index
599 * Get time zone information with index @idx from @msg.
601 * Returns: a #GstSDPZone.
603 DEFINE_ARRAY_P_GETTER (zone, zones, const GstSDPZone);
606 * gst_sdp_message_add_zone:
607 * @msg: a #GstSDPMessage
608 * @time: the NTP time that a time zone adjustment happens
609 * @typed_time: the offset from the time when the session was first scheduled
611 * Add time zone information to @msg.
613 * Returns: a #GstSDPResult.
616 gst_sdp_message_add_zone (GstSDPMessage * msg, const gchar * time,
617 const gchar * typed_time)
621 zone.time = g_strdup (time);
622 zone.typed_time = g_strdup (typed_time);
624 g_array_append_val (msg->zones, zone);
630 * gst_sdp_message_set_key:
631 * @msg: a #GstSDPMessage
632 * @type: the encryption type
633 * @data: the encryption data
635 * Adds the encryption information to @msg.
637 * Returns: a #GstSDPResult.
640 gst_sdp_message_set_key (GstSDPMessage * msg, const gchar * type,
643 REPLACE_STRING (msg->key.type, type);
644 REPLACE_STRING (msg->key.data, data);
650 * gst_sdp_message_get_key:
651 * @msg: a #GstSDPMessage
653 * Get the encryption information from @msg.
655 * Returns: a #GstSDPKey.
658 gst_sdp_message_get_key (GstSDPMessage * msg)
664 * gst_sdp_message_attributes_len:
665 * @msg: a #GstSDPMessage
667 * Get the number of attributes in @msg.
669 * Returns: the number of attributes in @msg.
671 DEFINE_ARRAY_LEN (attributes);
673 * gst_sdp_message_get_attribute:
674 * @msg: a #GstSDPMessage
677 * Get the attribute at position @idx in @msg.
679 * Returns: the #GstSDPAttribute at position @idx.
681 DEFINE_ARRAY_P_GETTER (attribute, attributes, const GstSDPAttribute);
683 * gst_sdp_message_get_attribute_val_n:
684 * @msg: a #GstSDPMessage
688 * Get the @nth attribute with key @key in @msg.
690 * Returns: the attribute value of the @nth attribute with @key.
693 gst_sdp_message_get_attribute_val_n (GstSDPMessage * msg, const gchar * key,
698 for (i = 0; i < msg->attributes->len; i++) {
699 GstSDPAttribute *attr;
701 attr = &g_array_index (msg->attributes, GstSDPAttribute, i);
702 if (!strcmp (attr->key, key)) {
713 * gst_sdp_message_get_attribute_val:
714 * @msg: a #GstSDPMessage
717 * Get the first attribute with key @key in @msg.
719 * Returns: the attribute value of the first attribute with @key.
722 gst_sdp_message_get_attribute_val (GstSDPMessage * msg, const gchar * key)
724 return gst_sdp_message_get_attribute_val_n (msg, key, 0);
728 * gst_sdp_message_add_attribute:
729 * @msg: a #GstSDPMessage
733 * Add the attribute with @key and @value to @msg.
735 * Returns: @GST_SDP_OK.
738 gst_sdp_message_add_attribute (GstSDPMessage * msg, const gchar * key,
741 GstSDPAttribute attr;
743 attr.key = g_strdup (key);
744 attr.value = g_strdup (value);
746 g_array_append_val (msg->attributes, attr);
752 * gst_sdp_message_medias_len:
753 * @msg: a #GstSDPMessage
755 * Get the number of media descriptions in @msg.
757 * Returns: the number of media descriptions in @msg.
759 DEFINE_ARRAY_LEN (medias);
761 * gst_sdp_message_get_media:
762 * @msg: a #GstSDPMessage
765 * Get the media description at index @idx in @msg.
767 * Returns: a #GstSDPMedia.
769 DEFINE_ARRAY_P_GETTER (media, medias, const GstSDPMedia);
772 * gst_sdp_message_add_media:
773 * @msg: a #GstSDPMessage
774 * @media: a #GstSDPMedia to add
776 * Adds @media to the array of medias in @msg. This function takes ownership of
777 * the contents of @media so that @media will have to be reinitialized with
778 * gst_media_init() before it can be used again.
780 * Returns: a #GstSDPResult.
783 gst_sdp_message_add_media (GstSDPMessage * msg, GstSDPMedia * media)
788 len = msg->medias->len;
789 g_array_set_size (msg->medias, len + 1);
790 nmedia = &g_array_index (msg->medias, GstSDPMedia, len);
792 memcpy (nmedia, media, sizeof (GstSDPMedia));
793 memset (media, 0, sizeof (GstSDPMedia));
802 * @media: pointer to new #GstSDPMedia
804 * Allocate a new GstSDPMedia and store the result in @media.
806 * Returns: a #GstSDPResult.
809 gst_sdp_media_new (GstSDPMedia ** media)
811 GstSDPMedia *newmedia;
813 g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
815 newmedia = g_new0 (GstSDPMedia, 1);
819 return gst_sdp_media_init (newmedia);
823 * gst_sdp_media_init:
824 * @media: a #GstSDPMedia
826 * Initialize @media so that its contents are as if it was freshly allocated
827 * with gst_sdp_media_new(). This function is mostly used to initialize a media
828 * allocated on the stack. gst_sdp_media_uninit() undoes this operation.
830 * When this function is invoked on newly allocated data (with malloc or on the
831 * stack), its contents should be set to 0 before calling this function.
833 * Returns: a #GstSDPResult.
836 gst_sdp_media_init (GstSDPMedia * media)
838 g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
840 FREE_STRING (media->media);
842 media->num_ports = 0;
843 FREE_STRING (media->proto);
844 INIT_ARRAY (media->fmts, gchar *, g_free);
845 FREE_STRING (media->information);
846 INIT_ARRAY (media->connections, GstSDPConnection, gst_sdp_connection_init);
847 INIT_ARRAY (media->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init);
848 gst_sdp_key_init (&media->key);
849 INIT_ARRAY (media->attributes, GstSDPAttribute, gst_sdp_attribute_init);
855 * gst_sdp_media_uninit:
856 * @media: a #GstSDPMedia
858 * Free all resources allocated in @media. @media should not be used anymore after
859 * this function. This function should be used when @media was allocated on the
860 * stack and initialized with gst_sdp_media_init().
862 * Returns: a #GstSDPResult.
865 gst_sdp_media_uninit (GstSDPMedia * media)
867 g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
869 gst_sdp_media_init (media);
870 FREE_ARRAY (media->fmts);
871 FREE_ARRAY (media->connections);
872 FREE_ARRAY (media->bandwidths);
873 FREE_ARRAY (media->attributes);
879 * gst_sdp_media_free:
880 * @media: a #GstSDPMedia
882 * Free all resources allocated by @media. @media should not be used anymore after
883 * this function. This function should be used when @media was dynamically
884 * allocated with gst_sdp_media_new().
886 * Returns: a #GstSDPResult.
889 gst_sdp_media_free (GstSDPMedia * media)
891 g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
893 gst_sdp_media_uninit (media);
900 * gst_sdp_media_get_media:
901 * @media: a #GstSDPMedia
903 * Get the media description of @media.
905 * Returns: the media description.
908 gst_sdp_media_get_media (GstSDPMedia * media)
914 * gst_sdp_media_set_media:
915 * @media: a #GstSDPMedia
916 * @med: the media description
918 * Set the media description of @media to @med.
920 * Returns: #GST_SDP_OK.
923 gst_sdp_media_set_media (GstSDPMedia * media, const gchar * med)
925 g_free (media->media);
926 media->media = g_strdup (med);
932 * gst_sdp_media_get_port:
933 * @media: a #GstSDPMedia
935 * Get the port number for @media.
937 * Returns: the port number of @media.
940 gst_sdp_media_get_port (GstSDPMedia * media)
946 * gst_sdp_media_get_num_ports:
947 * @media: a #GstSDPMedia
949 * Get the number of ports for @media.
951 * Returns: the number of ports for @media.
954 gst_sdp_media_get_num_ports (GstSDPMedia * media)
956 return media->num_ports;
960 * gst_sdp_media_set_port_info:
961 * @media: a #GstSDPMedia
962 * @port: the port number
963 * @num_ports: the number of ports
965 * Set the port information in @media.
967 * Returns: #GST_SDP_OK.
970 gst_sdp_media_set_port_info (GstSDPMedia * media, gint port, gint num_ports)
973 media->num_ports = num_ports;
979 * gst_sdp_media_get_proto:
980 * @media: a #GstSDPMedia
982 * Get the transport protocol of @media
984 * Returns: the transport protocol of @media.
987 gst_sdp_media_get_proto (GstSDPMedia * media)
993 * gst_sdp_media_set_proto:
994 * @media: a #GstSDPMedia
995 * @proto: the media transport protocol
997 * Set the media transport protocol of @media to @proto.
999 * Returns: #GST_SDP_OK.
1002 gst_sdp_media_set_proto (GstSDPMedia * media, const gchar * proto)
1004 g_free (media->proto);
1005 media->proto = g_strdup (proto);
1011 * gst_sdp_media_formats_len:
1012 * @media: a #GstSDPMedia
1014 * Get the number of formats in @media.
1016 * Returns: the number of formats in @media.
1019 gst_sdp_media_formats_len (GstSDPMedia * media)
1021 return media->fmts->len;
1025 * gst_sdp_media_get_format:
1026 * @media: a #GstSDPMedia
1029 * Get the format information at position @idx in @media.
1031 * Returns: the format at position @idx.
1034 gst_sdp_media_get_format (GstSDPMedia * media, guint idx)
1036 if (idx >= media->fmts->len)
1038 return g_array_index (media->fmts, gchar *, idx);
1042 * gst_sdp_media_add_format:
1043 * @media: a #GstSDPMedia
1044 * @format: the format
1046 * Add the format information to @media.
1048 * Returns: #GST_SDP_OK.
1051 gst_sdp_media_add_format (GstSDPMedia * media, const gchar * format)
1055 fmt = g_strdup (format);
1057 g_array_append_val (media->fmts, fmt);
1063 * gst_sdp_media_get_information:
1064 * @media: a #GstSDPMedia
1066 * Get the information of @media
1068 * Returns: the information of @media.
1071 gst_sdp_media_get_information (GstSDPMedia * media)
1073 return media->information;
1077 * gst_sdp_media_set_information:
1078 * @media: a #GstSDPMedia
1079 * @information: the media information
1081 * Set the media information of @media to @information.
1083 * Returns: #GST_SDP_OK.
1086 gst_sdp_media_set_information (GstSDPMedia * media, const gchar * information)
1088 g_free (media->information);
1089 media->information = g_strdup (information);
1095 * gst_sdp_media_connections_len:
1096 * @media: a #GstSDPMedia
1098 * Get the number of connection fields in @media.
1100 * Returns: the number of connections in @media.
1103 gst_sdp_media_connections_len (GstSDPMedia * media)
1105 return (media->connections->len);
1109 * gst_sdp_media_get_connection:
1110 * @media: a #GstSDPMedia
1113 * Get the connection at position @idx in @media.
1115 * Returns: the #GstSDPConnection at position @idx.
1117 const GstSDPConnection *
1118 gst_sdp_media_get_connection (GstSDPMedia * media, guint idx)
1120 return &g_array_index (media->connections, GstSDPConnection, idx);
1124 * gst_sdp_media_add_connection:
1125 * @media: a #GstSDPMedia
1126 * @nettype: the type of network. "IN" is defined to have the meaning
1128 * @addrtype: the type of address.
1129 * @address: the address
1130 * @ttl: the time to live of the address
1131 * @addr_number: the number of layers
1133 * Add the given connection parameters to @media.
1135 * Returns: a #GstSDPResult.
1138 gst_sdp_media_add_connection (GstSDPMedia * media, const gchar * nettype,
1139 const gchar * addrtype, const gchar * address, gint ttl, gint addr_number)
1141 GstSDPConnection conn;
1143 conn.nettype = g_strdup (nettype);
1144 conn.addrtype = g_strdup (addrtype);
1145 conn.address = g_strdup (address);
1147 conn.addr_number = addr_number;
1149 g_array_append_val (media->connections, conn);
1155 * gst_sdp_media_bandwidths_len:
1156 * @media: a #GstSDPMedia
1158 * Get the number of bandwidth fields in @media.
1160 * Returns: the number of bandwidths in @media.
1163 gst_sdp_media_bandwidths_len (GstSDPMedia * media)
1165 return (media->bandwidths->len);
1169 * gst_sdp_media_get_bandwidth:
1170 * @media: a #GstSDPMedia
1173 * Get the bandwidth at position @idx in @media.
1175 * Returns: the #GstSDPBandwidth at position @idx.
1177 const GstSDPBandwidth *
1178 gst_sdp_media_get_badwidth (GstSDPMedia * media, guint idx)
1180 return &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
1184 * gst_sdp_media_add_bandwidth:
1185 * @media: a #GstSDPMedia
1186 * @bwtype: the bandwidth modifier type
1187 * @bandwidth: the bandwidth in kilobits per second
1189 * Add the bandwidth information with @bwtype and @bandwidth to @media.
1191 * Returns: #GST_SDP_OK.
1194 gst_sdp_media_add_bandwidth (GstSDPMedia * media, const gchar * bwtype,
1199 bw.bwtype = g_strdup (bwtype);
1200 bw.bandwidth = bandwidth;
1202 g_array_append_val (media->bandwidths, bw);
1208 * gst_sdp_media_set_key:
1209 * @media: a #GstSDPMedia
1210 * @type: the encryption type
1211 * @data: the encryption data
1213 * Adds the encryption information to @media.
1215 * Returns: a #GstSDPResult.
1218 gst_sdp_media_set_key (GstSDPMedia * media, const gchar * type,
1221 g_free (media->key.type);
1222 media->key.type = g_strdup (type);
1223 g_free (media->key.data);
1224 media->key.data = g_strdup (data);
1230 * gst_sdp_media_get_key:
1231 * @media: a #GstSDPMedia
1233 * Get the encryption information from @media.
1235 * Returns: a #GstSDPKey.
1238 gst_sdp_media_get_key (GstSDPMedia * media)
1244 * gst_sdp_media_attributes_len:
1245 * @media: a #GstSDPMedia
1247 * Get the number of attribute fields in @media.
1249 * Returns: the number of attributes in @media.
1252 gst_sdp_media_attributes_len (GstSDPMedia * media)
1254 return (media->attributes->len);
1258 * gst_sdp_media_add_attribute:
1259 * @media: a #GstSDPMedia
1263 * Add the attribute with @key and @value to @media.
1265 * Returns: #GST_SDP_OK.
1268 gst_sdp_media_add_attribute (GstSDPMedia * media, const gchar * key,
1269 const gchar * value)
1271 GstSDPAttribute attr;
1273 attr.key = g_strdup (key);
1274 attr.value = g_strdup (value);
1276 g_array_append_val (media->attributes, attr);
1282 * gst_sdp_media_get_attribute:
1283 * @media: a #GstSDPMedia
1286 * Get the attribute at position @idx in @media.
1288 * Returns: the #GstSDPAttribute at position @idx.
1290 const GstSDPAttribute *
1291 gst_sdp_media_get_attribute (GstSDPMedia * media, guint idx)
1293 return &g_array_index (media->attributes, GstSDPAttribute, idx);
1297 * gst_sdp_media_get_attribute_val_n:
1298 * @media: a #GstSDPMedia
1302 * Get the @nth attribute value for @key in @media.
1304 * Returns: the @nth attribute value.
1307 gst_sdp_media_get_attribute_val_n (GstSDPMedia * media, const gchar * key,
1312 for (i = 0; i < media->attributes->len; i++) {
1313 GstSDPAttribute *attr;
1315 attr = &g_array_index (media->attributes, GstSDPAttribute, i);
1316 if (!strcmp (attr->key, key)) {
1327 * gst_sdp_media_get_attribute_val:
1328 * @media: a #GstSDPMedia
1331 * Get the first attribute value for @key in @media.
1333 * Returns: the first attribute value for @key.
1336 gst_sdp_media_get_attribute_val (GstSDPMedia * media, const gchar * key)
1338 return gst_sdp_media_get_attribute_val_n (media, key, 0);
1342 read_string (gchar * dest, guint size, gchar ** src)
1348 while (g_ascii_isspace (**src))
1351 while (!g_ascii_isspace (**src) && **src != '\0') {
1353 dest[idx++] = **src;
1361 read_string_del (gchar * dest, guint size, gchar del, gchar ** src)
1367 while (g_ascii_isspace (**src))
1370 while (**src != del && **src != '\0') {
1372 dest[idx++] = **src;
1393 gst_sdp_parse_line (SDPContext * c, gchar type, gchar * buffer)
1398 #define READ_STRING(field) read_string (str, sizeof(str), &p);REPLACE_STRING (field, str);
1399 #define READ_INT(field) read_string (str, sizeof(str), &p);field = atoi(str);
1403 if (buffer[0] != '0')
1404 g_warning ("wrong SDP version");
1405 gst_sdp_message_set_version (c->msg, buffer);
1408 READ_STRING (c->msg->origin.username);
1409 READ_STRING (c->msg->origin.sess_id);
1410 READ_STRING (c->msg->origin.sess_version);
1411 READ_STRING (c->msg->origin.nettype);
1412 READ_STRING (c->msg->origin.addrtype);
1413 READ_STRING (c->msg->origin.addr);
1416 REPLACE_STRING (c->msg->session_name, buffer);
1419 if (c->state == SDP_SESSION) {
1420 REPLACE_STRING (c->msg->information, buffer);
1422 REPLACE_STRING (c->media->information, buffer);
1426 REPLACE_STRING (c->msg->uri, buffer);
1429 gst_sdp_message_add_email (c->msg, buffer);
1432 gst_sdp_message_add_phone (c->msg, buffer);
1435 READ_STRING (c->msg->connection.nettype);
1436 READ_STRING (c->msg->connection.addrtype);
1437 READ_STRING (c->msg->connection.address);
1438 READ_INT (c->msg->connection.ttl);
1439 READ_INT (c->msg->connection.addr_number);
1443 gchar str2[MAX_LINE_LEN];
1445 read_string_del (str, sizeof (str), ':', &p);
1446 read_string (str2, sizeof (str2), &p);
1447 if (c->state == SDP_SESSION)
1448 gst_sdp_message_add_bandwidth (c->msg, str, atoi (str2));
1450 gst_sdp_media_add_bandwidth (c->media, str, atoi (str2));
1459 read_string_del (str, sizeof (str), ':', &p);
1462 if (c->state == SDP_SESSION)
1463 gst_sdp_message_add_attribute (c->msg, str, p);
1465 gst_sdp_media_add_attribute (c->media, str, p);
1472 c->state = SDP_MEDIA;
1473 memset (&nmedia, 0, sizeof (nmedia));
1474 gst_sdp_media_init (&nmedia);
1476 READ_STRING (nmedia.media);
1477 read_string (str, sizeof (str), &p);
1478 slash = g_strrstr (str, "/");
1481 nmedia.port = atoi (str);
1482 nmedia.num_ports = atoi (slash + 1);
1484 nmedia.port = atoi (str);
1485 nmedia.num_ports = -1;
1487 READ_STRING (nmedia.proto);
1489 read_string (str, sizeof (str), &p);
1490 gst_sdp_media_add_format (&nmedia, str);
1491 } while (*p != '\0');
1493 gst_sdp_message_add_media (c->msg, &nmedia);
1495 &g_array_index (c->msg->medias, GstSDPMedia, c->msg->medias->len - 1);
1505 * gst_sdp_message_parse_buffer:
1506 * @data: the start of the buffer
1507 * @size: the size of the buffer
1508 * @msg: the result #GstSDPMessage
1510 * Parse the contents of @size bytes pointed to by @data and store the result in
1513 * Returns: #GST_SDP_OK on success.
1516 gst_sdp_message_parse_buffer (const guint8 * data, guint size,
1517 GstSDPMessage * msg)
1522 gchar buffer[MAX_LINE_LEN];
1525 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
1526 g_return_val_if_fail (data != NULL, GST_SDP_EINVAL);
1527 g_return_val_if_fail (size != 0, GST_SDP_EINVAL);
1529 c.state = SDP_SESSION;
1535 while (g_ascii_isspace (*p))
1547 while (*p != '\n' && *p != '\r' && *p != '\0') {
1548 if (idx < sizeof (buffer) - 1)
1553 gst_sdp_parse_line (&c, type, buffer);
1556 while (*p != '\n' && *p != '\0')
1566 print_media (GstSDPMedia * media)
1568 g_print (" media: '%s'\n", media->media);
1569 g_print (" port: '%d'\n", media->port);
1570 g_print (" num_ports: '%d'\n", media->num_ports);
1571 g_print (" proto: '%s'\n", media->proto);
1572 if (media->fmts->len > 0) {
1575 g_print (" formats:\n");
1576 for (i = 0; i < media->fmts->len; i++) {
1577 g_print (" format '%s'\n", g_array_index (media->fmts, gchar *, i));
1580 g_print (" information: '%s'\n", media->information);
1581 g_print (" key:\n");
1582 g_print (" type: '%s'\n", media->key.type);
1583 g_print (" data: '%s'\n", media->key.data);
1584 if (media->attributes->len > 0) {
1587 g_print (" attributes:\n");
1588 for (i = 0; i < media->attributes->len; i++) {
1589 GstSDPAttribute *attr =
1590 &g_array_index (media->attributes, GstSDPAttribute, i);
1592 g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
1598 * gst_sdp_message_dump:
1599 * @msg: a #GstSDPMessage
1601 * Dump the parsed contents of @msg to stdout.
1603 * Returns: a #GstSDPResult.
1606 gst_sdp_message_dump (GstSDPMessage * msg)
1608 g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
1610 g_print ("sdp packet %p:\n", msg);
1611 g_print (" version: '%s'\n", msg->version);
1612 g_print (" origin:\n");
1613 g_print (" username: '%s'\n", msg->origin.username);
1614 g_print (" sess_id: '%s'\n", msg->origin.sess_id);
1615 g_print (" sess_version: '%s'\n", msg->origin.sess_version);
1616 g_print (" nettype: '%s'\n", msg->origin.nettype);
1617 g_print (" addrtype: '%s'\n", msg->origin.addrtype);
1618 g_print (" addr: '%s'\n", msg->origin.addr);
1619 g_print (" session_name: '%s'\n", msg->session_name);
1620 g_print (" information: '%s'\n", msg->information);
1621 g_print (" uri: '%s'\n", msg->uri);
1623 if (msg->emails->len > 0) {
1626 g_print (" emails:\n");
1627 for (i = 0; i < msg->emails->len; i++) {
1628 g_print (" email '%s'\n", g_array_index (msg->emails, gchar *, i));
1631 if (msg->phones->len > 0) {
1634 g_print (" phones:\n");
1635 for (i = 0; i < msg->phones->len; i++) {
1636 g_print (" phone '%s'\n", g_array_index (msg->phones, gchar *, i));
1639 g_print (" connection:\n");
1640 g_print (" nettype: '%s'\n", msg->connection.nettype);
1641 g_print (" addrtype: '%s'\n", msg->connection.addrtype);
1642 g_print (" address: '%s'\n", msg->connection.address);
1643 g_print (" ttl: '%d'\n", msg->connection.ttl);
1644 g_print (" addr_number: '%d'\n", msg->connection.addr_number);
1645 g_print (" key:\n");
1646 g_print (" type: '%s'\n", msg->key.type);
1647 g_print (" data: '%s'\n", msg->key.data);
1648 if (msg->attributes->len > 0) {
1651 g_print (" attributes:\n");
1652 for (i = 0; i < msg->attributes->len; i++) {
1653 GstSDPAttribute *attr =
1654 &g_array_index (msg->attributes, GstSDPAttribute, i);
1656 g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
1659 if (msg->medias->len > 0) {
1662 g_print (" medias:\n");
1663 for (i = 0; i < msg->medias->len; i++) {
1664 g_print (" media %d:\n", i);
1665 print_media (&g_array_index (msg->medias, GstSDPMedia, i));