diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2011-10-11 16:08:49 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2011-10-11 16:14:10 -0400 |
commit | 52a59229d200a8d74d66e02126c290434d3157d8 (patch) | |
tree | 1adf3344ad47dbed6c35c42511362b232c703683 /farstream/fs-rtp.c | |
parent | 7098f40db04b6a32c311b802a2c12f0f450ee7b7 (diff) | |
download | farstream-52a59229d200a8d74d66e02126c290434d3157d8.tar.gz |
Move the lib out of gst-libs
Diffstat (limited to 'farstream/fs-rtp.c')
-rw-r--r-- | farstream/fs-rtp.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/farstream/fs-rtp.c b/farstream/fs-rtp.c new file mode 100644 index 00000000..c978670c --- /dev/null +++ b/farstream/fs-rtp.c @@ -0,0 +1,318 @@ +/* + * Farstream - Farstream RTP specific types + * + * Copyright 2011 Collabora Ltd. + * @author: Olivier Crete <olivier.crete@collabora.co.uk> + * Copyright 2011 Nokia Corp. + * + * fs-rtp.c - Farstream RTP specific types + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fs-rtp.h" + +#include <string.h> + +typedef GList FsRtpHeaderExtensionGList; + +G_DEFINE_BOXED_TYPE (FsRtpHeaderExtension, fs_rtp_header_extension, + fs_rtp_header_extension_copy, fs_rtp_header_extension_destroy) +G_DEFINE_BOXED_TYPE (FsRtpHeaderExtensionGList, fs_rtp_header_extension_list, + fs_rtp_header_extension_list_copy, fs_rtp_header_extension_list_destroy) + + +/** + * fs_rtp_header_extension_new: + * @id: The identifier of the RTP header extension + * @direction: the direction in which this extension can be used + * @uri: The URI that defines this extension + * + * Creates a new #FsRtpHeaderExtension + * + * Returns: a new #FsRtpHeaderExtension + */ + +FsRtpHeaderExtension * +fs_rtp_header_extension_new (guint id, FsStreamDirection direction, + const gchar *uri) +{ + FsRtpHeaderExtension *extension; + + extension = g_slice_new (FsRtpHeaderExtension); + + extension->id = id; + extension->direction = direction; + extension->uri = g_strdup (uri); + + return extension; +} + +/** + * fs_rtp_header_extension_copy: + * @extension: The RTP header extension definition to copy + * + * Copies a #FsRtpHeaderExtension + * + * Returns: a new #FsRtpHeaderExtension + */ + +FsRtpHeaderExtension * +fs_rtp_header_extension_copy (FsRtpHeaderExtension *extension) +{ + if (extension) + return fs_rtp_header_extension_new (extension->id, extension->direction, + extension->uri); + else + return NULL; +} + +/** + * fs_rtp_header_extension_are_equal: + * @extension1: The first #FsRtpHeaderExtension + * @extension2: The second #FsRtpHeaderExtension + * + * Compares two #FsRtpHeaderExtension structures + * + * Returns: %TRUE if they are identical, %FALSE otherwise + */ + +gboolean +fs_rtp_header_extension_are_equal (FsRtpHeaderExtension *extension1, + FsRtpHeaderExtension *extension2) +{ + if (extension1 == extension2) + return TRUE; + + if (!extension2 || !extension2) + return FALSE; + + if (extension1->id == extension2->id && + extension1->direction == extension2->direction && + (extension1->uri == extension2->uri || + (extension1->uri && extension2->uri && + !strcmp (extension1->uri, extension2->uri)))) + return TRUE; + else + return FALSE; +} + +/** + * fs_rtp_header_extension_destroy: + * @extension: A RTP header extension to free + * + * Frees the passed #FsRtpHeaderExtension + */ + +void +fs_rtp_header_extension_destroy (FsRtpHeaderExtension *extension) +{ + if (extension) + { + g_free (extension->uri); + g_slice_free (FsRtpHeaderExtension, extension); + } +} + +/** + * fs_rtp_header_extension_list_copy: + * @extensions: a #GList of #FsRtpHeaderExtension + * + * Does a deep copy of a #GList of #FsRtpHeaderExtension + * + * Returns: (element-type FsRtpHeaderExtension) (transfer full): a new + * #GList of #FsRtpHeaderExtension + */ + +GList * +fs_rtp_header_extension_list_copy (GList *extensions) +{ + GQueue copy = G_QUEUE_INIT; + const GList *lp; + + for (lp = extensions; lp; lp = g_list_next (lp)) { + FsRtpHeaderExtension *ext = lp->data; + + g_queue_push_tail (©, fs_rtp_header_extension_copy (ext)); + } + + return copy.head; +} + +/** + * fs_rtp_header_extension_list_destroy: + * @extensions: a #GList of #FsRtpHeaderExtension + * + * Frees the passed #GList of #FsRtpHeaderExtension + */ + +void +fs_rtp_header_extension_list_destroy (GList *extensions) +{ + g_list_foreach (extensions, (GFunc) fs_rtp_header_extension_destroy, NULL); + g_list_free (extensions); +} + +#define RTP_HDREXT_PREFIX "rtp-hdrext:" +#define RTP_HDREXT_AUDIO_PREFIX "audio:" +#define RTP_HDREXT_VIDEO_PREFIX "video:" + +/** + * fs_rtp_header_extension_list_from_keyfile: + * @filename: Name of the #GKeyFile to read the RTP Header Extensions from + * @media_type: The media type for which to get header extensions + * @error: location of a #GError, or NULL if no error occured + * + * Reads the content of a #GKeyFile of the following format into a + * #GList of #FsRtpHeaderExtension structures. + * + * The groups have a format "rtp-hdrext:audio:XXX" or + * "rtp-hdrext:video:XXX" where XXX is a unique string (per media type). + * + * The valid keys are: + * <itemizedlist> + * <listitem>id: a int between in the 1-255 and 4096-4351 ranges</listitem> + * <listitem>uri: a URI describing the RTP Header Extension</listitem> + * <listitem>direction (optional): To only send or receive a RTP Header + * Extension, possible values are "send", "receive", "none" or "both". + * Defaults to "both"</listitem> + * </itemizedlist> + * + * Example: + * |[ + * [rtp-hdrext:audio:a] + * id=1 + * uri=urn:ietf:params:rtp-hdrext:toffset + * + * [rtp-hdrext:audio:abc] + * id=3 + * uri=urn:ietf:params:rtp-hdrext:ntp-64 + * direction=receive + * ]| + * + * Returns: (element-type FsRtpHeaderExtension) (transfer full): a + * #GList of #FsRtpHeaderExtension that must be freed with + * fs_rtp_header_extension_list_destroy() + */ + +GList * +fs_rtp_header_extension_list_from_keyfile (const gchar *filename, + FsMediaType media_type, + GError **error) +{ + GKeyFile *keyfile = NULL; + GList *extensions = NULL; + gchar **groups = NULL; + gsize groups_count = 0; + int i; + + g_return_val_if_fail (filename, NULL); + g_return_val_if_fail (media_type <= FS_MEDIA_TYPE_LAST, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + keyfile = g_key_file_new (); + + if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error)) + goto out; + + groups = g_key_file_get_groups (keyfile, &groups_count); + + if (!groups) + goto out; + + for (i=0; i < groups_count && groups[i]; i++) + { + FsStreamDirection direction = FS_DIRECTION_BOTH; + gint id; + gchar *uri; + GError *gerror = NULL; + gchar *str; + + if (g_ascii_strncasecmp (RTP_HDREXT_PREFIX, groups[i], + strlen (RTP_HDREXT_PREFIX))) + continue; + + if (!g_ascii_strncasecmp (RTP_HDREXT_AUDIO_PREFIX, + groups[i] + strlen (RTP_HDREXT_PREFIX), + strlen (RTP_HDREXT_AUDIO_PREFIX))) + { + if (media_type != FS_MEDIA_TYPE_AUDIO) + continue; + } + else if (!g_ascii_strncasecmp (RTP_HDREXT_VIDEO_PREFIX, + groups[i] + strlen (RTP_HDREXT_PREFIX), + strlen (RTP_HDREXT_VIDEO_PREFIX))) + { + if (media_type != FS_MEDIA_TYPE_VIDEO) + continue; + } + else + { + continue; + } + + id = g_key_file_get_integer (keyfile, groups[i], "id", &gerror); + if (gerror) + { + g_clear_error (&gerror); + continue; + } + + str = g_key_file_get_string (keyfile, groups[i], "direction", &gerror); + if (gerror) + { + GQuark domain = gerror->domain; + gint code = gerror->code; + + g_clear_error (&gerror); + if (domain != G_KEY_FILE_ERROR || code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) + continue; + } + else + { + if (!g_ascii_strcasecmp (str, "none")) + direction = FS_DIRECTION_NONE; + else if (!g_ascii_strcasecmp (str, "send")) + direction = FS_DIRECTION_SEND; + else if (!g_ascii_strcasecmp (str, "recv") || + !g_ascii_strcasecmp (str, "receive")) + direction = FS_DIRECTION_RECV; + g_free (str); + } + + uri = g_key_file_get_string (keyfile, groups[i], "uri", &gerror); + if (gerror) + { + g_clear_error (&gerror); + continue; + } + + extensions = g_list_append (extensions, fs_rtp_header_extension_new (id, + direction, uri)); + g_free (uri); + } + + out: + + g_strfreev (groups); + g_key_file_free (keyfile); + + return extensions; +} |