Codebase list farstream-0.2 / 52a5922
Move the lib out of gst-libs Olivier CrĂȘte 12 years ago
144 changed file(s) with 6993 addition(s) and 7004 deletion(s). Raw diff Collapse all Expand all
2121 transmitters/rawudp/fs-rawudp-marshal.[ch]
2222 transmitters/rawudp/fs-rawudp-marshal.list
2323
24 gst-libs/gst/farstream/fs-marshal.[ch]
25 gst-libs/gst/farstream/fs-marshal.list
26 gst-libs/gst/farstream/fs-enum-types.h
27 gst-libs/gst/farstream/fs-enumtypes.[ch]
24 farstream/fs-marshal.[ch]
25 farstream/fs-marshal.list
26 farstream/fs-enum-types.h
27 farstream/fs-enumtypes.[ch]
2828
2929 docs/libs/farstream-libs-decl-list.txt
3030 docs/libs/farstream-libs-decl-list.txt.bak
66 endif
77
88 SUBDIRS = \
9 gst-libs \
9 farstream \
1010 gst $(SUBDIRS_EXT) \
1111 transmitters \
1212 $(PYTHON_SUBDIR) \
1919 # pkgconfig
2020
2121 DIST_SUBDIRS = \
22 gst-libs \
22 farstream \
2323 gst $(SUBDIRS_EXT) \
2424 transmitters \
2525 python \
22
33 DIE=0
44 package=farstream
5 srcfile=gst-libs/gst/farstream/fs-candidate.c
5 srcfile=farstream/fs-candidate.c
66
77 # Make sure we have common
88 if test ! -f common/gst-autogen.sh;
2020 AS_NANO(FS_CVS="no", FS_CVS="yes")
2121
2222 dnl can autoconf find the source ?
23 AC_CONFIG_SRCDIR([gst-libs/gst/farstream/fs-candidate.c])
23 AC_CONFIG_SRCDIR([farstream/fs-conference.c])
2424
2525 dnl define the output header for config
2626 AM_CONFIG_HEADER([config.h])
306306 dnl FS_INTERNAL_CFLAGS
307307 dnl prefer internal headers to already installed ones
308308 dnl also add builddir include for enumtypes and marshal
309 FS_INTERNAL_CFLAGS="-I\$(top_srcdir)/gst-libs -I\$(top_builddir)/gst-libs"
309 FS_INTERNAL_CFLAGS="-I\$(top_srcdir) -I\$(top_builddir)"
310310 AC_SUBST(FS_INTERNAL_CFLAGS)
311311
312312 dnl FIXME: do we want to rename to GST_ALL_* ?
401401 gst/funnel/Makefile
402402 gst/rtcpfilter/Makefile
403403 gst/videoanyrate/Makefile
404 gst-libs/Makefile
405 gst-libs/gst/Makefile
406 gst-libs/gst/farstream/Makefile
404 farstream/Makefile
407405 transmitters/Makefile
408406 transmitters/rawudp/Makefile
409407 transmitters/multicast/Makefile
4545 # this is useful ;)
4646
4747 SCANOBJ_DEPS = \
48 $(top_builddir)/gst-libs/gst/farstream/libfarstream-@GST_MAJORMINOR@.la
48 $(top_builddir)/farstream/libfarstream-@GST_MAJORMINOR@.la
4949
5050 # Header files to ignore when scanning.
5151 IGNORE_HFILES = fs-marshal.h fs-enumtypes.h fs-private.h
6363 # contains GtkObjects/GObjects and you want to document signals and properties.
6464 GTKDOC_CFLAGS = $(FS_INTERNAL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS)
6565 GTKDOC_LIBS = -static \
66 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
66 $(top_builddir)/farstream/libfarstream-0.10.la \
6767 $(GST_BASE_LIBS) \
6868 $(GCOV_LIBS)
6969
00 <SECTION>
11 <FILE>fs-participant</FILE>
22 <TITLE>FsParticipant</TITLE>
3 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
3 <INCLUDE>farstream/fs-conference.h</INCLUDE>
44 FsParticipant
55 FsParticipantClass
66 FS_PARTICIPANT_DATA_LOCK
2020 <SECTION>
2121 <FILE>fs-stream</FILE>
2222 <TITLE>FsStream</TITLE>
23 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
23 <INCLUDE>farstream/fs-conference.h</INCLUDE>
2424 FsStream
2525 FsStreamClass
2626 FsStreamDirection
5151 FsDTMFEvent
5252 FsDTMFMethod
5353 <TITLE>FsSession</TITLE>
54 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
54 <INCLUDE>farstream/fs-conference.h</INCLUDE>
5555 FsSession
5656 FsSessionClass
5757 fs_session_new_stream
8383 <SECTION>
8484 <FILE>fs-conference</FILE>
8585 <TITLE>FsConference</TITLE>
86 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
86 <INCLUDE>farstream/fs-conference.h</INCLUDE>
8787 FsConference
8888 fs_conference_new_session
8989 fs_conference_new_participant
103103 <SECTION>
104104 <FILE>fs-candidate</FILE>
105105 <TITLE>FsCandidate</TITLE>
106 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
106 <INCLUDE>farstream/fs-conference.h</INCLUDE>
107107 FsCandidate
108108 FsCandidateType
109109 FsNetworkProtocol
123123 <SECTION>
124124 <FILE>fs-codec</FILE>
125125 <TITLE>FsCodec</TITLE>
126 <INCLUDE>gst/farstream/fs-conference.h</INCLUDE>
126 <INCLUDE>farstream/fs-conference.h</INCLUDE>
127127 FsCodec
128128 FsMediaType
129129 FsCodecParameter
158158 <SECTION>
159159 <FILE>fs-transmitter</FILE>
160160 <TITLE>FsTransmitter</TITLE>
161 <INCLUDE>gst/farstream/fs-transmitter.h</INCLUDE>
161 <INCLUDE>farstream/fs-transmitter.h</INCLUDE>
162162 FsTransmitter
163163 FsTransmitterClass
164164 fs_transmitter_new
182182 <SECTION>
183183 <FILE>fs-stream-transmitter</FILE>
184184 <TITLE>FsStreamTransmitter</TITLE>
185 <INCLUDE>gst/farstream/fs-transmitter.h</INCLUDE>
185 <INCLUDE>farstream/fs-transmitter.h</INCLUDE>
186186 FsStreamTransmitter
187187 FsStreamTransmitterClass
188188 fs_stream_transmitter_add_remote_candidates
205205 <SECTION>
206206 <FILE>fs-plugin</FILE>
207207 <TITLE>FsPlugin</TITLE>
208 <INCLUDE>gst/farstream/fs-plugin.h</INCLUDE>
208 <INCLUDE>farstream/fs-plugin.h</INCLUDE>
209209 FsPlugin
210210 fs_plugin_create_valist
211211 fs_plugin_create
226226 <SECTION>
227227 <FILE>fs-element-added-notifier</FILE>
228228 <TITLE>FsElementAddedNotifier</TITLE>
229 <INCLUDE>gst/farstream/fs-element-added-notifier.h</INCLUDE>
229 <INCLUDE>farstream/fs-element-added-notifier.h</INCLUDE>
230230 FsElementAddedNotifier
231231 fs_element_added_notifier_new
232232 fs_element_added_notifier_add
248248 <SECTION>
249249 <FILE>fs-rtp</FILE>
250250 <TITLE>RTP Specific types</TITLE>
251 <INCLUDE>gst/farstream/fs-rtp.h</INCLUDE>
251 <INCLUDE>farstream/fs-rtp.h</INCLUDE>
252252 FsRtpHeaderExtension
253253 fs_rtp_header_extension_new
254254 fs_rtp_header_extension_copy
269269 <SECTION>
270270 <FILE>fs-utils</FILE>
271271 <TITLE>Utility functions</TITLE>
272 <INCLUDE>gst/farstream/fs-utils.h</INCLUDE>
272 <INCLUDE>farstream/fs-utils.h</INCLUDE>
273273 fs_utils_set_bitrate
274274 fs_utils_get_default_codec_preferences
275275 fs_utils_get_default_element_properties
55 % - change output file name from gstreamer-(whatever).html to (whatever).html
66 % - document properties and signals
77
8 #include "../../gst-libs/gst/farstream/fs-participant.h"
9 #include "../../gst-libs/gst/farstream/fs-session.h"
10 #include "../../gst-libs/gst/farstream/fs-stream.h"
11 #include "../../gst-libs/gst/farstream/fs-conference.h"
12 #include "../../gst-libs/gst/farstream/fs-transmitter.h"
13 #include "../../gst-libs/gst/farstream/fs-stream-transmitter.h"
14 #include "../../gst-libs/gst/farstream/fs-element-added-notifier.h"
8 #include "../../farstream/fs-participant.h"
9 #include "../../farstream/fs-session.h"
10 #include "../../farstream/fs-stream.h"
11 #include "../../farstream/fs-conference.h"
12 #include "../../farstream/fs-transmitter.h"
13 #include "../../farstream/fs-stream-transmitter.h"
14 #include "../../farstream/fs-element-added-notifier.h"
1515
1616 fs_participant_get_type
1717 fs_session_get_type
125125 # contains GtkObjects/GObjects and you want to document signals and properties.
126126 GTKDOC_CFLAGS = $(GST_BASE_CFLAGS) -I$(top_builddir) -I$(top_builddir)/gst-libs
127127 GTKDOC_LIBS = \
128 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
128 $(top_builddir)/farstream/libfarstream-0.10.la \
129129 $(top_builddir)/gst/fsrtpconference/libfsrtpconference_doc.la \
130130 $(top_builddir)/gst/fsrawconference/libfsrawconference_doc.la \
131131 $(top_builddir)/gst/fsmsnconference/libfsmsnconference_doc.la \
0 #include <gst/farstream/fs-transmitter.h>
0 #include <farstream/fs-transmitter.h>
99 $(CFLAGS)
1010
1111 LDADD = \
12 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
12 $(top_builddir)/farstream/libfarstream-0.10.la \
1313 $(GST_LIBS)
1414
1515
3333 #include <gio/gunixinputstream.h>
3434 #include <gst/gst.h>
3535
36 #include <gst/farstream/fs-conference.h>
36 #include <farstream/fs-conference.h>
3737
3838 #define DEFAULT_AUDIOSRC "audiotestsrc is-live=1 ! audio/x-raw-int, rate=8000 ! identity"
3939 #define DEFAULT_AUDIOSINK "alsasink sync=false async=false"
2929
3030 #include <glib.h>
3131 #include <gst/gst.h>
32 #include <gst/farstream/fs-conference.h>
32 #include <farstream/fs-conference.h>
3333
3434 #define DEFAULT_AUDIOSRC "alsasrc"
3535 #define DEFAULT_AUDIOSINK "audioconvert ! audioresample ! audioconvert ! alsasink"
0 libfarstreamincludedir = $(includedir)/farstream-@FS_MAJORMINOR@/farstream
1
2 libfarstreaminclude_HEADERS = \
3 fs-candidate.h \
4 fs-codec.h \
5 fs-participant.h \
6 fs-session.h \
7 fs-stream.h \
8 fs-conference.h \
9 fs-transmitter.h \
10 fs-stream-transmitter.h \
11 fs-plugin.h \
12 fs-element-added-notifier.h \
13 fs-utils.h \
14 fs-rtp.h
15
16 nodist_libfarstreaminclude_HEADERS = \
17 fs-enumtypes.h
18
19
20 lib_LTLIBRARIES = libfarstream-@GST_MAJORMINOR@.la
21
22 BUILT_SOURCES = \
23 $(nodist_libfarstream_@GST_MAJORMINOR@_la_SOURCES) \
24 $(nodist_libfarstreaminclude_HEADERS)
25
26 CLEANFILES = $(BUILT_SOURCES) fs-marshal.list
27
28 libfarstream_@GST_MAJORMINOR@_la_SOURCES = \
29 fs-candidate.c \
30 fs-codec.c \
31 fs-participant.c \
32 fs-session.c \
33 fs-stream.c \
34 fs-conference.c \
35 fs-transmitter.c \
36 fs-stream-transmitter.c \
37 fs-plugin.c \
38 fs-element-added-notifier.c \
39 fs-utils.c \
40 fs-rtp.c \
41 fs-private.h
42
43 nodist_libfarstream_@GST_MAJORMINOR@_la_SOURCES = \
44 fs-marshal.c \
45 fs-marshal.h \
46 fs-enumtypes.c
47
48
49 fs-marshal.list: $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) Makefile.am
50 $(AM_V_GEN) ( cd $(srcdir) && \
51 sed -n -e 's/.*_fs_marshal_\([[:upper:][:digit:]]*__[[:upper:][:digit:]_]*\).*/\1/p' \
52 $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) ) \
53 | sed -e 's/__/:/' -e 'y/_/,/' | sort -u > $@.tmp
54 @if cmp -s $@.tmp $@; then \
55 rm $@.tmp; \
56 touch $@; \
57 else \
58 mv $@.tmp $@; \
59 fi
60
61 libfarstream_@GST_MAJORMINOR@_la_CFLAGS = \
62 $(FS_INTERNAL_CFLAGS) $(FS_CFLAGS) \
63 $(GST_PLUGINS_BASE_CFLAGS) \
64 $(GST_BASE_CFLAGS) \
65 $(GST_CFLAGS)
66 libfarstream_@GST_MAJORMINOR@_la_LIBADD = \
67 $(GST_BASE_LIBS) \
68 $(GST_LIBS)
69 libfarstream_@GST_MAJORMINOR@_la_LDFLAGS = \
70 $(FS_LIB_LDFLAGS) \
71 $(FS_ALL_LDFLAGS) \
72 $(FS_LT_LDFLAGS)
73
74
75 public_headers = fs-candidate.h \
76 fs-codec.h \
77 fs-participant.h \
78 fs-session.h \
79 fs-stream.h \
80 fs-conference.h \
81 fs-utils.h
82
83 glib_enum_headers=$(public_headers)
84 glib_enum_define=FS
85 glib_gen_prefix=_fs
86 glib_gen_basename=fs
87
88 include $(top_srcdir)/common-modified/gst-glib-gen.mak
89
90 if HAVE_INTROSPECTION
91 include $(INTROSPECTION_MAKEFILE)
92 introspection_sources = \
93 $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) \
94 $(nodist_libfarstreaminclude_HEADERS) \
95 $(libfarstreaminclude_HEADERS)
96
97 INTROSPECTION_GIRS = Farstream-@FS_MAJORMINOR@.gir
98 Farstream_0_1_gir_NAMESPACE = Farstream
99 Farstream_0_1_gir_VERSION = @FS_MAJORMINOR@
100 Farstream_0_1_gir_LIBS = libfarstream-@GST_MAJORMINOR@.la
101 Farstream_0_1_gir_FILES = $(introspection_sources)
102 Farstream_0_1_gir_INCLUDES = GObject-2.0 Gst-0.10
103 Farstream_0_1_gir_CFLAGS = $(FS_INTERNAL_CFLAGS)
104 Farstream_0_1_gir_SCANNERFLAGS = --identifier-prefix=fs_ --identifier-prefix=Fs
105
106 girdir = $(datadir)/gir-1.0
107 dist_gir_DATA = Farstream-@FS_MAJORMINOR@.gir
108 typelibdir = $(libdir)/girepository-1.0
109 typelib_DATA = Farstream-@FS_MAJORMINOR@.typelib
110 CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
111 endif
0 /*
1 * Farstream - Farstream Candidate
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-candidate.c - A Farstream candidate
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "fs-candidate.h"
29
30 /**
31 * SECTION:fs-candidate
32 * @short_description: Structure describing a transport candidate.
33 *
34 * An FsCandidate is a way to exchange candidate information between the client
35 * and Farstream. This description is compatible with ICE-13. It can also be a
36 * multicast address. Candidates are linked to streams. The information
37 * specified in this structure is usually representative of the codec
38 * information exchanged in the signaling.
39 */
40
41 GType
42 fs_candidate_get_type (void)
43 {
44 static GType candidate_type = 0;
45 if (candidate_type == 0)
46 {
47 candidate_type = g_boxed_type_register_static (
48 "FsCandidate",
49 (GBoxedCopyFunc)fs_candidate_copy,
50 (GBoxedFreeFunc)fs_candidate_destroy);
51 }
52
53 return candidate_type;
54 }
55
56 GType
57 fs_candidate_list_get_type (void)
58 {
59 static GType candidate_list_type = 0;
60 if (candidate_list_type == 0)
61 {
62 candidate_list_type = g_boxed_type_register_static (
63 "FsCandidateList",
64 (GBoxedCopyFunc)fs_candidate_list_copy,
65 (GBoxedFreeFunc)fs_candidate_list_destroy);
66 }
67
68 return candidate_list_type;
69 }
70
71 /**
72 * fs_candidate_destroy: (skip):
73 * @cand: a #FsCandidate to delete
74 *
75 * Frees a #FsCandidate and all its contents
76 */
77 void
78 fs_candidate_destroy (FsCandidate * cand)
79 {
80 if (cand == NULL)
81 return;
82
83 g_free ((gchar *) cand->foundation);
84 g_free ((gchar *) cand->ip);
85 g_free ((gchar *) cand->base_ip);
86 g_free ((gchar *) cand->username);
87 g_free ((gchar *) cand->password);
88
89 g_slice_free (FsCandidate, cand);
90 }
91
92 /**
93 * fs_candidate_copy:
94 * @cand: a #FsCandidate to copy
95 *
96 * Copies a #FsCandidate and its contents.
97 *
98 * Returns: a new #FsCandidate
99 */
100 FsCandidate *
101 fs_candidate_copy (const FsCandidate * cand)
102 {
103 FsCandidate *copy = g_slice_new0 (FsCandidate);
104
105 if (cand == NULL)
106 return NULL;
107
108 copy->component_id = cand->component_id;
109 copy->port = cand->port;
110 copy->base_port = cand->base_port;
111 copy->proto = cand->proto;
112 copy->priority = cand->priority;
113 copy->type = cand->type;
114 copy->ttl = cand->ttl;
115
116 copy->foundation = g_strdup (cand->foundation);
117 copy->ip = g_strdup (cand->ip);
118 copy->base_ip = g_strdup (cand->base_ip);
119 copy->username = g_strdup (cand->username);
120 copy->password = g_strdup (cand->password);
121
122 return copy;
123 }
124
125 /**
126 * fs_candidate_list_destroy: (skip):
127 * @candidate_list: A GList of #FsCandidate
128 *
129 * Deletes a GList of #FsCandidate and its contents
130 */
131 void
132 fs_candidate_list_destroy (GList *candidate_list)
133 {
134 GList *lp;
135 FsCandidate *cand;
136
137 for (lp = candidate_list; lp; lp = g_list_next (lp)) {
138 cand = (FsCandidate *) lp->data;
139 fs_candidate_destroy (cand);
140 lp->data = NULL;
141 }
142 g_list_free (candidate_list);
143 }
144
145 /**
146 * fs_candidate_list_copy:
147 * @candidate_list: (element-type FsCodec): A GList of #FsCandidate
148 *
149 * Copies a GList of #FsCandidate and its contents
150 *
151 * Returns: (element-type FsCodec) (transfer full): a new GList of #FsCandidate
152 */
153 GList *
154 fs_candidate_list_copy (const GList *candidate_list)
155 {
156 GQueue copy = G_QUEUE_INIT;
157 const GList *lp;
158
159 for (lp = candidate_list; lp; lp = g_list_next (lp)) {
160 FsCandidate *cand = lp->data;
161
162 g_queue_push_tail (&copy, fs_candidate_copy (cand));
163 }
164
165 return copy.head;
166 }
167
168 /**
169 * fs_candidate_new:
170 * @foundation: The foundation of the candidate
171 * @component_id: The component this candidate is for
172 * @type: The type of candidate
173 * @proto: The protocol this component is for
174 * @ip: The IP address of this component (can be NULL for local candidate to
175 * mean any address)
176 * @port: the UDP/TCP port
177 *
178 * Allocates a new #FsCandidate, the rest of the fields can be optionally
179 * filled manually.
180 *
181 * Returns: a newly-allocated #FsCandidate
182 */
183
184 FsCandidate *
185 fs_candidate_new (
186 const gchar *foundation,
187 guint component_id,
188 FsCandidateType type,
189 FsNetworkProtocol proto,
190 const gchar *ip,
191 guint port)
192 {
193 FsCandidate *candidate = g_slice_new0 (FsCandidate);
194
195 candidate->foundation = g_strdup (foundation);
196 candidate->component_id = component_id;
197 candidate->type = type;
198 candidate->proto = proto;
199 candidate->ip = g_strdup (ip);
200 candidate->port = port;
201
202 return candidate;
203 }
0 /*
1 * Farstream - Farstream Candidate
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-candidate.h - A Farstream candidate
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_CANDIDATE_H__
25 #define __FS_CANDIDATE_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 G_BEGIN_DECLS
31
32 #define FS_TYPE_CANDIDATE \
33 (fs_candidate_get_type ())
34
35
36 #define FS_TYPE_CANDIDATE_LIST \
37 (fs_candidate_list_get_type ())
38
39 /**
40 * FsCandidateType:
41 * @FS_CANDIDATE_TYPE_HOST: A host candidate (local)
42 * @FS_CANDIDATE_TYPE_SRFLX: A server reflexive candidate.
43 * @FS_CANDIDATE_TYPE_PRFLX: A peer reflexive candidate
44 * @FS_CANDIDATE_TYPE_RELAY: An relay candidate
45 * @FS_CANDIDATE_TYPE_MULTICAST: A multicast address
46 *
47 * An enum for the type of candidate used/reported
48 */
49 typedef enum _FsCandidateType
50 {
51 FS_CANDIDATE_TYPE_HOST,
52 FS_CANDIDATE_TYPE_SRFLX,
53 FS_CANDIDATE_TYPE_PRFLX,
54 FS_CANDIDATE_TYPE_RELAY, /* An external stream relay */
55 FS_CANDIDATE_TYPE_MULTICAST
56 } FsCandidateType;
57
58 /**
59 * FsNetworkProtocol:
60 * @FS_NETWORK_PROTOCOL_UDP: A UDP based protocol
61 * @FS_NETWORK_PROTOCOL_TCP: A TCP based protocol
62 *
63 * An enum for the base IP protocol
64 */
65 typedef enum _FsNetworkProtocol
66 {
67 FS_NETWORK_PROTOCOL_UDP,
68 FS_NETWORK_PROTOCOL_TCP
69 } FsNetworkProtocol;
70
71 /**
72 * FsComponentType:
73 * @FS_COMPONENT_NONE: Use this when specifying a component is innapropriate
74 * @FS_COMPONENT_RTP: This component is for RTP data
75 * @FS_COMPONENT_RTCP: This component is for RTCP control
76 *
77 * This enum contains the component IDs defined in ICE-19
78 */
79
80 typedef enum _FsComponentType
81 {
82 FS_COMPONENT_NONE = 0,
83 FS_COMPONENT_RTP = 1,
84 FS_COMPONENT_RTCP = 2
85 } FsComponentType;
86
87
88 typedef struct _FsCandidate FsCandidate;
89
90 /**
91 * FsCandidate:
92 * @foundation: a string representing the foundation of this candidate (maximum 32 chars)
93 * @component_id: value between 1 and 256 indicating which component this candidate represents (1 is RTP, 2 is RTCP, #FsComponentType can be used here)
94 * @ip: IP in dotted format
95 * @port: Port to use
96 * @base_ip: IP of base in dotted format as defined in ICE-19.
97 * @base_port: Port of base as defined in ICE-19.
98 * @proto: #FsNetworkProtocol for ip protocol to use as candidate
99 * @priority: Value between 0 and (2^31 - 1) representing the priority
100 * @type: The #FsCandidateType of the candidate
101 * @username: Username to use to connect to client if necessary,
102 * NULL otherwise
103 * @password: Username to use to connect to client if necessary,
104 * NULL otherwise
105 * @ttl: The TTL used when sending Multicast packet (0 = auto)
106 *
107 * Struct to hold information about ICE-19 compliant candidates
108 */
109 struct _FsCandidate
110 {
111 gchar *foundation;
112 guint component_id;
113 const gchar *ip;
114 guint16 port;
115 const gchar *base_ip;
116 guint16 base_port;
117 FsNetworkProtocol proto;
118 guint32 priority;
119 FsCandidateType type;
120 const gchar *username;
121 const gchar *password;
122 guint ttl;
123 };
124
125 GType fs_candidate_get_type (void);
126 GType fs_candidate_list_get_type (void);
127
128 void fs_candidate_destroy (FsCandidate *cand);
129
130 FsCandidate *fs_candidate_copy (const FsCandidate *cand);
131
132 void fs_candidate_list_destroy (GList *candidate_list);
133
134 GList *fs_candidate_list_copy (const GList *candidate_list);
135
136 FsCandidate * fs_candidate_new (
137 const gchar *foundation,
138 guint component_id,
139 FsCandidateType type,
140 FsNetworkProtocol proto,
141 const gchar *ip,
142 guint port);
143
144 G_END_DECLS
145 #endif /* __FS_CANDIDATE_H__ */
0 /*
1 * Farstream - Farstream Codec
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * Copyright 2005 Collabora Ltd.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 *
10 * fs-codec.c - A Farstream codec
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "fs-codec.h"
32
33 #include <string.h>
34
35 #include "fs-private.h"
36
37 #define GST_CAT_DEFAULT fs_conference_debug
38
39 /**
40 * SECTION:fs-codec
41 * @short_description: Structure representing a media codec
42 *
43 * An #FsCodec is a way to exchange codec information between the client and
44 * Farstream. The information specified in this structure is usually
45 * representative of the codec information exchanged in the signaling.
46 *
47 */
48
49 /* TODO Make a fs_codec_new() function since there is a _destroy() */
50
51 GType
52 fs_codec_get_type (void)
53 {
54 static GType codec_type = 0;
55 if (codec_type == 0)
56 {
57 codec_type = g_boxed_type_register_static (
58 "FsCodec",
59 (GBoxedCopyFunc)fs_codec_copy,
60 (GBoxedFreeFunc)fs_codec_destroy);
61 }
62
63 return codec_type;
64 }
65
66 GType
67 fs_codec_list_get_type (void)
68 {
69 static GType codec_list_type = 0;
70 if (codec_list_type == 0)
71 {
72 codec_list_type = g_boxed_type_register_static (
73 "FsCodecGList",
74 (GBoxedCopyFunc)fs_codec_list_copy,
75 (GBoxedFreeFunc)fs_codec_list_destroy);
76 }
77
78 return codec_list_type;
79 }
80
81 G_DEFINE_BOXED_TYPE (FsCodecParameter,
82 fs_codec_parameter,
83 fs_codec_parameter_copy,
84 fs_codec_parameter_free);
85
86
87 G_DEFINE_BOXED_TYPE (FsFeedbackParameter,
88 fs_feedback_parameter,
89 fs_feedback_parameter_copy,
90 fs_feedback_parameter_free);
91
92 /**
93 * fs_codec_new:
94 * @id: codec identifier, if RTP this should be based on IETF RTP payload types
95 * @encoding_name: Name of media type this encodes
96 * @media_type: #FsMediaType for type of codec
97 * @clock_rate: The clock rate this codec encodes at, if applicable
98 *
99 * Allocates and initializes a #FsCodec structure
100 *
101 * Returns: A newly allocated #FsCodec
102 */
103 FsCodec *
104 fs_codec_new (int id, const char *encoding_name,
105 FsMediaType media_type, guint clock_rate)
106 {
107 FsCodec *codec = g_slice_new0 (FsCodec);
108
109 codec->id = id;
110 codec->encoding_name = g_strdup (encoding_name);
111 codec->media_type = media_type;
112 codec->clock_rate = clock_rate;
113 codec->minimum_reporting_interval = G_MAXUINT;
114
115 return codec;
116 }
117
118 void
119 fs_codec_parameter_free (FsCodecParameter *param)
120
121 {
122 g_free (param->name);
123 g_free (param->value);
124 g_slice_free (FsCodecParameter, param);
125 }
126
127
128 void
129 fs_feedback_parameter_free (FsFeedbackParameter *param)
130 {
131 g_free (param->type);
132 g_free (param->subtype);
133 g_free (param->extra_params);
134 g_slice_free (FsFeedbackParameter, param);
135 }
136
137 /**
138 * fs_codec_destroy: (skip):
139 * @codec: #FsCodec structure to free
140 *
141 * Deletes a #FsCodec structure and all its data. Is a no-op on %NULL codec
142 */
143 void
144 fs_codec_destroy (FsCodec * codec)
145 {
146 if (codec == NULL)
147 return;
148
149 g_free (codec->encoding_name);
150
151 g_list_foreach (codec->optional_params, (GFunc) fs_codec_parameter_free,
152 NULL);
153 g_list_free (codec->optional_params);
154
155 g_list_foreach (codec->feedback_params,
156 (GFunc) fs_feedback_parameter_free, NULL);
157 g_list_free (codec->feedback_params);
158
159 g_slice_free (FsCodec, codec);
160 }
161
162 /**
163 * fs_codec_copy:
164 * @codec: codec to copy
165 *
166 * Copies a #FsCodec structure.
167 *
168 * Returns: a copy of the codec
169 */
170 FsCodec *
171 fs_codec_copy (const FsCodec * codec)
172 {
173 FsCodec *copy = NULL;
174 GList *lp;
175 GQueue list_copy = G_QUEUE_INIT;
176
177 if (codec == NULL)
178 return NULL;
179
180 copy = fs_codec_new (codec->id, codec->encoding_name, codec->media_type,
181 codec->clock_rate);
182
183 copy->channels = codec->channels;
184 copy->minimum_reporting_interval = codec->minimum_reporting_interval;
185
186 copy->encoding_name = g_strdup (codec->encoding_name);
187
188 for (lp = codec->optional_params; lp; lp = g_list_next (lp))
189 {
190 FsCodecParameter *param_copy;
191 FsCodecParameter *param = lp->data;;
192
193 param_copy = g_slice_new (FsCodecParameter);
194 param_copy->name = g_strdup (param->name);
195 param_copy->value = g_strdup (param->value);
196
197 g_queue_push_tail (&list_copy, param_copy);
198 }
199 copy->optional_params = list_copy.head;
200
201 g_queue_init (&list_copy);
202 for (lp = codec->feedback_params; lp; lp = g_list_next (lp))
203 {
204 FsFeedbackParameter *param_copy;
205 FsFeedbackParameter *param = lp->data;;
206
207 param_copy = g_slice_new (FsFeedbackParameter);
208 param_copy->type = g_strdup (param->type);
209 param_copy->subtype = g_strdup (param->subtype);
210 param_copy->extra_params = g_strdup (param->extra_params);
211
212 g_queue_push_tail (&list_copy, param_copy);
213 }
214 copy->feedback_params = list_copy.head;
215
216 return copy;
217 }
218
219 /**
220 * fs_codec_list_destroy: (skip):
221 * @codec_list: a GList of #FsCodec to delete
222 *
223 * Deletes a list of #FsCodec structures and the list itself.
224 * Does nothing on %NULL lists.
225 */
226 void
227 fs_codec_list_destroy (GList *codec_list)
228 {
229 GList *lp;
230 FsCodec *codec;
231
232 for (lp = codec_list; lp; lp = g_list_next (lp)) {
233 codec = (FsCodec *) lp->data;
234 fs_codec_destroy (codec);
235 lp->data = NULL;
236 }
237 g_list_free (codec_list);
238 }
239
240 /**
241 * fs_codec_list_copy:
242 * @codec_list: a GList of #FsCodec to copy
243 *
244 * Copies a list of #FsCodec structures.
245 *
246 * Returns: (element-type FsCodec) (transfer full): The new list.
247 */
248 GList *
249 fs_codec_list_copy (const GList *codec_list)
250 {
251 GQueue copy = G_QUEUE_INIT;
252 const GList *lp;
253
254 for (lp = codec_list; lp; lp = g_list_next (lp)) {
255 FsCodec *codec = (FsCodec *) lp->data;
256
257 g_queue_push_tail (&copy, fs_codec_copy (codec));
258 }
259
260 return copy.head;
261 }
262
263 /**
264 * fs_codec_list_from_keyfile
265 * @filename: Name of the #GKeyFile to read the codecs parameters from
266 * @error: location of a #GError, or NULL if no error occured
267 *
268 * Reads the content of a #GKeyFile of the following format into
269 * a #GList of #FsCodec structures.
270 *
271 *
272 * Example:
273 * |[
274 * [audio/codec1]
275 * clock-rate=8000
276 *
277 * [audio/codec1:1]
278 * clock-rate=16000
279 *
280 * [audio/codec2]
281 * one_param=QCIF
282 * another_param=WOW
283 *
284 * [video/codec3]
285 * wierd_param=42
286 * feedback:nack/pli=1
287 * feedback:tfrc=
288 * ]|
289 *
290 * Return value: (element-type FsCodec) (transfer full):
291 * The #GList of #FsCodec or %NULL if the keyfile was empty or an error occured.
292 */
293 GList *
294 fs_codec_list_from_keyfile (const gchar *filename, GError **error)
295 {
296 GKeyFile *keyfile = NULL;
297 GList *codecs = NULL;
298 GError *gerror = NULL;
299 gchar **groups = NULL;
300 gsize groups_count = 0;
301 int i;
302
303 g_return_val_if_fail (filename, NULL);
304 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
305
306 keyfile = g_key_file_new ();
307
308 if (!g_key_file_load_from_file (keyfile, filename,
309 G_KEY_FILE_NONE, error)) {
310 goto out;
311 }
312
313 groups = g_key_file_get_groups (keyfile, &groups_count);
314
315 if (!groups)
316 goto out;
317
318 for (i=0; i < groups_count && groups[i]; i++) {
319 FsCodec *codec;
320 gchar **keys = NULL;
321 gsize keys_count;
322 int j;
323 gchar *encoding_name = NULL;
324 gchar *next_tok = NULL;
325 FsMediaType media_type;
326
327 keys = g_key_file_get_keys (keyfile, groups[i], &keys_count, &gerror);
328
329 if (!keys || gerror) {
330 if (gerror)
331 GST_WARNING ("Unable to read parameters for %s: %s\n",
332 groups[i], gerror->message);
333 else
334 GST_WARNING ("Unknown errors while reading parameters for %s",
335 groups[i]);
336
337 g_clear_error (&gerror);
338
339 goto next_codec;
340 }
341
342 next_tok = strchr (groups[i], '/');
343 if (!next_tok)
344 {
345 GST_WARNING ("Invalid codec name: %s", groups[i]);
346 goto next_codec;
347 }
348
349 if ((next_tok - groups[i]) == 5 /* strlen ("audio") */ &&
350 !g_ascii_strncasecmp ("audio", groups[i], 5))
351 {
352 media_type = FS_MEDIA_TYPE_AUDIO;
353 }
354 else if ((next_tok - groups[i]) == 5 /* strlen ("video") */ &&
355 !g_ascii_strncasecmp ("video", groups[i], 5))
356 {
357 media_type = FS_MEDIA_TYPE_VIDEO;
358 }
359 else
360 {
361 GST_WARNING ("Invalid media type in codec name name %s", groups[i]);
362 goto next_codec;
363 }
364
365 encoding_name = next_tok + 1;
366
367 next_tok = strchr (encoding_name, ':');
368
369 if (encoding_name[0] == 0 || next_tok - encoding_name == 1)
370 goto next_codec;
371
372 if (next_tok)
373 encoding_name = g_strndup (encoding_name,
374 next_tok - encoding_name);
375 else
376 encoding_name = g_strdup (encoding_name);
377
378 codec = fs_codec_new (FS_CODEC_ID_ANY, encoding_name, media_type, 0);
379
380 g_free (encoding_name);
381
382 for (j = 0; j < keys_count && keys[j]; j++) {
383 if (!g_ascii_strcasecmp ("clock-rate", keys[j])) {
384 codec->clock_rate = g_key_file_get_integer (keyfile, groups[i], keys[j],
385 &gerror);
386 if (gerror) {
387 codec->clock_rate = 0;
388 goto keyerror;
389 }
390
391 } else if (!g_ascii_strcasecmp ("id", keys[j])) {
392 codec->id = g_key_file_get_integer (keyfile, groups[i], keys[j],
393 &gerror);
394 if (gerror) {
395 codec->id = FS_CODEC_ID_ANY;
396 goto keyerror;
397 }
398
399 if (codec->id < 0)
400 codec->id = FS_CODEC_ID_DISABLE;
401
402 } else if (!g_ascii_strcasecmp ("channels", keys[j])) {
403 codec->channels = g_key_file_get_integer (keyfile, groups[i], keys[j],
404 &gerror);
405 if (gerror) {
406 codec->channels = 0;
407 goto keyerror;
408 }
409 } else if (!g_ascii_strcasecmp ("trr-int", keys[j])) {
410 codec->minimum_reporting_interval =
411 g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror);
412 if (gerror) {
413 codec->minimum_reporting_interval = G_MAXUINT;
414 goto keyerror;
415 }
416 } else if (g_str_has_prefix (keys[j], "feedback:")) {
417 gchar *type = keys[j] + strlen ("feedback:");
418 gchar *subtype = strchr (type, '/');
419 gchar *extra_params;
420
421 extra_params = g_key_file_get_string (keyfile, groups[i], keys[j],
422 &gerror);
423 if (gerror)
424 goto keyerror;
425
426 /* Replace / with \0 and point to name (the next char) */
427 if (subtype)
428 {
429 *subtype=0;
430 subtype++;
431 }
432 else
433 {
434 subtype = "";
435 }
436
437 fs_codec_add_feedback_parameter (codec, type, subtype,
438 extra_params);
439 g_free (extra_params);
440 } else {
441 FsCodecParameter *param = g_slice_new (FsCodecParameter);
442
443 param->name = g_strdup (keys[j]);
444 param->value = g_key_file_get_string (keyfile, groups[i], keys[j],
445 &gerror);
446 if (gerror) {
447 fs_codec_parameter_free (param);
448 goto keyerror;
449 }
450
451 if (!param->name || !param->value)
452 fs_codec_parameter_free (param);
453 else
454 codec->optional_params = g_list_append (codec->optional_params,
455 param);
456 }
457 continue;
458 keyerror:
459 GST_WARNING ("Error reading key %s codec %s: %s", keys[j], groups[i],
460 gerror->message);
461 g_clear_error (&gerror);
462
463 }
464
465 codecs = g_list_append (codecs, codec);
466
467 next_codec:
468 g_strfreev (keys);
469 }
470
471
472 out:
473
474 g_strfreev (groups);
475 g_key_file_free (keyfile);
476
477 return codecs;
478 }
479
480 /**
481 * fs_media_type_to_string
482 * @media_type: A media type
483 *
484 * Gives a user-printable string representing the media type
485 *
486 * Return value: a static string representing the media type
487 */
488
489 const gchar *
490 fs_media_type_to_string (FsMediaType media_type)
491 {
492 if (media_type == FS_MEDIA_TYPE_AUDIO) {
493 return "audio";
494 } else if (media_type == FS_MEDIA_TYPE_VIDEO) {
495 return "video";
496 } else {
497 return NULL;
498 }
499 }
500
501 /**
502 * fs_codec_to_string
503 * @codec: A farstream codec
504 *
505 * Returns a newly-allocated string representing the codec
506 *
507 * Return value: the newly-allocated string
508 */
509 gchar *
510 fs_codec_to_string (const FsCodec *codec)
511 {
512 GString *string = NULL;
513 GList *item;
514 gchar *charstring;
515
516 if (codec == NULL)
517 return g_strdup ("(NULL)");
518
519 string = g_string_new ("");
520
521 g_string_printf (string, "%d: %s %s clock:%d channels:%d",
522 codec->id, fs_media_type_to_string (codec->media_type),
523 codec->encoding_name, codec->clock_rate, codec->channels);
524
525 if (codec->minimum_reporting_interval != G_MAXUINT)
526 g_string_append_printf (string, " trr-int=%u",
527 codec->minimum_reporting_interval);
528
529 for (item = codec->optional_params;
530 item;
531 item = g_list_next (item)) {
532 FsCodecParameter *param = item->data;
533 g_string_append_printf (string, " %s=%s", param->name, param->value);
534 }
535
536 for (item = codec->feedback_params;
537 item;
538 item = g_list_next (item)) {
539 FsFeedbackParameter *param = item->data;
540 g_string_append_printf (string, " %s/%s=%s", param->type, param->subtype,
541 param->extra_params);
542 }
543
544 charstring = string->str;
545 g_string_free (string, FALSE);
546
547 return charstring;
548 }
549
550
551 static gboolean
552 compare_optional_params (const gpointer p1, const gpointer p2)
553 {
554 const FsCodecParameter *param1 = p1;
555 const FsCodecParameter *param2 = p2;
556
557 if (!g_ascii_strcasecmp (param1->name, param2->name) &&
558 !strcmp (param1->value, param2->value))
559 return TRUE;
560 else
561 return FALSE;
562 }
563
564 static gboolean
565 compare_feedback_params (const gpointer p1, const gpointer p2)
566 {
567 const FsFeedbackParameter *param1 = p1;
568 const FsFeedbackParameter *param2 = p2;
569
570 if (!g_ascii_strcasecmp (param1->subtype, param2->subtype) &&
571 !g_ascii_strcasecmp (param1->type, param2->type) &&
572 !g_strcmp0 (param1->extra_params, param2->extra_params))
573 return TRUE;
574 else
575 return FALSE;
576 }
577
578 /*
579 * Check if all of the elements of list1 are in list2
580 * It compares GLists of X using the comparison function
581 */
582 static gboolean
583 compare_lists (GList *list1, GList *list2,
584 gboolean (*compare_params) (const gpointer p1, const gpointer p2))
585 {
586 GList *item1;
587
588 for (item1 = g_list_first (list1);
589 item1;
590 item1 = g_list_next (item1)) {
591 FsCodecParameter *param1 = item1->data;
592 GList *item2 = NULL;
593
594 for (item2 = g_list_first (list2);
595 item2;
596 item2 = g_list_next (item2)) {
597 FsCodecParameter *param2 = item2->data;
598
599 if (compare_params (param1, param2))
600 break;
601 }
602 if (!item2)
603 return FALSE;
604 }
605
606 return TRUE;
607 }
608
609
610 /**
611 * fs_codec_are_equal:
612 * @codec1: First codec
613 * @codec2: Second codec
614 *
615 * Compare two codecs, it will declare two codecs to be identical even
616 * if their optional parameters are in a different order. %NULL encoding names
617 * are ignored.
618 *
619 * Return value: %TRUE of the codecs are identical, %FALSE otherwise
620 */
621
622 gboolean
623 fs_codec_are_equal (const FsCodec *codec1, const FsCodec *codec2)
624 {
625 if (codec1 == codec2)
626 return TRUE;
627
628 if (!codec1 || !codec2)
629 return FALSE;
630
631 if (codec1->id != codec2->id ||
632 codec1->media_type != codec2->media_type ||
633 codec1->clock_rate != codec2->clock_rate ||
634 codec1->channels != codec2->channels ||
635 codec1->minimum_reporting_interval !=
636 codec2->minimum_reporting_interval ||
637 codec1->encoding_name == NULL ||
638 codec2->encoding_name == NULL ||
639 g_ascii_strcasecmp (codec1->encoding_name, codec2->encoding_name))
640 return FALSE;
641
642
643 /* Is there a smarter way to compare to un-ordered linked lists
644 * to make sure they contain exactly the same elements??
645 */
646 if (!compare_lists (codec1->optional_params, codec2->optional_params,
647 compare_optional_params) ||
648 !compare_lists (codec2->optional_params, codec1->optional_params,
649 compare_optional_params))
650 return FALSE;
651
652 if (!compare_lists (codec1->feedback_params,
653 codec2->feedback_params, compare_feedback_params) ||
654 !compare_lists (codec2->feedback_params,
655 codec1->feedback_params, compare_feedback_params))
656 return FALSE;
657
658 return TRUE;
659 }
660
661 /**
662 * fs_codec_list_are_equal:
663 * @list1: (element-type FsCodec): a #GList of #FsCodec
664 * @list2: (element-type FsCodec): a #GList of #FsCodec
665 *
666 * Verifies if two glist of fscodecs are identical
667 *
668 * Returns: %TRUE if they are identical, %FALSE otherwise
669 */
670
671 gboolean
672 fs_codec_list_are_equal (GList *list1, GList *list2)
673 {
674
675 for (;
676 list1 && list2;
677 list1 = g_list_next (list1), list2 = g_list_next (list2))
678 {
679 if (!fs_codec_are_equal (list1->data, list2->data))
680 return FALSE;
681 }
682
683 if (list1 == NULL && list2 == NULL)
684 return TRUE;
685 else
686 return FALSE;
687 }
688
689 /**
690 * fs_codec_add_optional_parameter:
691 * @codec: The #FsCodec to add the parameter to
692 * @name: The name of the optional parameter
693 * @value: The extra_params of the optional parameter
694 *
695 * This function adds an new optional parameter to a #FsCodec
696 */
697
698 void
699 fs_codec_add_optional_parameter (FsCodec *codec,
700 const gchar *name,
701 const gchar *value)
702 {
703 FsCodecParameter *param;
704
705 g_return_if_fail (name != NULL && value != NULL);
706
707 param = g_slice_new (FsCodecParameter);
708
709 param->name = g_strdup (name);
710 param->value = g_strdup (value);
711
712 codec->optional_params = g_list_append (codec->optional_params, param);
713 }
714
715 /**
716 * fs_codec_remove_optional_parameter:
717 * @codec: a #FsCodec
718 * @param: a pointer to the #FsCodecParameter to remove
719 *
720 * Removes an optional parameter from a codec.
721 *
722 * NULL param will do nothing.
723 */
724
725 void
726 fs_codec_remove_optional_parameter (FsCodec *codec,
727 FsCodecParameter *param)
728 {
729 g_return_if_fail (codec);
730
731 if (!param)
732 return;
733
734 fs_codec_parameter_free (param);
735 codec->optional_params = g_list_remove (codec->optional_params, param);
736 }
737
738 /**
739 * fs_codec_get_optional_parameter:
740 * @codec: a #FsCodec
741 * @name: The name of the parameter to search for
742 * @value: The value of the parameter to search for or %NULL for any value
743 *
744 * Finds the #FsCodecParameter in the #FsCodec that has the requested name
745 * and, if not %NULL, the requested value
746 *
747 * Returns: (transfer none) the #FsCodecParameter from the #FsCodec or %NULL
748 */
749
750 FsCodecParameter *
751 fs_codec_get_optional_parameter (FsCodec *codec, const gchar *name,
752 const gchar *value)
753 {
754 GList *item = NULL;
755
756 g_return_val_if_fail (codec != NULL, NULL);
757 g_return_val_if_fail (name != NULL, NULL);
758
759 for (item = g_list_first (codec->optional_params);
760 item;
761 item = g_list_next (item))
762 {
763 FsCodecParameter *param = item->data;
764 if (!g_ascii_strcasecmp (param->name, name) &&
765 (value == NULL || !g_ascii_strcasecmp (param->value, value)))
766 return param;
767 }
768
769 return NULL;
770 }
771
772 /**
773 * fs_codec_add_feedback_parameter:
774 * @codec: The #FsCodec to add the parameter to
775 * @type: The type of the feedback parameter
776 * @subtype: The subtype of the feedback parameter
777 * @extra_params: The extra_params of the feeback parameter
778 *
779 * This function adds an new feedback parameter to a #FsCodec
780 */
781
782 void
783 fs_codec_add_feedback_parameter (FsCodec *codec, const gchar *type,
784 const gchar *subtype, const gchar *extra_params)
785 {
786 FsFeedbackParameter *param;
787
788 g_return_if_fail (type != NULL);
789 g_return_if_fail (subtype != NULL);
790 g_return_if_fail (extra_params != NULL);
791
792 param = g_slice_new (FsFeedbackParameter);
793
794 param->type = g_strdup (type);
795 param->subtype = g_strdup (subtype);
796 param->extra_params = g_strdup (extra_params);
797
798 codec->feedback_params = g_list_append (codec->feedback_params, param);
799 }
800
801
802 /**
803 * fs_codec_get_feedback_parameter:
804 * @codec: a #FsCodec
805 * @type: The subtype of the parameter to search for or %NULL for any type
806 * @subtype: The subtype of the parameter to search for or %NULL for any subtype
807 * @extra_params: The extra_params of the parameter to search for or %NULL for
808 * any extra_params
809 *
810 * Finds the #FsFeedbackParameter in the #FsCodec that has the requested
811 * subtype, type and extra_params. One of which must be non-NULL;
812 *
813 * Returns: the #FsFeedbackParameter from the #FsCodec or %NULL
814 */
815
816 FsFeedbackParameter *
817 fs_codec_get_feedback_parameter (FsCodec *codec,
818 const gchar *type, const gchar *subtype, const gchar *extra_params)
819 {
820 GList *item = NULL;
821
822 g_return_val_if_fail (codec != NULL, NULL);
823 g_return_val_if_fail (type != NULL || subtype != NULL, NULL);
824
825 for (item = g_list_first (codec->feedback_params);
826 item;
827 item = g_list_next (item))
828 {
829 FsFeedbackParameter *param = item->data;
830 if (!g_ascii_strcasecmp (param->type, type) &&
831 (subtype == NULL || !g_ascii_strcasecmp (param->subtype, subtype)) &&
832 (extra_params == NULL || !g_ascii_strcasecmp (param->extra_params,
833 extra_params)))
834 return param;
835 }
836
837 return NULL;
838 }
839
840
841
842 /**
843 * fs_codec_remove_feedback_parameter:
844 * @codec: a #FsCodec
845 * @item: a pointer to the #GList element to remove that contains a
846 * #FsFeedbackParameter
847 *
848 * Removes an optional parameter from a codec.
849 *
850 * NULL param will do nothing.
851 */
852
853 void
854 fs_codec_remove_feedback_parameter (FsCodec *codec, GList *item)
855 {
856 g_return_if_fail (codec);
857
858 if (!item)
859 return;
860
861 fs_feedback_parameter_free (item->data);
862 codec->feedback_params =
863 g_list_delete_link (codec->feedback_params, item);
864 }
865
866 FsCodecParameter *
867 fs_codec_parameter_copy (const FsCodecParameter *param)
868 {
869 FsCodecParameter *outparam = g_slice_new (FsCodecParameter);
870
871 outparam->name = g_strdup (param->name);
872 outparam->value = g_strdup (param->value);
873
874 return outparam;
875 }
876
877
878 FsFeedbackParameter *
879 fs_feedback_parameter_copy (const FsFeedbackParameter *param)
880 {
881 FsFeedbackParameter *outparam = g_slice_new (FsFeedbackParameter);
882
883 outparam->type = g_strdup (param->type);
884 outparam->subtype = g_strdup (param->subtype);
885 outparam->extra_params = g_strdup (param->extra_params);
886
887 return outparam;
888 }
0 /*
1 * Farstream - Farstream Codec
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * Copyright 2005 Collabora Ltd.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 *
10 * fs-codec.h - A Farstream codec
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifndef __FS_CODEC_H__
28 #define __FS_CODEC_H__
29
30 #include <gst/gst.h>
31
32 G_BEGIN_DECLS
33
34 typedef struct _FsCodec FsCodec;
35 typedef struct _FsCodecParameter FsCodecParameter;
36 typedef struct _FsFeedbackParameter FsFeedbackParameter;
37
38 #define FS_TYPE_CODEC \
39 (fs_codec_get_type ())
40
41 #define FS_TYPE_CODEC_LIST \
42 (fs_codec_list_get_type ())
43
44 /**
45 * FsMediaType:
46 * @FS_MEDIA_TYPE_AUDIO: A media type that encodes audio.
47 * @FS_MEDIA_TYPE_VIDEO: A media type that encodes video.
48 * @FS_MEDIA_TYPE_LAST: Largest valid #FsMediaType
49 *
50 * Enum used to signify the media type of a codec or stream.
51 */
52 typedef enum _FsMediaType
53 {
54 FS_MEDIA_TYPE_AUDIO,
55 FS_MEDIA_TYPE_VIDEO,
56 FS_MEDIA_TYPE_LAST = FS_MEDIA_TYPE_VIDEO
57 } FsMediaType;
58
59 /**
60 * FS_CODEC_ID_ANY:
61 *
62 * If the id of a #FsCodec is #FS_CODEC_ID_ANY, then it will be replaced
63 * with a dynamic payload type at runtime
64 */
65
66 /**
67 * FS_CODEC_ID_DISABLE:
68 *
69 * If the id of a #FsCodec is #FS_CODEC_ID_DISABLE, then this codec will
70 * not be used
71 */
72
73 #define FS_CODEC_ID_ANY (-1)
74 #define FS_CODEC_ID_DISABLE (-2)
75
76 /**
77 * FsCodec:
78 * @id: numeric identifier for encoding, eg. PT for SDP
79 * @encoding_name: the name of the codec
80 * @media_type: type of media this codec is for
81 * @clock_rate: clock rate of this stream
82 * @channels: Number of channels codec should decode
83 * @ptime: The preferred duration (in ms) of a packet
84 * @maxptime: The maximum duration (in ms) of a packet
85 * @optional_params: (element-type FsCodecParameter): key pairs of param name to param data
86 * @minimum_reporting_interval: The minimum interval between two RTCP reports,
87 * If it is not specified (G_MAXUINT), it is up to the protocol to decide
88 * (it is 5 seconds for RTP).
89 *
90 * This structure reprensents one codec that can be offered or received
91 */
92 /* TODO Should this be made into a GstStructure? */
93 struct _FsCodec
94 {
95 gint id;
96 char *encoding_name;
97 FsMediaType media_type;
98 guint clock_rate;
99 guint channels;
100 guint minimum_reporting_interval;
101 GList *optional_params;
102 GList *feedback_params;
103 };
104
105 /**
106 * FsCodecParameter:
107 * @name: paramter name.
108 * @value: parameter value.
109 *
110 * Used to store arbitary parameters for a codec
111 */
112 struct _FsCodecParameter {
113 gchar *name;
114 gchar *value;
115 };
116
117 /**
118 * FsFeedbackParameter:
119 * @type: the type of feedback, like "ack", "name", "ccm"
120 * @subtype: the subtype of feedback (can be an empty string)
121 * @extra_params: a string containing extra parameters (can be empty)
122 *
123 * Use to store feedback parameters
124 */
125 struct _FsFeedbackParameter {
126 gchar *type;
127 gchar *subtype;
128 gchar *extra_params;
129 };
130
131
132 /**
133 * FS_CODEC_FORMAT:
134 *
135 * A format that can be used in printf like format strings to format a FsCodec
136 */
137
138 /**
139 * FS_CODEC_ARGS:
140 * @codec: a #FsCodec
141 *
142 * Formats the codec in args for FS_CODEC_FORMAT
143 */
144
145 #define FS_CODEC_FORMAT "%d: %s %s clock:%d channels:%d params:%p"
146 #define FS_CODEC_ARGS(codec) \
147 (codec)->id, \
148 fs_media_type_to_string ((codec)->media_type), \
149 (codec)->encoding_name, \
150 (codec)->clock_rate, \
151 (codec)->channels, \
152 (codec)->optional_params
153
154 GType fs_codec_get_type (void);
155 GType fs_codec_list_get_type (void);
156
157
158 FsCodec *fs_codec_new (int id, const char *encoding_name,
159 FsMediaType media_type, guint clock_rate);
160
161 void fs_codec_destroy (FsCodec * codec);
162 FsCodec *fs_codec_copy (const FsCodec * codec);
163 void fs_codec_list_destroy (GList *codec_list);
164 GList *fs_codec_list_copy (const GList *codec_list);
165
166 GList *fs_codec_list_from_keyfile (const gchar *filename, GError **error);
167 gchar *fs_codec_to_string (const FsCodec *codec);
168 const gchar *fs_media_type_to_string (FsMediaType media_type);
169
170 gboolean fs_codec_are_equal (const FsCodec *codec1, const FsCodec *codec2);
171 gboolean fs_codec_list_are_equal (GList *list1, GList *list2);
172
173
174 void fs_codec_add_optional_parameter (FsCodec *codec, const gchar *name,
175 const gchar *value);
176 void fs_codec_remove_optional_parameter (FsCodec *codec,
177 FsCodecParameter *param);
178 FsCodecParameter *fs_codec_get_optional_parameter (FsCodec *codec,
179 const gchar *name, const gchar *value);
180
181 #define FS_TYPE_CODEC_PARAMETER (fs_codec_parameter_get_type ())
182 GType fs_codec_parameter_get_type (void);
183
184 FsCodecParameter *fs_codec_parameter_copy (const FsCodecParameter *param);
185 void fs_codec_parameter_free (FsCodecParameter *param);
186
187
188 void fs_codec_add_feedback_parameter (FsCodec *codec, const gchar *type,
189 const gchar *subtype, const gchar *extra_params);
190 FsFeedbackParameter *fs_codec_get_feedback_parameter (FsCodec *codec,
191 const gchar *type, const gchar *subtype, const gchar *extra_params);
192 void fs_codec_remove_feedback_parameter (FsCodec *codec, GList *item);
193
194
195 #define FS_TYPE_FEEDBACK_PARAMETER (fs_feedback_parameter_get_type ())
196 GType fs_feedback_parameter_get_type (void);
197
198 FsFeedbackParameter *fs_feedback_parameter_copy (
199 const FsFeedbackParameter *param);
200 void fs_feedback_parameter_free (FsFeedbackParameter *param);
201
202
203
204 G_END_DECLS
205
206 #endif /* __FS_CODEC_H__ */
0 /*
1 * Farstream - GStreamer interfaces
2 *
3 * Copyright 2007-2011 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * @author: Olivier Crete <olivier.crete@collabora.com>
6 * Copyright 2007-2011 Nokia Corp.
7 *
8 * fs-conference.c - GStreamer interface to be implemented by farstream
9 * conference elements
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "fs-conference.h"
31 #include "fs-session.h"
32 #include "fs-private.h"
33
34 /**
35 * SECTION:fs-conference
36 * @short_description: Interface for farstream conference elements
37 *
38 * A Farstream conference is a conversation space that takes place between 2 or
39 * more participants. Each conference must have one or more Farstream sessions
40 * that are associated to the conference participants.
41 *
42 *
43 * This will communicate asynchronous events to the user through #GstMessage
44 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
45 * </para>
46 * <refsect2><title>The "<literal>farstream-error</literal>" message</title>
47 * |[
48 * "src-object" #GObject The object (#FsConference, #FsSession or #FsStream) that emitted the error
49 * "error-no" #FsError The Error number
50 * "error-msg" #gchar* The error message
51 * ]|
52 * <para>
53 * The message is sent on asynchronous errors.
54 * </para>
55 * </refsect2>
56 * <para>
57 */
58
59
60 GST_DEBUG_CATEGORY (fs_conference_debug);
61 #define GST_CAT_DEFAULT fs_conference_debug
62
63
64 GST_BOILERPLATE (
65 FsConference, fs_conference,
66 GstBin, GST_TYPE_BIN)
67
68
69 GQuark
70 fs_error_quark (void)
71 {
72 return g_quark_from_static_string ("fs-error");
73 }
74
75 void
76 _fs_conference_init_debug (void)
77 {
78 GST_DEBUG_CATEGORY_INIT (fs_conference_debug, "fsconference", 0,
79 "farstream base conference library");
80 }
81
82 static void
83 fs_conference_base_init (gpointer g_class)
84 {
85 _fs_conference_init_debug ();
86 }
87
88
89
90 static void
91 fs_conference_class_init (FsConferenceClass * klass)
92 {
93 }
94
95 static void
96 fs_conference_init (FsConference *conf, FsConferenceClass *bclass)
97 {
98 GST_DEBUG ("fs_conference_init");
99 }
100
101
102 static void
103 fs_conference_error (GObject *signal_src,
104 GObject *error_src,
105 FsError error_no,
106 gchar *error_msg,
107 FsConference *conf)
108 {
109 GstMessage *gst_msg = NULL;
110 GstStructure *error_struct = NULL;
111
112 error_struct = gst_structure_new ("farstream-error",
113 "src-object", G_TYPE_OBJECT, error_src,
114 "error-no", FS_TYPE_ERROR, error_no,
115 "error-msg", G_TYPE_STRING, error_msg,
116 NULL);
117
118 gst_msg = gst_message_new_element (GST_OBJECT (conf), error_struct);
119
120 if (!gst_element_post_message (GST_ELEMENT (conf), gst_msg))
121 GST_WARNING_OBJECT (conf, "Could not post error on bus");
122 }
123
124 /**
125 * fs_conference_new_session
126 * @conference: #FsConference interface of a #GstElement
127 * @media_type: #FsMediaType of the new session
128 * @error: location of a #GError, or %NULL if no error occured
129 *
130 * Create a new Farstream session for the given conference.
131 *
132 * Returns: (transfer full): the new #FsSession that has been created.
133 * The #FsSession must be unref'd by the user when closing the session.
134 */
135
136 FsSession *
137 fs_conference_new_session (FsConference *conf,
138 FsMediaType media_type,
139 GError **error)
140 {
141 FsConferenceClass *klass;
142 FsSession *new_session = NULL;
143
144 g_return_val_if_fail (conf, NULL);
145 g_return_val_if_fail (FS_IS_CONFERENCE (conf), NULL);
146 klass = FS_CONFERENCE_GET_CLASS (conf);
147 g_return_val_if_fail (klass->new_session, NULL);
148
149 new_session = klass->new_session (conf, media_type, error);
150
151 if (!new_session)
152 return NULL;
153
154 /* Let's catch all session errors and send them over the GstBus */
155 g_signal_connect_object (new_session, "error",
156 G_CALLBACK (fs_conference_error), conf, 0);
157
158 return new_session;
159 }
160
161 /**
162 * fs_conference_new_participant
163 * @conference: #FsConference interface of a #GstElement
164 * @error: location of a #GError, or %NULL if no error occured
165 *
166 * Create a new Farstream Participant for the type of the given conference.
167 *
168 * Returns: (transfer full): the new #FsParticipant that has been created.
169 * The #FsParticipant is owned by the user and he must unref it when he is
170 * done with it.
171 */
172 FsParticipant *
173 fs_conference_new_participant (FsConference *conf,
174 GError **error)
175 {
176 FsConferenceClass *klass;
177
178 g_return_val_if_fail (conf, NULL);
179 g_return_val_if_fail (FS_IS_CONFERENCE (conf), NULL);
180 klass = FS_CONFERENCE_GET_CLASS (conf);
181 g_return_val_if_fail (klass->new_participant, NULL);
182
183 return klass->new_participant (conf, error);
184 }
185
0 /*
1 * Farstream - FsConference Class
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-conference.h - Header file for farstream Conference base class
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_CONFERENCE_H__
25 #define __FS_CONFERENCE_H__
26
27 #include <gst/gst.h>
28
29 #include <farstream/fs-session.h>
30 #include <farstream/fs-codec.h>
31 #include <farstream/fs-enumtypes.h>
32
33 G_BEGIN_DECLS
34
35
36 #define FS_TYPE_CONFERENCE \
37 (fs_conference_get_type ())
38 #define FS_CONFERENCE(obj) \
39 (G_TYPE_CHECK_INSTANCE_CAST((obj),FS_TYPE_CONFERENCE,FsConference))
40 #define FS_CONFERENCE_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_CAST((klass),FS_TYPE_CONFERENCE,FsConferenceClass))
42 #define FS_CONFERENCE_GET_CLASS(obj) \
43 (G_TYPE_INSTANCE_GET_CLASS((obj),FS_TYPE_CONFERENCE,FsConferenceClass))
44 #define FS_IS_CONFERENCE(obj) \
45 (G_TYPE_CHECK_INSTANCE_TYPE((obj),FS_TYPE_CONFERENCE))
46 #define FS_IS_CONFERENCE_CLASS(klass) \
47 (G_TYPE_CHECK_CLASS_TYPE((klass),FS_TYPE_CONFERENCE))
48 #define FS_CONFERENCE_CAST(obj) \
49 ((FsConference *)(obj))
50
51 /**
52 * FsConference:
53 *
54 * Opaque #FsConference data structure.
55 */
56 typedef struct _FsConference FsConference;
57 typedef struct _FsConferenceClass FsConferenceClass;
58
59 /**
60 * FsConference
61 *
62 * The #FsConference structure, all the members are private
63 */
64
65 struct _FsConference
66 {
67 GstBin parent;
68
69 /*< private >*/
70
71 gpointer _padding[8];
72 };
73
74
75 /**
76 * FsConferenceClass:
77 * @parent: parent GstBin class
78 * @new_session: virtual method to create a new conference session
79 * @new_participant: virtual method to create a new participant
80 *
81 * #FsConferenceClass class structure.
82 */
83 struct _FsConferenceClass {
84 GstBinClass parent;
85
86 /* virtual functions */
87 FsSession *(* new_session) (FsConference *conference, FsMediaType media_type,
88 GError **error);
89
90 FsParticipant *(* new_participant) (FsConference *conference,
91 GError **error);
92
93 /*< private > */
94 gpointer _gst_reserved[GST_PADDING];
95 };
96
97 GType fs_conference_get_type (void);
98
99
100
101 /**
102 * FsError:
103 * @FS_ERROR_CONSTRUCTION: Error constructing some of the sub-elements, this
104 * probably denotes an error in the installation of the gstreamer elements.
105 * It is a fatal error.
106 * @FS_ERROR_INVALID_ARGUMENTS: Invalid arguments to the function, this
107 * is a programming error and should not be reported to the user
108 * @FS_ERROR_INTERNAL: An internal error happened in Farstream, it may be in
109 * an inconsistent state. The object from which this error comes should be
110 * discarded.
111 * @FS_ERROR_NETWORK: A network related error, this should probably be
112 * reported to the user.
113 * @FS_ERROR_NOT_IMPLEMENTED: The optional functionality is not implemented by
114 * this plugin.
115 * @FS_ERROR_NEGOTIATION_FAILED: The codec negotiation has failed, this means
116 * that there are no common codecs between the local and remote codecs.
117 * @FS_ERROR_UNKNOWN_CODEC: Data is received on an unknown codec, this most
118 * likely denotes an error on the remote side, the buffers will be ignored.
119 * It can safely be ignored in most cases (but may result in a call with no
120 * media received).
121 * @FS_ERROR_NO_CODECS: There are no codecs detected for that media type.
122 * @FS_ERROR_NO_CODECS_LEFT: All of the codecs have been disabled by the
123 * codec preferences, one should try less strict codec preferences.
124 * @FS_ERROR_CONNECTION_FAILED: Could not connect to the to remote party.
125 * @FS_ERROR_DISPOSED: The object has been disposed.
126 * @FS_ERROR_ALREADY_EXISTS: The object already exists
127 *
128 * This is the enum of error numbers that will come either on the "error"
129 * signal, from the Gst Bus or for error in the FS_ERROR domain in GErrors
130 */
131
132 typedef enum _FsError
133 {
134 FS_ERROR_CONSTRUCTION = 1,
135 FS_ERROR_INTERNAL,
136 FS_ERROR_INVALID_ARGUMENTS = 100,
137 FS_ERROR_NETWORK,
138 FS_ERROR_NOT_IMPLEMENTED,
139 FS_ERROR_NEGOTIATION_FAILED,
140 FS_ERROR_UNKNOWN_CODEC,
141 FS_ERROR_NO_CODECS,
142 FS_ERROR_NO_CODECS_LEFT,
143 FS_ERROR_CONNECTION_FAILED,
144 FS_ERROR_DISPOSED,
145 FS_ERROR_ALREADY_EXISTS
146 } FsError;
147
148 /**
149 * FS_ERROR:
150 *
151 * This quark is used to denote errors coming from Farstream objects
152 */
153
154 #define FS_ERROR (fs_error_quark ())
155
156 /**
157 * FS_ERROR_IS_FATAL:
158 * @error: a #FsError
159 *
160 * Tells the programmer if an error if fatal or not, if it returns %TRUE,
161 * the error is fatal, and the object that created it should
162 * be discarded. It returns %FALSE otherwise.
163 */
164
165 #define FS_ERROR_IS_FATAL(error) \
166 (error < 100)
167
168 GQuark fs_error_quark (void);
169
170 /* virtual class function wrappers */
171 FsSession *fs_conference_new_session (FsConference *conference,
172 FsMediaType media_type,
173 GError **error);
174
175 FsParticipant *fs_conference_new_participant (FsConference *conference,
176 GError **error);
177
178
179 G_END_DECLS
180
181 #endif /* __FS_CONFERENCE_H__ */
182
183
0 /*
1 * Farstream - Recursive element addition notifier
2 *
3 * Copyright 2007-2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007-2008 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 /**
24 * SECTION:fs-element-added-notifier
25 * @short_description: Recursive element addition notifier
26 *
27 * This object can be attach to any #GstBin and will emit a the
28 * #FsElementAddedNotifier::element-added signal for every element inside the
29 * #GstBin or any sub-bin and any element added in the future to the bin or
30 * its sub-bins. There is also a utility method to have it used to
31 * set the properties of elements based on a GKeyfile.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37
38 #include "fs-element-added-notifier.h"
39
40 #include <stdlib.h>
41
42 #include "fs-utils.h"
43
44 #include "fs-marshal.h"
45
46
47 /* Signals */
48 enum
49 {
50 ELEMENT_ADDED,
51 LAST_SIGNAL
52 };
53
54 #define FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(o) \
55 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
56 FsElementAddedNotifierPrivate))
57
58 struct _FsElementAddedNotifierPrivate {
59 GList *keyfiles;
60 };
61
62 static void _element_added_callback (GstBin *parent, GstElement *element,
63 gpointer user_data);
64
65 static void fs_element_added_notifier_finalize (GObject *object);
66
67
68 G_DEFINE_TYPE(FsElementAddedNotifier, fs_element_added_notifier, G_TYPE_OBJECT);
69
70 static guint signals[LAST_SIGNAL] = { 0 };
71
72 static void
73 fs_element_added_notifier_class_init (FsElementAddedNotifierClass *klass)
74 {
75 GObjectClass *gobject_class;
76
77 gobject_class = (GObjectClass *) klass;
78
79 gobject_class->finalize = fs_element_added_notifier_finalize;
80
81 /**
82 * FsElementAddedNotifier::element-added:
83 * @self: #FsElementAddedNotifier that emitted the signal
84 * @bin: The #GstBin to which this object was added
85 * @element: The #GstElement that was added
86 *
87 * This signal is emitted when an element is added to a #GstBin that was added
88 * to this object or one of its sub-bins.
89 * Be careful, there is no guarantee that this will be emitted on your
90 * main thread, it will be emitted in the thread that added the element.
91 * The bin may be %NULL if this is the top-level bin.
92 */
93 signals[ELEMENT_ADDED] = g_signal_new ("element-added",
94 G_TYPE_FROM_CLASS (klass),
95 G_SIGNAL_RUN_LAST,
96 0,
97 NULL,
98 NULL,
99 _fs_marshal_VOID__OBJECT_OBJECT,
100 G_TYPE_NONE, 2, GST_TYPE_BIN, GST_TYPE_ELEMENT);
101
102 g_type_class_add_private (klass, sizeof (FsElementAddedNotifierPrivate));
103 }
104
105
106 static void
107 fs_element_added_notifier_init (FsElementAddedNotifier *notifier)
108 {
109 notifier->priv = FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(notifier);
110 }
111
112
113
114 static void
115 fs_element_added_notifier_finalize (GObject *object)
116 {
117 FsElementAddedNotifier *self = FS_ELEMENT_ADDED_NOTIFIER (object);
118
119 g_list_foreach (self->priv->keyfiles, (GFunc) g_key_file_free, NULL);
120 g_list_free (self->priv->keyfiles);
121 self->priv->keyfiles = NULL;
122 }
123
124 /**
125 * fs_element_added_notifier_new:
126 *
127 * Creates a new #FsElementAddedNotifier object
128 *
129 * Returns: the newly-created #FsElementAddedNotifier
130 */
131
132 FsElementAddedNotifier *
133 fs_element_added_notifier_new (void)
134 {
135 return (FsElementAddedNotifier *)
136 g_object_new (FS_TYPE_ELEMENT_ADDED_NOTIFIER, NULL);
137 }
138
139 /**
140 * fs_element_added_notifier_add:
141 * @notifier: a #FsElementAddedNotifier
142 * @bin: A #GstBin to watch to added elements
143 *
144 * Add a #GstBin to on which the #FsElementAddedNotifier::element-added signal
145 * will be called on every element and sub-element present and added in the
146 * future.
147 */
148
149 void
150 fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
151 GstBin *bin)
152 {
153 g_return_if_fail (notifier && FS_IS_ELEMENT_ADDED_NOTIFIER (notifier));
154 g_return_if_fail (bin && GST_IS_BIN (bin));
155
156 _element_added_callback (NULL, GST_ELEMENT_CAST (bin), notifier);
157 }
158
159
160 static void
161 _bin_unparented_cb (GstObject *object, GstObject *parent, gpointer user_data)
162 {
163 GstIterator *iter = NULL;
164 gboolean done;
165
166 /* Return if there was no handler connected */
167 if (g_signal_handlers_disconnect_by_func (object, _element_added_callback,
168 user_data) == 0)
169 return;
170
171 iter = gst_bin_iterate_elements (GST_BIN (object));
172
173 done = FALSE;
174 while (!done)
175 {
176 gpointer item;
177
178 switch (gst_iterator_next (iter, &item)) {
179 case GST_ITERATOR_OK:
180 if (GST_IS_BIN (item))
181 _bin_unparented_cb (GST_OBJECT (item), object, user_data);
182 gst_object_unref (item);
183 break;
184 case GST_ITERATOR_RESYNC:
185 // We don't rollback anything, we just ignore already processed ones
186 gst_iterator_resync (iter);
187 break;
188 case GST_ITERATOR_ERROR:
189 g_error ("Wrong parameters were given?");
190 done = TRUE;
191 break;
192 case GST_ITERATOR_DONE:
193 done = TRUE;
194 break;
195 }
196 }
197
198 gst_iterator_free (iter);
199 }
200
201
202 /**
203 * fs_element_added_notifier_remove:
204 * @notifier: a #FsElementAddedNotifier
205 * @bin: A #GstBin to stop watching
206 *
207 * Stop watching the passed bin and its subbins.
208 *
209 * Returns: %TRUE if the #GstBin was being watched, %FALSE otherwise
210 */
211
212 gboolean
213 fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
214 GstBin *bin)
215 {
216 g_return_val_if_fail (FS_IS_ELEMENT_ADDED_NOTIFIER (notifier), FALSE);
217 g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
218
219 if (g_signal_handler_find (bin,
220 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
221 0, 0, NULL, /* id, detail, closure */
222 _element_added_callback, notifier) != 0)
223 {
224 _bin_unparented_cb (GST_OBJECT (bin), NULL, notifier);
225 return TRUE;
226 }
227 else
228 {
229 return FALSE;
230 }
231 }
232
233
234 #if 1
235 # define DEBUG(...) do {} while (0)
236 #else
237 # define DEBUG g_debug
238 #endif
239
240 static void
241 _bin_added_from_keyfile (FsElementAddedNotifier *notifier, GstBin *bin,
242 GstElement *element, gpointer user_data)
243 {
244 GKeyFile *keyfile = user_data;
245 const gchar *name = NULL;
246 gchar *free_name = NULL;
247 gchar **keys;
248 gint i;
249 GstElementFactory *factory = gst_element_get_factory (element);
250
251 if (factory)
252 {
253 name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
254 if (name && !g_key_file_has_group (keyfile, name))
255 name = NULL;
256 }
257
258 if (!name)
259 {
260 GST_OBJECT_LOCK (element);
261 if (GST_OBJECT_NAME (element) &&
262 g_key_file_has_group (keyfile, GST_OBJECT_NAME (element)))
263 name = free_name = g_strdup (GST_OBJECT_NAME (element));
264 GST_OBJECT_UNLOCK (element);
265 }
266
267 if (!name)
268 return;
269
270 DEBUG ("Found config for %s", name);
271 keys = g_key_file_get_keys (keyfile, name, NULL, NULL);
272
273 for (i = 0; keys[i]; i++)
274 {
275 GParamSpec *param_spec;
276 GValue prop_value = { 0 };
277 gchar *str_value;
278
279 DEBUG ("getting %s", keys[i]);
280 param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS(element),
281 keys[i]);
282
283 if (!param_spec)
284 {
285 DEBUG ("Property %s does not exist in element %s, ignoring",
286 keys[i], name);
287 continue;
288 }
289
290 g_value_init (&prop_value, param_spec->value_type);
291
292 str_value = g_key_file_get_value (keyfile, name, keys[i], NULL);
293 if (str_value && gst_value_deserialize (&prop_value, str_value))
294 {
295 DEBUG ("Setting %s to on %s", keys[i], name);
296 g_object_set_property (G_OBJECT (element), keys[i], &prop_value);
297 }
298 else
299 {
300 DEBUG ("Could not read value for property %s", keys[i]);
301 }
302 g_free (str_value);
303 g_value_unset (&prop_value);
304 }
305
306 g_strfreev (keys);
307 g_free (free_name);
308 }
309
310
311 /**
312 * fs_element_added_notifier_set_properties_from_keyfile:
313 * @notifier: a #FsElementAddedNotifier
314 * @keyfile: a #GKeyFile
315 *
316 * Using a #GKeyFile where the groups are the element's type or name
317 * and the key=value are the property and its value, this function
318 * will set the properties on the elements added to this object after
319 * this function has been called. It will take ownership of the
320 * GKeyFile structure. It will first try the group as the element type, if that
321 * does not match, it will check its name.
322 */
323 void
324 fs_element_added_notifier_set_properties_from_keyfile (
325 FsElementAddedNotifier *notifier,
326 GKeyFile *keyfile)
327 {
328 g_return_if_fail (FS_IS_ELEMENT_ADDED_NOTIFIER (notifier));
329 g_return_if_fail (keyfile);
330
331 g_signal_connect (notifier, "element-added",
332 G_CALLBACK (_bin_added_from_keyfile), keyfile);
333
334 notifier->priv->keyfiles =
335 g_list_prepend (notifier->priv->keyfiles, keyfile);
336 }
337
338
339 /**
340 * fs_element_added_notifier_set_properties_from_file:
341 * @notifier: a #FsElementAddedNotifier
342 * @filename: The name of the keyfile to use
343 * @error: location of a #GError, or %NULL if no error occured
344 *
345 * Same as fs_element_added_notifier_set_properties_from_keyfile() but using
346 * the name of the file to load instead of the #GKeyFile directly.
347 *
348 * Returns: %TRUE if the file was successfully loaded, %FALSE otherwise
349 */
350 gboolean
351 fs_element_added_notifier_set_properties_from_file (
352 FsElementAddedNotifier *notifier,
353 const gchar *filename,
354 GError **error)
355 {
356 GKeyFile *keyfile = g_key_file_new ();
357
358 if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error))
359 {
360 g_key_file_free (keyfile);
361 return FALSE;
362 }
363
364 fs_element_added_notifier_set_properties_from_keyfile(notifier, keyfile);
365
366 return TRUE;
367 }
368
369 static void
370 _element_added_callback (GstBin *parent, GstElement *element,
371 gpointer user_data)
372 {
373 FsElementAddedNotifier *notifier = FS_ELEMENT_ADDED_NOTIFIER (user_data);
374
375 if (GST_IS_BIN (element)) {
376 GstIterator *iter = NULL;
377 gboolean done;
378
379 g_signal_connect_object (element, "element-added",
380 G_CALLBACK (_element_added_callback), notifier, 0);
381
382 if (parent)
383 g_signal_connect_object (element, "parent-unset",
384 G_CALLBACK (_bin_unparented_cb), notifier, 0);
385
386 iter = gst_bin_iterate_elements (GST_BIN (element));
387
388 done = FALSE;
389 while (!done)
390 {
391 gpointer item = NULL;
392
393 switch (gst_iterator_next (iter, &item)) {
394 case GST_ITERATOR_OK:
395 /* We make sure the callback has not already been added */
396 if (g_signal_handler_find (item,
397 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
398 0, 0, NULL, /* id, detail, closure */
399 _element_added_callback, notifier) == 0)
400 _element_added_callback (GST_BIN_CAST (element), item, notifier);
401 gst_object_unref (item);
402 break;
403 case GST_ITERATOR_RESYNC:
404 // We don't rollback anything, we just ignore already processed ones
405 gst_iterator_resync (iter);
406 break;
407 case GST_ITERATOR_ERROR:
408 g_error ("Wrong parameters were given?");
409 done = TRUE;
410 break;
411 case GST_ITERATOR_DONE:
412 done = TRUE;
413 break;
414 }
415 }
416
417 gst_iterator_free (iter);
418 }
419
420 g_signal_emit (notifier, signals[ELEMENT_ADDED], 0, parent, element);
421 }
422
423
424 /**
425 * fs_element_added_notifier_set_default_properties:
426 * @notifier: a #FsElementAddedNotifier
427 * @element: Element for which to set the default codec
428 * preferences
429 *
430 * Same as first calling fs_utils_get_default_element_properties() and using
431 * the result with
432 * fs_element_added_notifier_set_properties_from_keyfile() .
433 *
434 * This is binding friendly (since GKeyFile doesn't have a boxed type).
435 */
436 void
437 fs_element_added_notifier_set_default_properties (
438 FsElementAddedNotifier *notifier,
439 GstElement *element)
440 {
441 GKeyFile *keyfile = fs_utils_get_default_element_properties (element);
442
443 if (!keyfile)
444 return;
445
446 fs_element_added_notifier_set_properties_from_keyfile(notifier, keyfile);
447 }
0 /*
1 * Farstream - Recursive element addition notifier
2 *
3 * Copyright 2007-2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007-2008 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef __FS_ELEMENT_ADDED_NOTIFIER_H__
23 #define __FS_ELEMENT_ADDED_NOTIFIER_H__
24
25 #include <gst/gst.h>
26
27 G_BEGIN_DECLS
28
29
30 /* TYPE MACROS */
31 #define FS_TYPE_ELEMENT_ADDED_NOTIFIER \
32 (fs_element_added_notifier_get_type ())
33 #define FS_ELEMENT_ADDED_NOTIFIER(obj) \
34 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
35 FsElementAddedNotifier))
36 #define FS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
37 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
38 FsElementAddedNotifierClass))
39 #define FS_IS_ELEMENT_ADDED_NOTIFIER(obj) \
40 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
41 #define FS_IS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
42 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
43 #define FS_ELEMENT_ADDED_NOTIFIER_GET_CLASS(obj) \
44 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
45 FsElementAddedNotifierClass))
46
47
48 typedef struct _FsElementAddedNotifier FsElementAddedNotifier;
49 typedef struct _FsElementAddedNotifierClass FsElementAddedNotifierClass;
50 typedef struct _FsElementAddedNotifierPrivate FsElementAddedNotifierPrivate;
51
52 /**
53 * FsElementAddedNotifier:
54 *
55 * All members are private
56 */
57
58 struct _FsElementAddedNotifier
59 {
60 GObject parent;
61
62 /*< private >*/
63
64 FsElementAddedNotifierPrivate *priv;
65 };
66
67 /**
68 * FsElementAddedNotifierClass:
69 * @parent_class: the #GObjectClass parent
70 *
71 * All members are private
72 */
73 struct _FsElementAddedNotifierClass
74 {
75 GObjectClass parent_class;
76 };
77
78
79 GType fs_element_added_notifier_get_type (void);
80
81 FsElementAddedNotifier *fs_element_added_notifier_new (void);
82
83 void fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
84 GstBin *bin);
85
86 gboolean fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
87 GstBin *bin);
88
89 void fs_element_added_notifier_set_properties_from_keyfile (
90 FsElementAddedNotifier *notifier,
91 GKeyFile *keyfile);
92
93 gboolean fs_element_added_notifier_set_properties_from_file (
94 FsElementAddedNotifier *notifier,
95 const gchar *filename,
96 GError **error);
97
98 void fs_element_added_notifier_set_default_properties (
99 FsElementAddedNotifier *notifier,
100 GstElement *element);
101
102 G_END_DECLS
103
104 #endif /* __FS_ELEMENT_ADDED_NOTIFIER_H__ */
0 /*
1 * Farstream - Farstream Participant
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-participant.c - A Farstream Participant gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-participant
26 * @short_description: A participant in a conference
27 *
28 * This object is the base implementation of a Farstream Participant. It needs to be
29 * derived and implemented by a farstream conference gstreamer element. A
30 * participant represents any source of media in a conference. This could be a
31 * human-participant or an automaton.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "fs-participant.h"
39 #include "fs-enumtypes.h"
40 #include "fs-marshal.h"
41
42 /* Signals */
43 enum
44 {
45 LAST_SIGNAL
46 };
47
48 /* props */
49 enum
50 {
51 PROP_0
52 };
53
54 /*
55 struct _FsParticipantPrivate
56 {
57 };
58 */
59
60 G_DEFINE_ABSTRACT_TYPE(FsParticipant, fs_participant, GST_TYPE_OBJECT);
61
62 #define FS_PARTICIPANT_GET_PRIVATE(o) \
63 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_PARTICIPANT, \
64 FsParticipantPrivate))
65
66 static void fs_participant_finalize (GObject *object);
67
68
69 // static guint signals[LAST_SIGNAL] = { 0 };
70
71 static void
72 fs_participant_class_init (FsParticipantClass *klass)
73 {
74 GObjectClass *gobject_class;
75
76 gobject_class = (GObjectClass *) klass;
77
78 gobject_class->finalize = fs_participant_finalize;
79
80 // g_type_class_add_private (klass, sizeof (FsParticipantPrivate));
81 }
82
83 static void
84 fs_participant_init (FsParticipant *self)
85 {
86 //self->priv = FS_PARTICIPANT_GET_PRIVATE (self);
87 self->mutex = g_mutex_new ();
88 }
89
90 static void
91 fs_participant_finalize (GObject *object)
92 {
93 FsParticipant *self = FS_PARTICIPANT (object);
94 g_mutex_free (self->mutex);
95
96 G_OBJECT_CLASS (fs_participant_parent_class)->finalize (object);
97 }
0 /*
1 * Farstream - Farstream Participant
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-participant.h - A Farstream Participant gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_PARTICIPANT_H__
25 #define __FS_PARTICIPANT_H__
26
27 #include <gst/gst.h>
28
29 G_BEGIN_DECLS
30
31 /* TYPE MACROS */
32 #define FS_TYPE_PARTICIPANT \
33 (fs_participant_get_type ())
34 #define FS_PARTICIPANT(obj) \
35 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_PARTICIPANT, FsParticipant))
36 #define FS_PARTICIPANT_CLASS(klass) \
37 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_PARTICIPANT, FsParticipantClass))
38 #define FS_IS_PARTICIPANT(obj) \
39 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_PARTICIPANT))
40 #define FS_IS_PARTICIPANT_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_PARTICIPANT))
42 #define FS_PARTICIPANT_GET_CLASS(obj) \
43 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_PARTICIPANT, FsParticipantClass))
44 #define FS_PARTICIPANT_CAST(obj) ((FsParticipant *) (obj))
45
46 typedef struct _FsParticipant FsParticipant;
47 typedef struct _FsParticipantClass FsParticipantClass;
48 typedef struct _FsParticipantPrivate FsParticipantPrivate;
49
50 /**
51 * FsParticipantClass:
52 * @parent_class: Our parent
53 *
54 * The FsParticipant class has no virtual methods to implement,
55 * but you may want to override the properties or attach more date to it
56 */
57
58 struct _FsParticipantClass
59 {
60 GstObjectClass parent_class;
61
62 /* virtual functions */
63
64 /*< private >*/
65 FsParticipantPrivate *priv;
66 gpointer _padding[8];
67 };
68
69 /**
70 * FsParticipant:
71 *
72 * All members are private (access them using the properties)
73 */
74 struct _FsParticipant
75 {
76 GstObject parent;
77
78 /*< private >*/
79
80 GMutex *mutex;
81
82 FsParticipantPrivate *priv;
83
84 gpointer _padding[8];
85 };
86
87 /**
88 * FS_PARTICIPANT_DATA_LOCK
89 * @participant: A #FsParticipant
90 *
91 * Locks the participant for data set with g_object_set_data() or
92 * g_object_set_qdata().
93 */
94
95 #define FS_PARTICIPANT_DATA_LOCK(participant) \
96 g_mutex_lock ((participant)->mutex)
97
98 /**
99 * FS_PARTICIPANT_DATA_UNLOCK
100 * @participant: A #FsParticipant
101 *
102 * Unlocks the participant for data set with g_object_set_data() or
103 * g_object_set_qdata().
104 */
105
106 #define FS_PARTICIPANT_DATA_UNLOCK(participant) \
107 g_mutex_unlock ((participant)->mutex)
108
109 GType fs_participant_get_type (void);
110
111 G_END_DECLS
112
113 #endif /* __FS_PARTICIPANT_H__ */
0 /*
1 * fs-plugin.c - Source for farstream plugin infrastructure
2 *
3 * Farstream Voice+Video library
4 * Copyright (c) 2005 INdT.
5 * @author Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
6 * Copyright 2005-2007 Collabora Ltd.
7 * Copyright 2005-2007 Nokia Corp.
8 * @author Rob Taylor <rob.taylor@collabora.co.uk>
9 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
10 *
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "fs-plugin.h"
32
33 #include <string.h>
34
35 #include "fs-conference.h"
36 #include "fs-private.h"
37
38 #define GST_CAT_DEFAULT fs_conference_debug
39
40 /**
41 * SECTION:fs-plugin
42 * @short_description: A class for defining Farstream plugins
43 *
44 * This class is a generic class to load GType plugins based on their name.
45 * With this simple class, you can only have one type per plugin.
46 */
47
48 #define FS_PLUGIN_GET_PRIVATE(o) \
49 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_PLUGIN, FsPluginPrivate))
50
51 static gboolean fs_plugin_load (GTypeModule *module);
52
53
54 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
55 static gchar **search_paths = NULL;
56 static GList *plugins = NULL;
57
58 struct _FsPluginPrivate
59 {
60 GModule *handle;
61 };
62
63 G_DEFINE_TYPE(FsPlugin, fs_plugin, G_TYPE_TYPE_MODULE);
64
65 static void
66 fs_plugin_search_path_init (void)
67 {
68 const gchar *env;
69
70 if (search_paths)
71 return;
72
73 env = g_getenv ("FS_PLUGIN_PATH");
74
75 if (env == NULL)
76 {
77 search_paths = g_new (gchar *, 2);
78 search_paths[0] = g_strdup (FS_PLUGIN_PATH);
79 search_paths[1] = NULL;
80 return;
81 }
82 else
83 {
84 gchar *path;
85
86 path = g_strjoin (":", env, FS_PLUGIN_PATH, NULL);
87 search_paths = g_strsplit (path, ":", -1);
88 g_free (path);
89 }
90 }
91
92 static void
93 fs_plugin_class_init (FsPluginClass * klass)
94 {
95 GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
96
97 module_class->load = fs_plugin_load;
98
99 g_type_class_add_private (klass, sizeof (FsPluginPrivate));
100
101 /* Calling from class initializer so it only gets init'ed once */
102 fs_plugin_search_path_init ();
103 }
104
105
106
107 static void
108 fs_plugin_init (FsPlugin * plugin)
109 {
110 /* member init */
111 plugin->priv = FS_PLUGIN_GET_PRIVATE (plugin);
112 plugin->priv->handle = NULL;
113 }
114
115 static gboolean fs_plugin_load (GTypeModule *module)
116 {
117 FsPlugin *plugin = FS_PLUGIN(module);
118 gchar **search_path = NULL;
119 gchar *path=NULL;
120
121 gboolean (*fs_init_plugin) (FsPlugin *);
122
123 g_return_val_if_fail (plugin != NULL, FALSE);
124 g_return_val_if_fail (plugin->name != NULL && plugin->name[0] != '\0', FALSE);
125
126 for (search_path = search_paths; *search_path; search_path++) {
127 GST_DEBUG("looking for plugins in %s", *search_path);
128
129 path = g_module_build_path (*search_path, plugin->name);
130
131 plugin->priv->handle = g_module_open (path, G_MODULE_BIND_LOCAL);
132 GST_INFO ("opening module %s: %s\n", path,
133 (plugin->priv->handle != NULL) ? "succeeded" : g_module_error ());
134 g_free (path);
135
136 if (!plugin->priv->handle) {
137 continue;
138 }
139
140 else if (!g_module_symbol (plugin->priv->handle,
141 "fs_init_plugin",
142 (gpointer) & fs_init_plugin)) {
143 g_module_close (plugin->priv->handle);
144 plugin->priv->handle = NULL;
145 GST_WARNING ("could not find init function in plugin\n");
146 continue;
147 }
148
149 else
150 break;
151 }
152
153 if (!plugin->priv->handle) {
154 return FALSE;
155 }
156
157 fs_init_plugin (plugin);
158 if (!plugin->type) {
159 /* TODO error handling (init error or no info defined) */
160 GST_WARNING ("init error or no info defined");
161 goto err_close_module;
162 }
163
164 return TRUE;
165
166 err_close_module:
167 g_module_close (plugin->priv->handle);
168 return FALSE;
169
170 }
171
172 static FsPlugin *
173 fs_plugin_get_by_name_locked (const gchar * name, const gchar * type_suffix)
174 {
175 gchar *fullname;
176 FsPlugin *plugin = NULL;
177 GList *plugin_item;
178
179 g_return_val_if_fail (name != NULL, NULL);
180 g_return_val_if_fail (type_suffix != NULL, NULL);
181
182 fullname = g_strdup_printf ("%s-%s",name,type_suffix);
183
184 for (plugin_item = plugins;
185 plugin_item;
186 plugin_item = g_list_next (plugin_item)) {
187 plugin = plugin_item->data;
188 if (plugin->name == NULL || plugin->name[0] == 0)
189 continue;
190 if (!strcmp (plugin->name, fullname)) {
191 break;
192 }
193
194 }
195 g_free (fullname);
196
197 if (plugin_item)
198 return plugin;
199
200 return NULL;
201 }
202
203
204 /**
205 * fs_plugin_create_valist:
206 * @name: The name of the plugin to load
207 * @type_suffix: The type of plugin to load (normally "transmitter")
208 * @error: location of a #GError, or NULL if no error occured
209 * @first_property_name: The name of the first property to be set on the
210 * object
211 * @var_args: The rest of the arguments
212 *
213 * Loads the appropriate plugin if necessary and creates a GObject of
214 * the requested type
215 *
216 * Returns: (transfer full): The object created (or NULL if there is an error)
217 **/
218
219 GObject *
220 fs_plugin_create_valist (const gchar *name, const gchar *type_suffix,
221 GError **error, const gchar *first_property_name, va_list var_args)
222 {
223 GObject *object;
224 FsPlugin *plugin;
225
226 g_return_val_if_fail (name, NULL);
227 g_return_val_if_fail (type_suffix, NULL);
228
229 _fs_conference_init_debug ();
230
231 g_static_mutex_lock (&mutex);
232
233 plugin = fs_plugin_get_by_name_locked (name, type_suffix);
234
235 if (!plugin) {
236 plugin = g_object_new (FS_TYPE_PLUGIN, NULL);
237 if (!plugin) {
238 g_static_mutex_unlock (&mutex);
239 g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
240 "Could not create a fsplugin object");
241 return NULL;
242 }
243 plugin->name = g_strdup_printf ("%s-%s",name,type_suffix);
244 g_type_module_set_name (G_TYPE_MODULE (plugin), plugin->name);
245 plugins = g_list_append (plugins, plugin);
246
247 /* We do the use once and then we keep it loaded forever because
248 * the gstreamer libraries can't be unloaded
249 */
250 if (!g_type_module_use (G_TYPE_MODULE (plugin))) {
251 g_static_mutex_unlock (&mutex);
252 g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
253 "Could not load the %s-%s transmitter plugin", name, type_suffix);
254 return NULL;
255 }
256 }
257
258 g_static_mutex_unlock (&mutex);
259
260 object = g_object_new_valist (plugin->type, first_property_name, var_args);
261
262 return object;
263 }
264
265
266 /**
267 * fs_plugin_create:
268 * @name: The name of the plugin to load
269 * @type_suffix: The type of plugin to load (normally "transmitter")
270 * @error: location of a #GError, or NULL if no error occured
271 * @first_property_name: The name of the first property to be set on the
272 * object
273 * @...: The NULL-terminated list of properties to set on the transmitter
274 *
275 * Loads the appropriate plugin if necessary and creates a GObject of
276 * the requested type
277 *
278 * Returns: (transfer full): The object created (or NULL if there is an error)
279 **/
280
281 GObject *
282 fs_plugin_create (const gchar *name, const gchar *type_suffix,
283 GError **error, const gchar *first_property_name, ...)
284 {
285 va_list var_args;
286 GObject *obj;
287
288 va_start (var_args, first_property_name);
289 obj = fs_plugin_create_valist (name, type_suffix, error, first_property_name,
290 var_args);
291 va_end (var_args);
292
293 return obj;
294 }
295
296 /**
297 * fs_plugin_list_available:
298 * @type_suffix: Get list of plugins with this type suffix
299 *
300 * Gets the list of all available plugins of a certain type
301 *
302 * Returns: (transfer full): a newly allocated NULL terminated array of
303 * strings or %NULL if no strings were found.
304 * It should be freed with g_strfreev().
305 */
306
307 gchar **
308 fs_plugin_list_available (const gchar *type_suffix)
309 {
310 GPtrArray *list = g_ptr_array_new ();
311 gchar **retval = NULL;
312 gchar **search_path = NULL;
313 GRegex *matcher;
314 GError *error = NULL;
315 gchar *tmp1, *tmp2, *tmp3;
316
317 g_static_mutex_lock (&mutex);
318
319 fs_plugin_search_path_init ();
320
321 tmp1 = g_strdup_printf ("(.+)-%s", type_suffix);
322 tmp2 = g_module_build_path ("", tmp1);
323 tmp3 = g_strconcat ("^", tmp2, NULL);
324 matcher = g_regex_new (tmp3, 0, 0, NULL);
325 g_free (tmp1);
326 g_free (tmp2);
327 g_free (tmp3);
328
329
330 for (search_path = search_paths; *search_path; search_path++)
331 {
332 GDir *dir = NULL;
333 const gchar *entry;
334
335 dir = g_dir_open (*search_path, 0, &error);
336 if (!dir)
337 {
338 GST_WARNING ("Could not open path %s to look for plugins: %s",
339 *search_path, error ? error->message : "Unknown error");
340 g_clear_error (&error);
341 continue;
342 }
343
344 while ((entry = g_dir_read_name (dir)))
345 {
346 gchar **matches = NULL;
347
348 matches = g_regex_split (matcher, entry, 0);
349
350 if (matches && g_strv_length (matches) == 3)
351 {
352 gint i;
353 gboolean found = FALSE;
354
355 for (i = 0; i < list->len; i++)
356 {
357 if (!strcmp (matches[1], g_ptr_array_index (list, i)))
358 {
359 found = TRUE;
360 break;
361 }
362 }
363 if (!found)
364 g_ptr_array_add (list, g_strdup (matches[1]));
365 }
366
367 g_strfreev (matches);
368 }
369
370 g_dir_close (dir);
371 }
372
373 g_regex_unref (matcher);
374
375 if (list->len)
376 {
377 g_ptr_array_add (list, NULL);
378 retval = (gchar**) list->pdata;
379 g_ptr_array_free (list, FALSE);
380 }
381 else
382 {
383 g_ptr_array_free (list, TRUE);
384 }
385
386 g_static_mutex_unlock (&mutex);
387
388 return retval;
389 }
0 /*
1 * fs-plugin.h - Header for farstream plugin infrastructure
2 *
3 * Farstream Voice+Video library
4 * Copyright (c) 2005 INdT.
5 * @author: Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
6 * Copyright (c) 2005-2007 Collabora Ltd.
7 * Copyright (c) 2005-2007 Nokia Corp.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #ifndef __FS_PLUGIN_H__
27 #define __FS_PLUGIN_H__
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <gmodule.h>
32 #include <gst/gst.h>
33
34 #include <stdarg.h>
35
36 G_BEGIN_DECLS
37
38
39 /* TYPE MACROS */
40 #define FS_TYPE_PLUGIN \
41 (fs_plugin_get_type ())
42 #define FS_PLUGIN(obj) \
43 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_PLUGIN, FsPlugin))
44 #define FS_PLUGIN_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_PLUGIN, FsPluginClass))
46 #define FS_IS_PLUGIN(obj) \
47 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_PLUGIN))
48 #define FS_IS_PLUGIN_CLASS(klass) \
49 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_PLUGIN))
50 #define FS_PLUGIN_GET_CLASS(obj) \
51 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_PLUGIN, FsPluginClass))
52
53 /**
54 * FsPlugin:
55 * @parent: the parent object
56 *
57 * This structure represents a plugin, it is opaque.
58 */
59
60 typedef struct _FsPlugin FsPlugin;
61 typedef struct _FsPluginClass FsPluginClass;
62 typedef struct _FsPluginPrivate FsPluginPrivate;
63
64 struct _FsPlugin
65 {
66 GTypeModule parent;
67
68 /*< private >*/
69
70 GType type;
71
72 gchar *name; /* name of the plugin */
73
74 /*< private >*/
75
76 FsPluginPrivate *priv;
77
78 gpointer unused[8];
79 };
80
81 struct _FsPluginClass
82 {
83 GTypeModuleClass parent_class;
84
85 /*< private >*/
86
87 gpointer unused[8];
88 };
89
90 GType fs_plugin_get_type (void);
91
92
93 GObject *fs_plugin_create_valist (const gchar *name,
94 const gchar *type_suffix,
95 GError **error,
96 const gchar *first_property_name,
97 va_list var_args);
98
99 GObject *fs_plugin_create (const gchar *name,
100 const gchar *type_suffix,
101 GError **error,
102 const gchar *first_property_name, ...);
103
104 gchar **fs_plugin_list_available (const gchar *type_suffix);
105
106 /**
107 * FS_INIT_PLUGIN:
108 * @type_register_func: A function that register a #GType and returns it
109 *
110 * This macro is used to declare Farstream plugins and must be used once
111 * in any farstream plugin.
112 */
113
114 #define FS_INIT_PLUGIN(type_register_func) \
115 G_MODULE_EXPORT void fs_init_plugin (FsPlugin *plugin) { \
116 plugin->type = (type_register_func (plugin)); \
117 }
118
119
120 G_END_DECLS
121 #endif
122
0 /*
1 * Farstream - Private declarations
2 *
3 * Copyright 2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2008 Nokia Corp.
6 *
7 * fs-conference.h - Header file for gstreamer interface to be
8 * implemented by farstream conference elements
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef __FS_PRIVATE_H__
26 #define __FS_PRIVATE_H__
27
28 #include <gst/gst.h>
29
30 G_BEGIN_DECLS
31
32 void _fs_conference_init_debug (void);
33
34 GST_DEBUG_CATEGORY_EXTERN (fs_conference_debug);
35
36 G_END_DECLS
37
38 #endif /* __FS_PRIVATE_H__ */
39
0 /*
1 * Farstream - Farstream RTP specific types
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * fs-rtp.c - Farstream RTP specific types
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "fs-rtp.h"
30
31 #include <string.h>
32
33 typedef GList FsRtpHeaderExtensionGList;
34
35 G_DEFINE_BOXED_TYPE (FsRtpHeaderExtension, fs_rtp_header_extension,
36 fs_rtp_header_extension_copy, fs_rtp_header_extension_destroy)
37 G_DEFINE_BOXED_TYPE (FsRtpHeaderExtensionGList, fs_rtp_header_extension_list,
38 fs_rtp_header_extension_list_copy, fs_rtp_header_extension_list_destroy)
39
40
41 /**
42 * fs_rtp_header_extension_new:
43 * @id: The identifier of the RTP header extension
44 * @direction: the direction in which this extension can be used
45 * @uri: The URI that defines this extension
46 *
47 * Creates a new #FsRtpHeaderExtension
48 *
49 * Returns: a new #FsRtpHeaderExtension
50 */
51
52 FsRtpHeaderExtension *
53 fs_rtp_header_extension_new (guint id, FsStreamDirection direction,
54 const gchar *uri)
55 {
56 FsRtpHeaderExtension *extension;
57
58 extension = g_slice_new (FsRtpHeaderExtension);
59
60 extension->id = id;
61 extension->direction = direction;
62 extension->uri = g_strdup (uri);
63
64 return extension;
65 }
66
67 /**
68 * fs_rtp_header_extension_copy:
69 * @extension: The RTP header extension definition to copy
70 *
71 * Copies a #FsRtpHeaderExtension
72 *
73 * Returns: a new #FsRtpHeaderExtension
74 */
75
76 FsRtpHeaderExtension *
77 fs_rtp_header_extension_copy (FsRtpHeaderExtension *extension)
78 {
79 if (extension)
80 return fs_rtp_header_extension_new (extension->id, extension->direction,
81 extension->uri);
82 else
83 return NULL;
84 }
85
86 /**
87 * fs_rtp_header_extension_are_equal:
88 * @extension1: The first #FsRtpHeaderExtension
89 * @extension2: The second #FsRtpHeaderExtension
90 *
91 * Compares two #FsRtpHeaderExtension structures
92 *
93 * Returns: %TRUE if they are identical, %FALSE otherwise
94 */
95
96 gboolean
97 fs_rtp_header_extension_are_equal (FsRtpHeaderExtension *extension1,
98 FsRtpHeaderExtension *extension2)
99 {
100 if (extension1 == extension2)
101 return TRUE;
102
103 if (!extension2 || !extension2)
104 return FALSE;
105
106 if (extension1->id == extension2->id &&
107 extension1->direction == extension2->direction &&
108 (extension1->uri == extension2->uri ||
109 (extension1->uri && extension2->uri &&
110 !strcmp (extension1->uri, extension2->uri))))
111 return TRUE;
112 else
113 return FALSE;
114 }
115
116 /**
117 * fs_rtp_header_extension_destroy:
118 * @extension: A RTP header extension to free
119 *
120 * Frees the passed #FsRtpHeaderExtension
121 */
122
123 void
124 fs_rtp_header_extension_destroy (FsRtpHeaderExtension *extension)
125 {
126 if (extension)
127 {
128 g_free (extension->uri);
129 g_slice_free (FsRtpHeaderExtension, extension);
130 }
131 }
132
133 /**
134 * fs_rtp_header_extension_list_copy:
135 * @extensions: a #GList of #FsRtpHeaderExtension
136 *
137 * Does a deep copy of a #GList of #FsRtpHeaderExtension
138 *
139 * Returns: (element-type FsRtpHeaderExtension) (transfer full): a new
140 * #GList of #FsRtpHeaderExtension
141 */
142
143 GList *
144 fs_rtp_header_extension_list_copy (GList *extensions)
145 {
146 GQueue copy = G_QUEUE_INIT;
147 const GList *lp;
148
149 for (lp = extensions; lp; lp = g_list_next (lp)) {
150 FsRtpHeaderExtension *ext = lp->data;
151
152 g_queue_push_tail (&copy, fs_rtp_header_extension_copy (ext));
153 }
154
155 return copy.head;
156 }
157
158 /**
159 * fs_rtp_header_extension_list_destroy:
160 * @extensions: a #GList of #FsRtpHeaderExtension
161 *
162 * Frees the passed #GList of #FsRtpHeaderExtension
163 */
164
165 void
166 fs_rtp_header_extension_list_destroy (GList *extensions)
167 {
168 g_list_foreach (extensions, (GFunc) fs_rtp_header_extension_destroy, NULL);
169 g_list_free (extensions);
170 }
171
172 #define RTP_HDREXT_PREFIX "rtp-hdrext:"
173 #define RTP_HDREXT_AUDIO_PREFIX "audio:"
174 #define RTP_HDREXT_VIDEO_PREFIX "video:"
175
176 /**
177 * fs_rtp_header_extension_list_from_keyfile:
178 * @filename: Name of the #GKeyFile to read the RTP Header Extensions from
179 * @media_type: The media type for which to get header extensions
180 * @error: location of a #GError, or NULL if no error occured
181 *
182 * Reads the content of a #GKeyFile of the following format into a
183 * #GList of #FsRtpHeaderExtension structures.
184 *
185 * The groups have a format "rtp-hdrext:audio:XXX" or
186 * "rtp-hdrext:video:XXX" where XXX is a unique string (per media type).
187 *
188 * The valid keys are:
189 * <itemizedlist>
190 * <listitem>id: a int between in the 1-255 and 4096-4351 ranges</listitem>
191 * <listitem>uri: a URI describing the RTP Header Extension</listitem>
192 * <listitem>direction (optional): To only send or receive a RTP Header
193 * Extension, possible values are "send", "receive", "none" or "both".
194 * Defaults to "both"</listitem>
195 * </itemizedlist>
196 *
197 * Example:
198 * |[
199 * [rtp-hdrext:audio:a]
200 * id=1
201 * uri=urn:ietf:params:rtp-hdrext:toffset
202 *
203 * [rtp-hdrext:audio:abc]
204 * id=3
205 * uri=urn:ietf:params:rtp-hdrext:ntp-64
206 * direction=receive
207 * ]|
208 *
209 * Returns: (element-type FsRtpHeaderExtension) (transfer full): a
210 * #GList of #FsRtpHeaderExtension that must be freed with
211 * fs_rtp_header_extension_list_destroy()
212 */
213
214 GList *
215 fs_rtp_header_extension_list_from_keyfile (const gchar *filename,
216 FsMediaType media_type,
217 GError **error)
218 {
219 GKeyFile *keyfile = NULL;
220 GList *extensions = NULL;
221 gchar **groups = NULL;
222 gsize groups_count = 0;
223 int i;
224
225 g_return_val_if_fail (filename, NULL);
226 g_return_val_if_fail (media_type <= FS_MEDIA_TYPE_LAST, NULL);
227 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
228
229 keyfile = g_key_file_new ();
230
231 if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error))
232 goto out;
233
234 groups = g_key_file_get_groups (keyfile, &groups_count);
235
236 if (!groups)
237 goto out;
238
239 for (i=0; i < groups_count && groups[i]; i++)
240 {
241 FsStreamDirection direction = FS_DIRECTION_BOTH;
242 gint id;
243 gchar *uri;
244 GError *gerror = NULL;
245 gchar *str;
246
247 if (g_ascii_strncasecmp (RTP_HDREXT_PREFIX, groups[i],
248 strlen (RTP_HDREXT_PREFIX)))
249 continue;
250
251 if (!g_ascii_strncasecmp (RTP_HDREXT_AUDIO_PREFIX,
252 groups[i] + strlen (RTP_HDREXT_PREFIX),
253 strlen (RTP_HDREXT_AUDIO_PREFIX)))
254 {
255 if (media_type != FS_MEDIA_TYPE_AUDIO)
256 continue;
257 }
258 else if (!g_ascii_strncasecmp (RTP_HDREXT_VIDEO_PREFIX,
259 groups[i] + strlen (RTP_HDREXT_PREFIX),
260 strlen (RTP_HDREXT_VIDEO_PREFIX)))
261 {
262 if (media_type != FS_MEDIA_TYPE_VIDEO)
263 continue;
264 }
265 else
266 {
267 continue;
268 }
269
270 id = g_key_file_get_integer (keyfile, groups[i], "id", &gerror);
271 if (gerror)
272 {
273 g_clear_error (&gerror);
274 continue;
275 }
276
277 str = g_key_file_get_string (keyfile, groups[i], "direction", &gerror);
278 if (gerror)
279 {
280 GQuark domain = gerror->domain;
281 gint code = gerror->code;
282
283 g_clear_error (&gerror);
284 if (domain != G_KEY_FILE_ERROR || code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
285 continue;
286 }
287 else
288 {
289 if (!g_ascii_strcasecmp (str, "none"))
290 direction = FS_DIRECTION_NONE;
291 else if (!g_ascii_strcasecmp (str, "send"))
292 direction = FS_DIRECTION_SEND;
293 else if (!g_ascii_strcasecmp (str, "recv") ||
294 !g_ascii_strcasecmp (str, "receive"))
295 direction = FS_DIRECTION_RECV;
296 g_free (str);
297 }
298
299 uri = g_key_file_get_string (keyfile, groups[i], "uri", &gerror);
300 if (gerror)
301 {
302 g_clear_error (&gerror);
303 continue;
304 }
305
306 extensions = g_list_append (extensions, fs_rtp_header_extension_new (id,
307 direction, uri));
308 g_free (uri);
309 }
310
311 out:
312
313 g_strfreev (groups);
314 g_key_file_free (keyfile);
315
316 return extensions;
317 }
0 /*
1 * Farstream - Farstream RTP specific types
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * fs-rtp.h - Farstream RTP specific types
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_RTP_H__
25 #define __FS_RTP_H__
26
27 #include <gst/gst.h>
28 #include <farstream/fs-stream.h>
29
30 G_BEGIN_DECLS
31
32 /**
33 * FsRtpHeaderExtension:
34 * @id: The identifier of the RTP header extension
35 * @direction: the direction in which this extension can be used
36 * @uri: The URI that defines this extension
37 *
38 * Defines a RTP header extension with its negotiated identifier, direction
39 * and URI. They should only be created with fs_rtp_header_extension_new().
40 */
41
42 typedef struct _FsRtpHeaderExtension {
43 guint id;
44 FsStreamDirection direction;
45 gchar *uri;
46 } FsRtpHeaderExtension;
47
48 /**
49 * FS_TYPE_RTP_HEADER_EXTENSION:
50 *
51 * Boxed type for #FsRtpHeaderExtension
52 */
53
54 /**
55 * FS_TYPE_RTP_HEADER_EXTENSION_LIST:
56 *
57 * Boxed type for a #GList of #FsRtpHeaderExtension
58 */
59
60 #define FS_TYPE_RTP_HEADER_EXTENSION \
61 fs_rtp_header_extension_get_type ()
62 #define FS_TYPE_RTP_HEADER_EXTENSION_LIST \
63 fs_rtp_header_extension_list_get_type ()
64
65 GType fs_rtp_header_extension_get_type (void);
66 GType fs_rtp_header_extension_list_get_type (void);
67
68
69 FsRtpHeaderExtension *
70 fs_rtp_header_extension_new (guint id, FsStreamDirection direction,
71 const gchar *uri);
72
73 FsRtpHeaderExtension *
74 fs_rtp_header_extension_copy (FsRtpHeaderExtension *extension);
75 void
76 fs_rtp_header_extension_destroy (FsRtpHeaderExtension *extension);
77
78 gboolean
79 fs_rtp_header_extension_are_equal (FsRtpHeaderExtension *extension1,
80 FsRtpHeaderExtension *extension2);
81
82 GList *
83 fs_rtp_header_extension_list_copy (GList *extensions);
84 void
85 fs_rtp_header_extension_list_destroy (GList *extensions);
86
87 GList *
88 fs_rtp_header_extension_list_from_keyfile (const gchar *filename,
89 FsMediaType media_type,
90 GError **error);
91
92 /**
93 * FS_RTP_HEADER_EXTENSION_FORMAT:
94 *
95 * A format that can be used in printf like format strings to format a
96 * FsRtpHeaderExtension
97 */
98
99 /**
100 * FS_RTP_HEADER_EXTENSION_ARGS:
101 * @hdrext: a #FsRtpHeaderExtension
102 *
103 * Formats the codec in args for FS_RTP_HEADER_EXTENSION_ARGS
104 */
105
106 #define FS_RTP_HEADER_EXTENSION_FORMAT "%d: (%s) %s"
107 #define FS_RTP_HEADER_EXTENSION_ARGS(hdrext) \
108 (hdrext)->id, \
109 (hdrext)->direction == FS_DIRECTION_BOTH ? "both" : \
110 ((hdrext)->direction == FS_DIRECTION_RECV? "recv" : \
111 ((hdrext)->direction == FS_DIRECTION_SEND ? "send" : "none")), \
112 (hdrext)->uri
113
114 G_END_DECLS
115
116 #endif /* __FS_RTP_H__ */
0 /*
1 * Farstream - Farstream Session
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-session.c - A Farstream Session gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24
25
26 /**
27 * SECTION:fs-session
28 * @short_description: A session in a conference
29 *
30 * This object is the base implementation of a Farstream Session. It needs to be
31 * derived and implemented by a farstream conference gstreamer element. A
32 * Farstream session is defined in the same way as an RTP session. It can contain
33 * one or more participants but represents only one media stream (i.e. One
34 * session for video and one session for audio in an AV conference). Sessions
35 * contained in the same conference will be synchronised together during
36 * playback.
37 *
38 *
39 * This will communicate asynchronous events to the user through #GstMessage
40 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
41 * </para>
42 * <refsect2><title>The "<literal>farstream-send-codec-changed</literal>"
43 * message</title>
44 * |[
45 * "session" #FsSession The session that emits the message
46 * "codec" #FsCodec The new send codec
47 * "secondary-codecs" #GList A #GList of #FsCodec (to be freed
48 * with fs_codec_list_destroy())
49 * ]|
50 * <para>
51 * This message is sent on the bus when the value of the
52 * #FsSession:current-send-codec property changes.
53 * </para>
54 * </refsect2>
55 * <refsect2><title>The "<literal>farstream-codecs-changed</literal>"
56 * message</title>
57 * |[
58 * "session" #FsSession The session that emits the message
59 * ]|
60 * <para>
61 * This message is sent on the bus when the value of the
62 * #FsSession:codecs or #FsSession:codecs-without-config properties change.
63 * If one is using codecs that have configuration data that needs to be
64 * transmitted reliably, one should fetch #FsSession:codecs, otherwise,
65 * #FsSession:codecs-without-config should be enough.
66 * </para>
67 * </refsect2>
68 * <para>
69 */
70
71 #ifdef HAVE_CONFIG_H
72 #include "config.h"
73 #endif
74
75 #include "fs-session.h"
76
77 #include <gst/gst.h>
78
79 #include "fs-conference.h"
80 #include "fs-codec.h"
81 #include "fs-marshal.h"
82 #include "fs-enumtypes.h"
83 #include "fs-private.h"
84
85 #define GST_CAT_DEFAULT fs_conference_debug
86
87 /* Signals */
88 enum
89 {
90 ERROR_SIGNAL,
91 LAST_SIGNAL
92 };
93
94 /* props */
95 enum
96 {
97 PROP_0,
98 PROP_MEDIA_TYPE,
99 PROP_ID,
100 PROP_SINK_PAD,
101 PROP_CODEC_PREFERENCES,
102 PROP_CODECS,
103 PROP_CODECS_WITHOUT_CONFIG,
104 PROP_CURRENT_SEND_CODEC,
105 PROP_TYPE_OF_SERVICE
106 };
107
108 /*
109 struct _FsSessionPrivate
110 {
111 };
112
113 #define FS_SESSION_GET_PRIVATE(o) \
114 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_SESSION, FsSessionPrivate))
115 */
116
117 G_DEFINE_ABSTRACT_TYPE(FsSession, fs_session, GST_TYPE_OBJECT);
118
119 static void fs_session_get_property (GObject *object,
120 guint prop_id,
121 GValue *value,
122 GParamSpec *pspec);
123 static void fs_session_set_property (GObject *object,
124 guint prop_id,
125 const GValue *value,
126 GParamSpec *pspec);
127
128 static guint signals[LAST_SIGNAL] = { 0 };
129
130 static void
131 fs_session_class_init (FsSessionClass *klass)
132 {
133 GObjectClass *gobject_class;
134
135 gobject_class = (GObjectClass *) klass;
136
137 gobject_class->set_property = fs_session_set_property;
138 gobject_class->get_property = fs_session_get_property;
139
140 /**
141 * FsSession:media-type:
142 *
143 * The media-type of the session. This is either Audio, Video or both.
144 * This is a constructor parameter that cannot be changed.
145 *
146 */
147 g_object_class_install_property (gobject_class,
148 PROP_MEDIA_TYPE,
149 g_param_spec_enum ("media-type",
150 "The media type of the session",
151 "An enum that specifies the media type of the session",
152 FS_TYPE_MEDIA_TYPE,
153 FS_MEDIA_TYPE_AUDIO,
154 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
155
156 /**
157 * FsSession:id:
158 *
159 * The ID of the session, the first number of the pads linked to this session
160 * will be this id
161 *
162 */
163 g_object_class_install_property (gobject_class,
164 PROP_ID,
165 g_param_spec_uint ("id",
166 "The ID of the session",
167 "This ID is used on pad related to this session",
168 0, G_MAXUINT, 0,
169 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
170
171 /**
172 * FsSession:sink-pad:
173 *
174 * The Gstreamer sink pad that must be used to send media data on this
175 * session. User must unref this GstPad when done with it.
176 *
177 */
178 g_object_class_install_property (gobject_class,
179 PROP_SINK_PAD,
180 g_param_spec_object ("sink-pad",
181 "A gstreamer sink pad for this session",
182 "A pad used for sending data on this session",
183 GST_TYPE_PAD,
184 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
185
186 /**
187 * FsSession:codec-preferences:
188 *
189 * Type: GLib.List<FsCodec>
190 * Transfer: full
191 *
192 * This is the current preferences list for the local codecs. It is
193 * set by the user to specify the codec options and priorities. The user may
194 * change its value with fs_session_set_codec_preferences() at any time
195 * during a session. It is a #GList of #FsCodec.
196 * The user must free this codec list using fs_codec_list_destroy() when done.
197 *
198 * The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
199 * or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
200 * payload type of the codec will be "reserved" and not be used by any
201 * dynamically assigned payload type.
202 */
203 g_object_class_install_property (gobject_class,
204 PROP_CODEC_PREFERENCES,
205 g_param_spec_boxed ("codec-preferences",
206 "List of user preferences for the codecs",
207 "A GList of FsCodecs that allows user to set his codec options and"
208 " priorities",
209 FS_TYPE_CODEC_LIST,
210 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
211
212 /**
213 * FsSession:codecs:
214 *
215 * Type: GLib.List<FsCodec>
216 * Transfer: full
217 *
218 * This is the list of codecs used for this session. It will include the
219 * codecs and payload type used to receive media on this session. It will
220 * also include any configuration parameter that must be transmitted reliably
221 * for the other end to decode the content.
222 *
223 * It may change when the codec preferences are set, when codecs are set
224 * on a #FsStream in this session, when a #FsStream is destroyed or
225 * asynchronously when new config data is discovered.
226 *
227 * If any configuration parameter needs to be discovered, this property
228 * will be %NULL until they have been discovered. One can always get
229 * the codecs from #FsSession:codecs-without-config.
230 * The "farstream-codecs-changed" message will be emitted whenever the value
231 * of this property changes.
232 *
233 * It is a #GList of #FsCodec. User must free this codec list using
234 * fs_codec_list_destroy() when done.
235 *
236 */
237 g_object_class_install_property (gobject_class,
238 PROP_CODECS,
239 g_param_spec_boxed ("codecs",
240 "List of codecs",
241 "A GList of FsCodecs indicating the codecs for this session",
242 FS_TYPE_CODEC_LIST,
243 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
244
245 /**
246 * FsSession:codecs-without-config:
247 *
248 * Type: GLib.List<FsCodec>
249 * Transfer: full
250 *
251 * This is the same list of codecs as #FsSession:codecs without
252 * the configuration information that describes the data sent. It is suitable
253 * for configurations where a list of codecs is shared by many senders.
254 * If one is using codecs such as Theora, Vorbis or H.264 that require
255 * such information to be transmitted, the configuration data should be
256 * included in the stream and retransmitted regularly.
257 *
258 * It may change when the codec preferences are set, when codecs are set
259 * on a #FsStream in this session, when a #FsStream is destroyed or
260 * asynchronously when new config data is discovered.
261 *
262 * The "farstream-codecs-changed" message will be emitted whenever the value
263 * of this property changes.
264 *
265 * It is a #GList of #FsCodec. User must free this codec list using
266 * fs_codec_list_destroy() when done.
267 *
268 */
269 g_object_class_install_property (gobject_class,
270 PROP_CODECS_WITHOUT_CONFIG,
271 g_param_spec_boxed ("codecs-without-config",
272 "List of codecs without the configuration data",
273 "A GList of FsCodecs indicating the codecs for this session without "
274 "any configuration data",
275 FS_TYPE_CODEC_LIST,
276 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
277
278 /**
279 * FsSession:current-send-codec:
280 *
281 * Indicates the currently active send codec. A user can change the active
282 * send codec by calling fs_session_set_send_codec(). The send codec could
283 * also be automatically changed by Farstream. This property is an
284 * #FsCodec. User must free the codec using fs_codec_destroy() when done.
285 * The "farstream-send-codec-changed" message is emitted on the bus when
286 * the value of this property changes.
287 */
288 g_object_class_install_property (gobject_class,
289 PROP_CURRENT_SEND_CODEC,
290 g_param_spec_boxed ("current-send-codec",
291 "Current active send codec",
292 "An FsCodec indicating the currently active send codec",
293 FS_TYPE_CODEC,
294 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
295
296 /**
297 * FsSession:tos
298 *
299 * Sets the IP ToS field (and if possible the IPv6 TCLASS field
300 */
301 g_object_class_install_property (gobject_class,
302 PROP_TYPE_OF_SERVICE,
303 g_param_spec_uint ("tos",
304 "IP Type of Service",
305 "The IP Type of Service to set on sent packets",
306 0, 255, 0,
307 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
308
309
310 /**
311 * FsSession::error:
312 * @self: #FsSession that emitted the signal
313 * @object: The #Gobject that emitted the signal
314 * @error_no: The number of the error
315 * @error_msg: Error message
316 *
317 * This signal is emitted in any error condition, it can be emitted on any
318 * thread. Applications should listen to the GstBus for errors.
319 *
320 */
321 signals[ERROR_SIGNAL] = g_signal_new ("error",
322 G_TYPE_FROM_CLASS (klass),
323 G_SIGNAL_RUN_LAST,
324 0,
325 NULL,
326 NULL,
327 _fs_marshal_VOID__OBJECT_ENUM_STRING,
328 G_TYPE_NONE, 3, G_TYPE_OBJECT, FS_TYPE_ERROR, G_TYPE_STRING);
329 }
330
331 static void
332 fs_session_init (FsSession *self)
333 {
334 /* member init */
335 // self->priv = FS_SESSION_GET_PRIVATE (self);
336 }
337
338 static void
339 fs_session_get_property (GObject *object,
340 guint prop_id,
341 GValue *value,
342 GParamSpec *pspec)
343 {
344 GST_WARNING ("Subclass %s of FsSession does not override the %s property"
345 " getter",
346 G_OBJECT_TYPE_NAME(object),
347 g_param_spec_get_name (pspec));
348 }
349
350 static void
351 fs_session_set_property (GObject *object,
352 guint prop_id,
353 const GValue *value,
354 GParamSpec *pspec)
355 {
356 GST_WARNING ("Subclass %s of FsSession does not override the %s property"
357 " setter",
358 G_OBJECT_TYPE_NAME(object),
359 g_param_spec_get_name (pspec));
360 }
361
362 static void
363 fs_session_error_forward (GObject *signal_src,
364 FsError error_no, gchar *error_msg,
365 FsSession *session)
366 {
367 /* We just need to forward the error signal including a ref to the stream
368 * object (signal_src) */
369 g_signal_emit (session, signals[ERROR_SIGNAL], 0, signal_src, error_no,
370 error_msg);
371 }
372
373 /**
374 * fs_session_new_stream:
375 * @session: a #FsSession
376 * @participant: #FsParticipant of a participant for the new stream
377 * @direction: #FsStreamDirection describing the direction of the new stream that will
378 * be created for this participant
379 * @error: location of a #GError, or %NULL if no error occured
380 *
381 * This function creates a stream for the given participant into the active session.
382 *
383 * Returns: (transfer full): the new #FsStream that has been created.
384 * User must unref the #FsStream when the stream is ended. If an error occured,
385 * returns NULL.
386 */
387 FsStream *
388 fs_session_new_stream (FsSession *session,
389 FsParticipant *participant,
390 FsStreamDirection direction,
391 GError **error)
392 {
393 FsSessionClass *klass;
394 FsStream *new_stream = NULL;
395
396 g_return_val_if_fail (session, NULL);
397 g_return_val_if_fail (FS_IS_SESSION (session), NULL);
398 klass = FS_SESSION_GET_CLASS (session);
399 g_return_val_if_fail (klass->new_stream, NULL);
400
401 new_stream = klass->new_stream (session, participant, direction, error);
402
403 if (!new_stream)
404 return NULL;
405
406 /* Let's catch all stream errors and forward them */
407 g_signal_connect_object (new_stream, "error",
408 G_CALLBACK (fs_session_error_forward), session, 0);
409
410 return new_stream;
411 }
412
413 /**
414 * fs_session_start_telephony_event:
415 * @session: a #FsSession
416 * @event: A #FsStreamDTMFEvent or another number defined at
417 * http://www.iana.org/assignments/audio-telephone-event-registry
418 * @volume: The volume in dBm0 without the negative sign. Should be between
419 * 0 and 36. Higher values mean lower volume
420 * @method: The method used to send the event
421 *
422 * This function will start sending a telephony event (such as a DTMF
423 * tone) on the #FsSession. You have to call the function
424 * fs_session_stop_telephony_event() to stop it.
425 * This function will use any available method, if you want to use a specific
426 * method only, use fs_session_start_telephony_event_full()
427 *
428 * Returns: %TRUE if sucessful, it can return %FALSE if the #FsStream
429 * does not support this telephony event.
430 */
431 gboolean
432 fs_session_start_telephony_event (FsSession *session, guint8 event,
433 guint8 volume, FsDTMFMethod method)
434 {
435 FsSessionClass *klass;
436
437 g_return_val_if_fail (session, FALSE);
438 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
439 klass = FS_SESSION_GET_CLASS (session);
440
441 if (klass->start_telephony_event) {
442 return klass->start_telephony_event (session, event, volume, method);
443 } else {
444 GST_WARNING ("start_telephony_event not defined in class");
445 }
446 return FALSE;
447 }
448
449 /**
450 * fs_session_stop_telephony_event:
451 * @session: an #FsSession
452 * @method: The method used to send the event
453 *
454 * This function will stop sending a telephony event started by
455 * fs_session_start_telephony_event(). If the event was being sent
456 * for less than 50ms, it will be sent for 50ms minimum. If the
457 * duration was a positive and the event is not over, it will cut it
458 * short.
459 *
460 * Returns: %TRUE if sucessful, it can return %FALSE if the #FsSession
461 * does not support telephony events or if no telephony event is being sent
462 */
463 gboolean
464 fs_session_stop_telephony_event (FsSession *session, FsDTMFMethod method)
465 {
466 FsSessionClass *klass;
467
468 g_return_val_if_fail (session, FALSE);
469 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
470 klass = FS_SESSION_GET_CLASS (session);
471
472 if (klass->stop_telephony_event) {
473 return klass->stop_telephony_event (session, method);
474 } else {
475 GST_WARNING ("stop_telephony_event not defined in class");
476 }
477 return FALSE;
478 }
479
480 /**
481 * fs_session_set_send_codec:
482 * @session: a #FsSession
483 * @send_codec: a #FsCodec representing the codec to send
484 * @error: location of a #GError, or %NULL if no error occured
485 *
486 * This function will set the currently being sent codec for all streams in this
487 * session. The given #FsCodec must be taken directly from the #codecs
488 * property of the session. If the given codec is not in the codecs
489 * list, @error will be set and %FALSE will be returned. The @send_codec will be
490 * copied so it must be free'd using fs_codec_destroy() when done.
491 *
492 * Returns: %FALSE if the send codec couldn't be set.
493 */
494 gboolean
495 fs_session_set_send_codec (FsSession *session, FsCodec *send_codec,
496 GError **error)
497 {
498 FsSessionClass *klass;
499
500 g_return_val_if_fail (session, FALSE);
501 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
502 klass = FS_SESSION_GET_CLASS (session);
503
504 if (klass->set_send_codec) {
505 return klass->set_send_codec (session, send_codec, error);
506 } else {
507 GST_WARNING ("set_send_codec not defined in class");
508 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
509 "set_send_codec not defined in class");
510 }
511 return FALSE;
512 }
513
514 /**
515 * fs_session_set_codec_preferences:
516 * @session: a #FsSession
517 * @codec_preferences: (element-type FsCodec): a #GList of #FsCodec with the
518 * desired configuration
519 * @error: location of a #GError, or %NULL if no error occured
520 *
521 * Set the list of desired codec preferences. The user may
522 * change this value during an ongoing session. Note that doing this can cause
523 * the codecs to change. Therefore this requires the user to fetch
524 * the new codecs and renegotiate them with the peers. It is a #GList
525 * of #FsCodec. The changes are immediately effective.
526 * The function does not take ownership of the list.
527 *
528 * The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
529 * or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
530 * payload type of the codec will be "reserved" and not be used by any
531 * dynamically assigned payload type.
532 *
533 * If the list of specifications would invalidate all codecs, an error will
534 * be returned.
535 *
536 * Returns: %TRUE on success, %FALSE on error.
537 */
538 gboolean
539 fs_session_set_codec_preferences (FsSession *session,
540 GList *codec_preferences,
541 GError **error)
542 {
543 FsSessionClass *klass;
544
545 g_return_val_if_fail (session, FALSE);
546 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
547 klass = FS_SESSION_GET_CLASS (session);
548
549 if (klass->set_codec_preferences) {
550 return klass->set_codec_preferences (session, codec_preferences, error);
551 } else {
552 GST_WARNING ("set_send_preferences not defined in class");
553 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
554 "set_codec_preferences not defined in class");
555 }
556 return FALSE;
557 }
558
559 /**
560 * fs_session_emit_error:
561 * @session: #FsSession on which to emit the error signal
562 * @error_no: The number of the error of type #FsError
563 * @error_msg: Error message
564 *
565 * This function emit the "error" signal on a #FsSession, it should only be
566 * called by subclasses.
567 */
568 void
569 fs_session_emit_error (FsSession *session,
570 gint error_no,
571 const gchar *error_msg)
572 {
573 g_signal_emit (session, signals[ERROR_SIGNAL], 0, session, error_no,
574 error_msg);
575 }
576
577 /**
578 * fs_session_list_transmitters:
579 * @session: A #FsSession
580 *
581 * Get the list of all available transmitters for this session.
582 *
583 * Returns: (transfer full): a newly-allocagted %NULL terminated array of
584 * named of transmitters or %NULL if no transmitter is needed for this type of
585 * session. It should be freed with g_strfreev().
586 */
587
588 gchar **
589 fs_session_list_transmitters (FsSession *session)
590 {
591 FsSessionClass *klass;
592
593 g_return_val_if_fail (session, NULL);
594 g_return_val_if_fail (FS_IS_SESSION (session), NULL);
595 klass = FS_SESSION_GET_CLASS (session);
596
597 if (klass->list_transmitters) {
598 return klass->list_transmitters (session);
599 } else {
600 return NULL;
601 }
602 }
603
604
605 /**
606 * fs_session_get_stream_transmitter_type:
607 * @session: A #FsSession
608 * @transmitter: The name of the transmitter
609 *
610 * Returns the GType of the stream transmitter, bindings can use it
611 * to validate/convert the parameters passed to fs_session_new_stream().
612 *
613 * Returns: The #GType of the stream transmitter
614 */
615 GType
616 fs_session_get_stream_transmitter_type (FsSession *session,
617 const gchar *transmitter)
618 {
619 FsSessionClass *klass;
620
621 g_return_val_if_fail (session, 0);
622 g_return_val_if_fail (FS_IS_SESSION (session), 0);
623 klass = FS_SESSION_GET_CLASS (session);
624
625 if (klass->get_stream_transmitter_type)
626 return klass->get_stream_transmitter_type (session, transmitter);
627
628 return 0;
629 }
630
631 /**
632 * fs_session_codecs_need_resend:
633 * @session: a #FsSession
634 * @old_codecs: Codecs previously retrieved from the #FsSession:codecs property
635 * @new_codecs: Codecs recently retrieved from the #FsSession:codecs property
636 *
637 * Some codec updates need to be reliably transmitted to the other side
638 * because they contain important parameters required to decode the media.
639 * Other codec updates, caused by user action, don't.
640 *
641 * Returns: (element-type FsCodec) (transfer full): A new #GList of
642 * #FsCodec that need to be resent or %NULL if there are none. This
643 * list must be freed with fs_codec_list_destroy().
644 */
645 GList *
646 fs_session_codecs_need_resend (FsSession *session,
647 GList *old_codecs, GList *new_codecs)
648 {
649 FsSessionClass *klass;
650
651 g_return_val_if_fail (session, 0);
652 g_return_val_if_fail (FS_IS_SESSION (session), 0);
653 klass = FS_SESSION_GET_CLASS (session);
654
655 if (klass->codecs_need_resend)
656 return klass->codecs_need_resend (session, old_codecs, new_codecs);
657
658 return NULL;
659 }
660
661 /**
662 * fs_session_destroy:
663 * @session: a #FsSession
664 *
665 * This will cause the session to remove all links to other objects and to
666 * remove itself from the #FsConference, it will also destroy all #FsStream
667 * inside this #FsSession Once a #FsSession has been destroyed, it
668 * can not be used anymore.
669 *
670 * It is strongly recommended to call this function from the main thread because
671 * releasing the application's reference to a session.
672 */
673
674 void
675 fs_session_destroy (FsSession *session)
676 {
677 g_return_if_fail (session);
678 g_return_if_fail (FS_IS_SESSION (session));
679
680 g_object_run_dispose (G_OBJECT (session));
681 }
0 /*
1 * Farstream - Farstream Session
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-session.h - A Farstream Session gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_SESSION_H__
25 #define __FS_SESSION_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include <farstream/fs-stream.h>
31 #include <farstream/fs-participant.h>
32 #include <farstream/fs-codec.h>
33
34 G_BEGIN_DECLS
35
36 /* TYPE MACROS */
37 #define FS_TYPE_SESSION \
38 (fs_session_get_type ())
39 #define FS_SESSION(obj) \
40 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_SESSION, FsSession))
41 #define FS_SESSION_CLASS(klass) \
42 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_SESSION, FsSessionClass))
43 #define FS_IS_SESSION(obj) \
44 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_SESSION))
45 #define FS_IS_SESSION_CLASS(klass) \
46 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_SESSION))
47 #define FS_SESSION_GET_CLASS(obj) \
48 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_SESSION, FsSessionClass))
49 #define FS_SESSION_CAST(obj) ((FsSession *) (obj))
50
51 typedef struct _FsSession FsSession;
52 typedef struct _FsSessionClass FsSessionClass;
53 typedef struct _FsSessionPrivate FsSessionPrivate;
54
55 /**
56 * FsDTMFEvent:
57 *
58 * An enum that represents the different DTMF event that can be sent to a
59 * #FsSession. The values corresponds those those defined in RFC 4733
60 * The rest of the possibles values are in the IANA registry at:
61 * http://www.iana.org/assignments/audio-telephone-event-registry
62 *
63 */
64 typedef enum _FsDTMFEvent
65 {
66 /*< protected >*/
67 FS_DTMF_EVENT_0 = 0,
68 FS_DTMF_EVENT_1 = 1,
69 FS_DTMF_EVENT_2 = 2,
70 FS_DTMF_EVENT_3 = 3,
71 FS_DTMF_EVENT_4 = 4,
72 FS_DTMF_EVENT_5 = 5,
73 FS_DTMF_EVENT_6 = 6,
74 FS_DTMF_EVENT_7 = 7,
75 FS_DTMF_EVENT_8 = 8,
76 FS_DTMF_EVENT_9 = 9,
77 FS_DTMF_EVENT_STAR = 10,
78 FS_DTMF_EVENT_POUND = 11,
79 FS_DTMF_EVENT_A = 12,
80 FS_DTMF_EVENT_B = 13,
81 FS_DTMF_EVENT_C = 14,
82 FS_DTMF_EVENT_D = 15
83 } FsDTMFEvent;
84
85 /**
86 * FsDTMFMethod:
87 * @FS_DTMF_METHOD_AUTO: Send in any possible way
88 * @FS_DTMF_METHOD_RTP_RFC4733: Send as a special payload type defined by RFC 4733
89 * (which obsoletes RFC 2833)
90 * @FS_DTMF_METHOD_SOUND: Send as tones as in-band audio sound
91 *
92 * An enum that represents the different ways a DTMF event can be sent
93 *
94 */
95 typedef enum _FsDTMFMethod
96 {
97 FS_DTMF_METHOD_AUTO = 0,
98 FS_DTMF_METHOD_RTP_RFC4733,
99 FS_DTMF_METHOD_SOUND
100 } FsDTMFMethod;
101
102 /**
103 * FsSessionClass:
104 * @parent_class: Our parent
105 * @new_stream: Create a new #FsStream
106 * @start_telephony_event: Starts a telephony event
107 * @stop_telephony_event: Stops a telephony event
108 * @set_send_codec: Forces sending with a specific codec
109 * @set_codec_preferences: Specifies the codec preferences
110 * @list_transmitters: Returns a list of the available transmitters
111 * @get_stream_transmitter_type: Returns the GType of the stream transmitter
112 * @codecs_need_resend: Returns the list of codecs that need resending
113 *
114 * You must override at least new_stream in a subclass.
115 */
116
117
118 struct _FsSessionClass
119 {
120 GstObjectClass parent_class;
121
122 /*virtual functions */
123 FsStream *(* new_stream) (FsSession *session,
124 FsParticipant *participant,
125 FsStreamDirection direction,
126 GError **error);
127
128 gboolean (* start_telephony_event) (FsSession *session, guint8 event,
129 guint8 volume, FsDTMFMethod method);
130 gboolean (* stop_telephony_event) (FsSession *session, FsDTMFMethod method);
131
132 gboolean (* set_send_codec) (FsSession *session, FsCodec *send_codec,
133 GError **error);
134 gboolean (* set_codec_preferences) (FsSession *session,
135 GList *codec_preferences,
136 GError **error);
137
138 gchar** (* list_transmitters) (FsSession *session);
139
140 GType (* get_stream_transmitter_type) (FsSession *session,
141 const gchar *transmitter);
142
143 GList* (* codecs_need_resend) (FsSession *session, GList *old_codecs,
144 GList *new_codecs);
145
146 /*< private >*/
147 gpointer _padding[8];
148 };
149
150 /**
151 * FsSession:
152 *
153 * All members are private, access them using methods and properties
154 */
155 struct _FsSession
156 {
157 GstObject parent;
158 /*< private >*/
159
160 FsSessionPrivate *priv;
161
162
163 gpointer _padding[8];
164 };
165
166 GType fs_session_get_type (void);
167
168 FsStream *fs_session_new_stream (FsSession *session,
169 FsParticipant *participant,
170 FsStreamDirection direction,
171 GError **error);
172
173 gboolean fs_session_start_telephony_event (FsSession *session, guint8 event,
174 guint8 volume, FsDTMFMethod method);
175
176 gboolean fs_session_stop_telephony_event (FsSession *session,
177 FsDTMFMethod method);
178
179 gboolean fs_session_set_send_codec (FsSession *session, FsCodec *send_codec,
180 GError **error);
181
182 gboolean fs_session_set_codec_preferences (FsSession *session,
183 GList *codec_preferences,
184 GError **error);
185
186 gchar **fs_session_list_transmitters (FsSession *session);
187
188 void fs_session_emit_error (FsSession *session,
189 gint error_no,
190 const gchar *error_msg);
191
192 GType fs_session_get_stream_transmitter_type (FsSession *session,
193 const gchar *transmitter);
194
195 GList* fs_session_codecs_need_resend (FsSession *session,
196 GList *old_codecs, GList *new_codecs);
197
198 void fs_session_destroy (FsSession *session);
199
200
201 G_END_DECLS
202
203 #endif /* __FS_SESSION_H__ */
0 /*
1 * Farstream - Farstream Stream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream-transmitter.c - A Farstream Stream Transmitter gobject
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-stream-transmitter
26 * @short_description: A stream transmitter object used to convey per-stream
27 * information to a transmitter.
28 *
29 * This object is the base implementation of a Farstream Stream Transmitter.
30 * It needs to be derived and implement by a Farstream transmitter.
31 * A Farstream Stream transmitter is used to convery per-stream information
32 * to a transmitter, this is mostly local and remote candidates
33 *
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "fs-stream-transmitter.h"
41
42 #include <gst/gst.h>
43
44 #include "fs-marshal.h"
45 #include "fs-conference.h"
46 #include "fs-private.h"
47
48 #define GST_CAT_DEFAULT fs_conference_debug
49
50 /* Signals */
51 enum
52 {
53 ERROR_SIGNAL,
54 NEW_LOCAL_CANDIDATE,
55 NEW_ACTIVE_CANDIDATE_PAIR,
56 LOCAL_CANDIDATES_PREPARED,
57 KNOWN_SOURCE_PACKET_RECEIVED,
58 STATE_CHANGED,
59 LAST_SIGNAL
60 };
61
62 /* props */
63 enum
64 {
65 PROP_0,
66 PROP_SENDING,
67 PROP_PREFERRED_LOCAL_CANDIDATES,
68 PROP_ASSOCIATE_ON_SOURCE
69 };
70
71 struct _FsStreamTransmitterPrivate
72 {
73 gboolean disposed;
74 };
75
76 G_DEFINE_ABSTRACT_TYPE(FsStreamTransmitter, fs_stream_transmitter,
77 GST_TYPE_OBJECT);
78
79
80 #define FS_STREAM_TRANSMITTER_GET_PRIVATE(o) \
81 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_STREAM_TRANSMITTER, \
82 FsStreamTransmitterPrivate))
83
84 static void fs_stream_transmitter_get_property (GObject *object,
85 guint prop_id,
86 GValue *value,
87 GParamSpec *pspec);
88 static void fs_stream_transmitter_set_property (GObject *object,
89 guint prop_id,
90 const GValue *value,
91 GParamSpec *pspec);
92
93 static guint signals[LAST_SIGNAL] = { 0 };
94
95 static void
96 fs_stream_transmitter_class_init (FsStreamTransmitterClass *klass)
97 {
98 GObjectClass *gobject_class;
99
100 gobject_class = (GObjectClass *) klass;
101
102 gobject_class->set_property = fs_stream_transmitter_set_property;
103 gobject_class->get_property = fs_stream_transmitter_get_property;
104
105
106 /**
107 * FsStreamTransmitter:sending:
108 *
109 * A network source #GstElement to be used by the #FsSession
110 *
111 */
112 g_object_class_install_property (gobject_class,
113 PROP_SENDING,
114 g_param_spec_boolean ("sending",
115 "Whether to send from this transmitter",
116 "If set to FALSE, the transmitter will stop sending to this person",
117 TRUE,
118 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
119
120 /**
121 * FsStreamTransmitter:preferred-local-candidate:
122 *
123 * The list of preferred local candidates for this stream
124 * It is a #GList of #FsCandidates
125 *
126 */
127 g_object_class_install_property (gobject_class,
128 PROP_PREFERRED_LOCAL_CANDIDATES,
129 g_param_spec_boxed ("preferred-local-candidates",
130 "The preferred candidates",
131 "A GList of FsCandidates",
132 FS_TYPE_CANDIDATE_LIST,
133 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
134
135 /**
136 * FsStreamTransmitter:associate-on-source
137 *
138 * This tells the stream transmitter to associate incoming data with this
139 * based on the source without looking at the content if possible.
140 *
141 */
142
143 g_object_class_install_property (gobject_class,
144 PROP_ASSOCIATE_ON_SOURCE,
145 g_param_spec_boolean ("associate-on-source",
146 "Associate incoming data based on the source address",
147 "Whether to associate incoming data stream based on the source address",
148 TRUE,
149 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150
151 /**
152 * FsStreamTransmitter::error:
153 * @self: #FsStreamTransmitter that emitted the signal
154 * @errorno: The number of the error
155 * @error_msg: Error message (for the programmer)
156 *
157 * This signal is emitted in any error condition
158 *
159 */
160 signals[ERROR_SIGNAL] = g_signal_new ("error",
161 G_TYPE_FROM_CLASS (klass),
162 G_SIGNAL_RUN_LAST,
163 0,
164 NULL,
165 NULL,
166 _fs_marshal_VOID__ENUM_STRING,
167 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
168
169 /**
170 * FsStreamTransmitter::new-active-candidate-pair:
171 * @self: #FsStreamTransmitter that emitted the signal
172 * @local_candidate: #FsCandidate of the local candidate being used
173 * @remote_candidate: #FsCandidate of the remote candidate being used
174 *
175 * This signal is emitted when there is a new active chandidate pair that has
176 * been established. This is specially useful for ICE where the active
177 * candidate pair can change automatically due to network conditions. The user
178 * must not modify the candidates and must copy them if he wants to use them
179 * outside the callback scope.
180 *
181 */
182 signals[NEW_ACTIVE_CANDIDATE_PAIR] = g_signal_new
183 ("new-active-candidate-pair",
184 G_TYPE_FROM_CLASS (klass),
185 G_SIGNAL_RUN_LAST,
186 0,
187 NULL,
188 NULL,
189 _fs_marshal_VOID__BOXED_BOXED,
190 G_TYPE_NONE, 2, FS_TYPE_CANDIDATE, FS_TYPE_CANDIDATE);
191
192 /**
193 * FsStreamTransmitter::new-local-candidate:
194 * @self: #FsStream that emitted the signal
195 * @local_candidate: #FsCandidate of the local candidate
196 *
197 * This signal is emitted when a new local candidate is discovered.
198 *
199 */
200 signals[NEW_LOCAL_CANDIDATE] = g_signal_new
201 ("new-local-candidate",
202 G_TYPE_FROM_CLASS (klass),
203 G_SIGNAL_RUN_LAST,
204 0,
205 NULL,
206 NULL,
207 g_cclosure_marshal_VOID__BOXED,
208 G_TYPE_NONE, 1, FS_TYPE_CANDIDATE);
209
210 /**
211 * FsStreamTransmitter::local-candidates-prepared:
212 * @self: #FsStreamTransmitter that emitted the signal
213 *
214 * This signal is emitted when all local candidates have been
215 * prepared, an ICE implementation would send its SDP offer or answer.
216 *
217 */
218 signals[LOCAL_CANDIDATES_PREPARED] = g_signal_new
219 ("local-candidates-prepared",
220 G_TYPE_FROM_CLASS (klass),
221 G_SIGNAL_RUN_LAST,
222 0,
223 NULL,
224 NULL,
225 g_cclosure_marshal_VOID__VOID,
226 G_TYPE_NONE, 0);
227
228 /**
229 * FsStreamTransmitter::known-source-packet-received:
230 * @self: #FsStreamTransmitter that emitted the signal
231 * @component: The Component on which this buffer was received
232 * @buffer: the #GstBuffer coming from the known source
233 *
234 * This signal is emitted when a buffer coming from a confirmed known source
235 * is received.
236 */
237 signals[KNOWN_SOURCE_PACKET_RECEIVED] = g_signal_new
238 ("known-source-packet-received",
239 G_TYPE_FROM_CLASS (klass),
240 G_SIGNAL_RUN_LAST,
241 0,
242 NULL,
243 NULL,
244 _fs_marshal_VOID__UINT_POINTER,
245 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
246
247
248 /**
249 * FsStreamTransmitter::state-changed
250 * @self: #FsStreamTransmitter that emitted the signal
251 * @component: the id of the component which state has changed
252 * @state: the new state of the component
253 *
254 * This signal is emitted when the ICE state (or equivalent) of the component
255 * changes
256 */
257 signals[STATE_CHANGED] = g_signal_new
258 ("state-changed",
259 G_TYPE_FROM_CLASS (klass),
260 G_SIGNAL_RUN_LAST,
261 0,
262 NULL,
263 NULL,
264 _fs_marshal_VOID__UINT_ENUM,
265 G_TYPE_NONE, 2, G_TYPE_UINT, FS_TYPE_STREAM_STATE);
266
267
268 g_type_class_add_private (klass, sizeof (FsStreamTransmitterPrivate));
269 }
270
271 static void
272 fs_stream_transmitter_init (FsStreamTransmitter *self)
273 {
274 /* member init */
275 self->priv = FS_STREAM_TRANSMITTER_GET_PRIVATE (self);
276 self->priv->disposed = FALSE;
277 }
278
279 static void
280 fs_stream_transmitter_get_property (GObject *object,
281 guint prop_id,
282 GValue *value,
283 GParamSpec *pspec)
284 {
285 GST_WARNING ("Subclass %s of FsStreamTransmitter does not override the %s"
286 " property getter",
287 G_OBJECT_TYPE_NAME(object),
288 g_param_spec_get_name (pspec));
289 }
290
291 static void
292 fs_stream_transmitter_set_property (GObject *object,
293 guint prop_id,
294 const GValue *value,
295 GParamSpec *pspec)
296 {
297 switch (prop_id)
298 {
299 /* These properties, we can safely not override */
300 case PROP_ASSOCIATE_ON_SOURCE:
301 break;
302 default:
303 GST_WARNING ("Subclass %s of FsStreamTransmitter does not override the %s"
304 " property setter",
305 G_OBJECT_TYPE_NAME(object),
306 g_param_spec_get_name (pspec));
307 break;
308 }
309 }
310
311
312 /**
313 * fs_stream_transmitter_add_remote_candidates
314 * @streamtransmitter: a #FsStreamTranmitter
315 * @candidates: (element-type FsCandidate): a #GList of the remote candidates
316 * @error: location of a #GError, or NULL if no error occured
317 *
318 * This function is used to add remote candidates to the transmitter
319 *
320 * Returns: TRUE of the candidate could be added, FALSE if it couldnt
321 * (and the #GError will be set)
322 */
323
324 gboolean
325 fs_stream_transmitter_add_remote_candidates (
326 FsStreamTransmitter *streamtransmitter,
327 GList *candidates,
328 GError **error)
329 {
330 FsStreamTransmitterClass *klass;
331
332 g_return_val_if_fail (streamtransmitter, FALSE);
333 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
334 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
335
336 if (klass->add_remote_candidates) {
337 return klass->add_remote_candidates (streamtransmitter, candidates, error);
338 } else {
339 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
340 "add_remote_candidate not defined in stream transmitter class");
341 }
342
343 return FALSE;
344 }
345
346 /**
347 * fs_stream_transmitter_force_remote_candidates:
348 * @streamtransmitter: a #FsStreamTransmitter
349 * @remote_candidates: (element-type FsCandidate): a #GList of #FsCandidate to
350 * force
351 * @error: location of a #GError, or NULL if no error occured
352 *
353 * This function forces data to be sent immediately to the selected remote
354 * candidate, by-passing any connectivity checks. There should be at most
355 * one candidate per component.
356 *
357 * Returns: %TRUE if the candidates could be forced, %FALSE otherwise
358 */
359
360 gboolean
361 fs_stream_transmitter_force_remote_candidates (
362 FsStreamTransmitter *streamtransmitter,
363 GList *remote_candidates,
364 GError **error)
365 {
366 FsStreamTransmitterClass *klass;
367
368 g_return_val_if_fail (streamtransmitter, FALSE);
369 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
370 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
371
372 if (klass->force_remote_candidates) {
373 return klass->force_remote_candidates (streamtransmitter,
374 remote_candidates, error);
375 } else {
376 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
377 "force_remote_candidates not defined in stream transmitter class");
378 }
379
380 return FALSE;
381 }
382
383 /**
384 * fs_stream_transmitter_gather_local_candidates:
385 * @streamtransmitter: a #FsStreamTransmitter
386 * @error: location of a #GErrorh, or NULL if no error occured
387 *
388 * This function tells the transmitter to start gathering local candidates,
389 * signals for new candidates and newly active candidates can be emitted
390 * during the call to this function.
391 *
392 * Returns: %TRUE if it succeeds (or is not implemented), %FALSE otherwise
393 */
394
395 gboolean
396 fs_stream_transmitter_gather_local_candidates (
397 FsStreamTransmitter *streamtransmitter,
398 GError **error)
399 {
400 FsStreamTransmitterClass *klass;
401
402 g_return_val_if_fail (streamtransmitter, FALSE);
403 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
404 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
405
406 if (klass->gather_local_candidates)
407 return klass->gather_local_candidates (streamtransmitter, error);
408 else
409 return TRUE;
410 }
411
412
413
414 /**
415 * fs_stream_transmitter_stop:
416 * @streamtransmitter: a #FsStreamTransmitter
417 *
418 * This functions stops the #FsStreamTransmitter, it must be called before
419 * the last reference is dropped.
420 */
421
422 void
423 fs_stream_transmitter_stop (FsStreamTransmitter *streamtransmitter)
424 {
425 FsStreamTransmitterClass *klass;
426
427 g_return_if_fail (streamtransmitter);
428 g_return_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter));
429 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
430
431 if (klass->stop)
432 klass->stop (streamtransmitter);
433 }
434
435
436 /**
437 * fs_stream_transmitter_emit_error:
438 * @streamtransmitter: #FsStreamTransmitter on which to emit the error signal
439 * @error_no: The number of the error
440 * @error_msg: Error message (for the programmer)
441 *
442 * This function emit the "error" signal on a #FsStreamTransmitter, it should
443 * only be called by subclasses.
444 */
445 void
446 fs_stream_transmitter_emit_error (FsStreamTransmitter *streamtransmitter,
447 gint error_no,
448 const gchar *error_msg)
449 {
450 g_signal_emit (streamtransmitter, signals[ERROR_SIGNAL], 0, error_no,
451 error_msg);
452 }
0 /*
1 * Farstream - Farstream Stream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream-transmitter.h - A Farstream Stream Transmitter (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_STREAM_TRANSMITTER_H__
25 #define __FS_STREAM_TRANSMITTER_H__
26
27 #include <gst/gst.h>
28
29 #include <farstream/fs-candidate.h>
30
31 G_BEGIN_DECLS
32
33 /* TYPE MACROS */
34 #define FS_TYPE_STREAM_TRANSMITTER \
35 (fs_stream_transmitter_get_type ())
36 #define FS_STREAM_TRANSMITTER(obj) \
37 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_STREAM_TRANSMITTER, \
38 FsStreamTransmitter))
39 #define FS_STREAM_TRANSMITTER_CLASS(klass) \
40 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_STREAM_TRANSMITTER, \
41 FsStreamTransmitterClass))
42 #define FS_IS_STREAM_TRANSMITTER(obj) \
43 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_STREAM_TRANSMITTER))
44 #define FS_IS_STREAM_TRANSMITTER_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_STREAM_TRANSMITTER))
46 #define FS_STREAM_TRANSMITTER_GET_CLASS(obj) \
47 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_STREAM_TRANSMITTER, \
48 FsStreamTransmitterClass))
49 #define FS_STREAM_TRANSMITTER_CAST(obj) ((FsStreamTransmitter *) (obj))
50
51 typedef struct _FsStreamTransmitter FsStreamTransmitter;
52 typedef struct _FsStreamTransmitterClass FsStreamTransmitterClass;
53 typedef struct _FsStreamTransmitterPrivate FsStreamTransmitterPrivate;
54
55 /**
56 * FsStreamTransmitterClass:
57 * @parent_class: Our parent
58 * @add_remote_candidates: Sets the remote candidates
59 * @force_remote_candidates: Forces certain remote candidates
60 * @gather_local_candidates: Starts the gathering of local candidates
61 * @stop: Stop the stream transmitter synchronously (does any Gst stopping
62 * that needs to be done)
63 *
64 * You must override the add_remote_candidate in a subclass
65 */
66
67 struct _FsStreamTransmitterClass
68 {
69 GstObjectClass parent_class;
70
71 /*virtual functions */
72 gboolean (*add_remote_candidates) (FsStreamTransmitter *streamtransmitter,
73 GList *candidates, GError **error);
74
75 gboolean (*force_remote_candidates) (FsStreamTransmitter *streamtransmitter,
76 GList *remote_candidates,
77 GError **error);
78 gboolean (*gather_local_candidates) (FsStreamTransmitter *streamtransmitter,
79 GError **error);
80 void (*stop) (FsStreamTransmitter *streamtransmitter);
81
82 /*< private >*/
83 gpointer _padding[8];
84 };
85
86 /**
87 * FsStreamTransmitter:
88 *
89 * All members are private, access them using methods and properties
90 */
91 struct _FsStreamTransmitter
92 {
93 GstObject parent;
94
95 /*< private >*/
96 FsStreamTransmitterPrivate *priv;
97 gpointer _padding[8];
98 };
99
100 GType fs_stream_transmitter_get_type (void);
101
102 gboolean fs_stream_transmitter_add_remote_candidates (
103 FsStreamTransmitter *streamtransmitter,
104 GList *candidates,
105 GError **error);
106
107 gboolean fs_stream_transmitter_force_remote_candidates (
108 FsStreamTransmitter *streamtransmitter,
109 GList *remote_candidates,
110 GError **error);
111
112 gboolean
113 fs_stream_transmitter_gather_local_candidates (
114 FsStreamTransmitter *streamtransmitter,
115 GError **error);
116
117 void fs_stream_transmitter_stop (FsStreamTransmitter *streamtransmitter);
118
119 void fs_stream_transmitter_emit_error (FsStreamTransmitter *streamtransmitter,
120 gint error_no,
121 const gchar *error_msg);
122
123 G_END_DECLS
124
125 #endif /* __FS_STREAM_TRANSMITTER_H__ */
0 /*
1 * Farstream - Farstream Stream
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream.c - A Farstream Stream gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-stream
26 * @short_description: A stream in a session in a conference
27 *
28 * This object is the base implementation of a Farstream Stream. It
29 * needs to be derived and implemented by a Farstream conference GStreamer
30 * element. A Farstream Stream is a media stream originating from a
31 * #FsParticipant inside a #FsSession. In fact, a #FsStream instance is
32 * obtained by adding a participant into a session using
33 * fs_session_new_stream().
34 *
35 *
36 * This will communicate asynchronous events to the user through #GstMessage
37 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
38 * </para>
39 * <refsect2><title>The "<literal>farstream-new-local-candidate</literal>" message</title>
40 * |[
41 * "stream" #FsStream The stream that emits the message
42 * "candidate" #FsCandidate The new candidate
43 * ]|
44 * <para>
45 * This message is emitted when a new local candidate is discovered.
46 * </para>
47 * </refsect2>
48 * <refsect2><title>The "<literal>farstream-local-candidates-prepared</literal>" message</title>
49 * |[
50 * "stream" #FsStream The stream that emits the message
51 * ]|
52 * <para>
53 * This signal is emitted when all local candidates have been
54 * prepared, an ICE implementation would send its SDP offer or answer.
55 * </para>
56 * </refsect2>
57 * <refsect2><title>The "<literal>farstream-new-active-candidate-pair</literal>" message</title>
58 * |[
59 * "stream" #FsStream The stream that emits the message
60 * "local-candidate" #FsCandidate Local candidate being used
61 * "remote-candidate" #FsCandidate Remote candidate being used
62 * ]|
63 * <para>
64 * This message is emitted when there is a new active candidate pair that has
65 * been established. This is specially useful for ICE where the active
66 * candidate pair can change automatically due to network conditions. The user
67 * must not modify the candidates and must copy them if he wants to use them
68 * outside the callback scope. This message is emitted once per component.
69 * </para>
70 * </refsect2>
71 * <refsect2><title>The "<literal>farstream-recv-codecs-changed</literal>" message</title>
72 * |[
73 * "stream" #FsStream The stream that emits the message
74 * "codecs" #FsCodecGList A #GList of #FsCodec
75 * ]|
76 * <para>
77 * This message is emitted when the content of the
78 * #FsStream:current-recv-codecs property changes. It is normally emitted
79 * right after the #FsStream::src-pad-added signal only if that codec was not
80 * previously received in this stream, but it can also be emitted if the pad
81 * already exists, but the source material that will come to it is different.
82 * The list of new recv-codecs is included in the message
83 * </para>
84 * </refsect2>
85 * <refsect2><title>The "<literal>farstream-component-state-changed</literal>" message</title>
86 * |[
87 * "stream" #FsStream The stream that emits the message
88 * "component" #guint The component whose state changed
89 * "state" #FsStreamState The new state of the component
90 * ]|
91 * <para>
92 * This message is emitted the state of a component of a stream changes.
93 * </para>
94 * </refsect2>
95 * <para>
96 */
97
98 #ifdef HAVE_CONFIG_H
99 #include "config.h"
100 #endif
101
102 #include "fs-stream.h"
103
104 #include <gst/gst.h>
105
106 #include "fs-session.h"
107 #include "fs-marshal.h"
108 #include "fs-codec.h"
109 #include "fs-candidate.h"
110 #include "fs-stream-transmitter.h"
111 #include "fs-conference.h"
112 #include "fs-enumtypes.h"
113 #include "fs-private.h"
114
115 /* Signals */
116 enum
117 {
118 ERROR_SIGNAL,
119 SRC_PAD_ADDED,
120 LAST_SIGNAL
121 };
122
123 /* props */
124 enum
125 {
126 PROP_0,
127 PROP_REMOTE_CODECS,
128 PROP_NEGOTIATED_CODECS,
129 PROP_CURRENT_RECV_CODECS,
130 PROP_DIRECTION,
131 PROP_PARTICIPANT,
132 PROP_SESSION
133 };
134
135
136 struct _FsStreamPrivate
137 {
138 GMutex *mutex;
139 GList *src_pads;
140 guint32 src_pads_cookie;
141 };
142
143 #define FS_STREAM_GET_PRIVATE(o) \
144 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_STREAM, FsStreamPrivate))
145
146
147 G_DEFINE_ABSTRACT_TYPE(FsStream, fs_stream, GST_TYPE_OBJECT);
148
149 static void fs_stream_get_property (GObject *object,
150 guint prop_id,
151 GValue *value,
152 GParamSpec *pspec);
153 static void fs_stream_set_property (GObject *object,
154 guint prop_id,
155 const GValue *value,
156 GParamSpec *pspec);
157 static void fs_stream_finalize (GObject *obj);
158
159 static guint signals[LAST_SIGNAL] = { 0 };
160
161 #define FS_STREAM_LOCK(self) g_mutex_lock((self)->priv->mutex)
162 #define FS_STREAM_UNLOCK(self) g_mutex_unlock((self)->priv->mutex)
163
164 static void
165 fs_stream_class_init (FsStreamClass *klass)
166 {
167 GObjectClass *gobject_class;
168
169 gobject_class = (GObjectClass *) klass;
170
171 gobject_class->set_property = fs_stream_set_property;
172 gobject_class->get_property = fs_stream_get_property;
173 gobject_class->finalize = fs_stream_finalize;
174
175 /**
176 * FsStream:remote-codecs:
177 *
178 * Type: GLib.List<FsCodec>
179 * Transfer: full
180 *
181 * This is the list of remote codecs for this stream. They must be set by the
182 * user as soon as they are known using fs_stream_set_remote_codecs()
183 * (generally through external signaling). It is a #GList of #FsCodec.
184 *
185 */
186 g_object_class_install_property (gobject_class,
187 PROP_REMOTE_CODECS,
188 g_param_spec_boxed ("remote-codecs",
189 "List of remote codecs",
190 "A GList of FsCodecs of the remote codecs",
191 FS_TYPE_CODEC_LIST,
192 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
193
194 /**
195 * FsStream:negotiated-codecs:
196 *
197 * Type: GLib.List<FsCodec>
198 * Transfer: full
199 *
200 * This is the list of negotiatied codecs, it is the same list as the list
201 * of #FsCodec from the parent #FsSession, except that the codec config data
202 * has been replaced with the data from the remote codecs for this stream.
203 * This is the list of #FsCodec used to receive data from this stream.
204 * It is a #GList of #FsCodec.
205 *
206 */
207 g_object_class_install_property (gobject_class,
208 PROP_NEGOTIATED_CODECS,
209 g_param_spec_boxed ("negotiated-codecs",
210 "List of remote codecs",
211 "A GList of FsCodecs of the negotiated codecs for this stream",
212 FS_TYPE_CODEC_LIST,
213 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
214
215 /**
216 * FsStream:current-recv-codecs:
217 *
218 * Type: GLib.List<FsCodec>
219 * Transfer: full
220 *
221 * This is the list of codecs that have been received by this stream.
222 * The user must free the list if fs_codec_list_destroy().
223 * The "farstream-recv-codecs-changed" message is send on the #GstBus
224 * when the value of this property changes.
225 * It is normally emitted right after #FsStream::src-pad-added
226 * only if that codec was not previously received in this stream, but it can
227 * also be emitted if the pad already exists, but the source material that
228 * will come to it is different.
229 *
230 */
231 g_object_class_install_property (gobject_class,
232 PROP_CURRENT_RECV_CODECS,
233 g_param_spec_boxed ("current-recv-codecs",
234 "The codecs currently being received",
235 "A GList of FsCodec representing the codecs that have been received",
236 FS_TYPE_CODEC_LIST,
237 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
238
239 /**
240 * FsStream:direction:
241 *
242 * The direction of the stream. This property is set initially as a parameter
243 * to the fs_session_new_stream() function. It can be changed later if
244 * required by setting this property.
245 *
246 */
247 g_object_class_install_property (gobject_class,
248 PROP_DIRECTION,
249 g_param_spec_flags ("direction",
250 "The direction of the stream",
251 "An enum to set and get the direction of the stream",
252 FS_TYPE_STREAM_DIRECTION,
253 FS_DIRECTION_NONE,
254 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
255
256 /**
257 * FsStream:participant:
258 *
259 * The #FsParticipant for this stream. This property is a construct param and
260 * is read-only construction.
261 *
262 */
263 g_object_class_install_property (gobject_class,
264 PROP_PARTICIPANT,
265 g_param_spec_object ("participant",
266 "The participant of the stream",
267 "An FsParticipant represented by the stream",
268 FS_TYPE_PARTICIPANT,
269 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
270
271 /**
272 * FsStream:session:
273 *
274 * The #FsSession for this stream. This property is a construct param and
275 * is read-only construction.
276 *
277 */
278 g_object_class_install_property (gobject_class,
279 PROP_SESSION,
280 g_param_spec_object ("session",
281 "The session of the stream",
282 "An FsSession represented by the stream",
283 FS_TYPE_SESSION,
284 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
285
286 /**
287 * FsStream::error:
288 * @self: #FsStream that emitted the signal
289 * @errorno: The number of the error
290 * @error_msg: Error message to be displayed to user
291 *
292 * This signal is emitted in any error condition
293 *
294 */
295 signals[ERROR_SIGNAL] = g_signal_new ("error",
296 G_TYPE_FROM_CLASS (klass),
297 G_SIGNAL_RUN_LAST,
298 0,
299 NULL,
300 NULL,
301 _fs_marshal_VOID__ENUM_STRING,
302 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
303
304 /**
305 * FsStream::src-pad-added:
306 * @self: #FsStream that emitted the signal
307 * @pad: #GstPad of the new source pad
308 * @codec: #FsCodec of the codec being received on the new source pad
309 *
310 * This signal is emitted when a new gst source pad has been created for a
311 * specific codec being received. There will be a different source pad for
312 * each codec that is received. The user must ref the #GstPad if he wants to
313 * keep it. The user should not modify the #FsCodec and must copy it if he
314 * wants to use it outside the callback scope.
315 *
316 * This signal is not emitted on the main thread, but on GStreamer's streaming
317 * thread!
318 *
319 */
320 signals[SRC_PAD_ADDED] = g_signal_new ("src-pad-added",
321 G_TYPE_FROM_CLASS (klass),
322 G_SIGNAL_RUN_LAST,
323 0,
324 NULL,
325 NULL,
326 _fs_marshal_VOID__BOXED_BOXED,
327 G_TYPE_NONE, 2, GST_TYPE_PAD, FS_TYPE_CODEC);
328
329 g_type_class_add_private (klass, sizeof (FsStreamPrivate));
330 }
331
332 static void
333 fs_stream_init (FsStream *self)
334 {
335 /* member init */
336 self->priv = FS_STREAM_GET_PRIVATE (self);
337 self->priv->mutex = g_mutex_new ();
338 }
339
340 static void
341 fs_stream_finalize (GObject *obj)
342 {
343 FsStream *stream = FS_STREAM (obj);
344
345 g_list_free (stream->priv->src_pads);
346 g_mutex_free (stream->priv->mutex);
347
348 G_OBJECT_CLASS (fs_stream_parent_class)->finalize (obj);
349 }
350
351 static void
352 fs_stream_get_property (GObject *object,
353 guint prop_id,
354 GValue *value,
355 GParamSpec *pspec)
356 {
357 GST_WARNING ("Subclass %s of FsStream does not override the %s property"
358 " getter",
359 G_OBJECT_TYPE_NAME(object),
360 g_param_spec_get_name (pspec));
361 }
362
363 static void
364 fs_stream_set_property (GObject *object,
365 guint prop_id,
366 const GValue *value,
367 GParamSpec *pspec)
368 {
369 GST_WARNING ("Subclass %s of FsStream does not override the %s property"
370 " setter",
371 G_OBJECT_TYPE_NAME(object),
372 g_param_spec_get_name (pspec));
373 }
374
375 /**
376 * fs_stream_add_remote_candidates:
377 * @stream: an #FsStream
378 * @candidates: (element-type FsCandidate): an #GList of #FsCandidate
379 * representing the remote candidates
380 * @error: location of a #GError, or %NULL if no error occured
381 *
382 * This function adds remote candidates. Any new candidates are
383 * added to the list. The candidates will be used to establish a connection
384 * with the peer. A copy will be made so the user must free the
385 * passed candidate using fs_candidate_destroy() when done.
386 *
387 * Return value: TRUE if the candidate was valid, FALSE otherwise
388 */
389 gboolean
390 fs_stream_add_remote_candidates (FsStream *stream,
391 GList *candidates,
392 GError **error)
393 {
394 FsStreamClass *klass;
395
396 g_return_val_if_fail (stream, FALSE);
397 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
398 klass = FS_STREAM_GET_CLASS (stream);
399
400 if (klass->add_remote_candidates) {
401 return klass->add_remote_candidates (stream, candidates, error);
402 } else {
403 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
404 "add_remote_candidate not defined in class");
405 }
406
407 return FALSE;
408 }
409
410 /**
411 * fs_stream_force_remote_candidates:
412 * @stream: a #FsStream
413 * @remote_candidates: (element-type FsCandidate):
414 * a #GList of #FsCandidate to force
415 * @error: location of a #GError, or %NULL if no error occured
416 *
417 * This function forces data to be sent immediately to the selected remote
418 * candidate, by-passing any connectivity checks. There should be at most
419 * one candidate per component.
420 *
421 * Returns: %TRUE if the candidates could be forced, %FALSE otherwise
422 */
423
424 gboolean
425 fs_stream_force_remote_candidates (FsStream *stream,
426 GList *remote_candidates,
427 GError **error)
428 {
429 FsStreamClass *klass;
430
431 g_return_val_if_fail (stream, FALSE);
432 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
433 klass = FS_STREAM_GET_CLASS (stream);
434
435 if (klass->force_remote_candidates) {
436 return klass->force_remote_candidates (stream,
437 remote_candidates,
438 error);
439 } else {
440 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
441 "force_remote_candidates not defined in class");
442 }
443
444 return FALSE;
445 }
446
447 /**
448 * fs_stream_set_remote_codecs:
449 * @stream: a #FsStream
450 * @remote_codecs: (element-type FsCodec): a #GList of #FsCodec representing
451 * the remote codecs
452 * @error: location of a #GError, or %NULL if no error occured
453 *
454 * This function will set the list of remote codecs for this stream. If
455 * the given remote codecs couldn't be negotiated with the list of local
456 * codecs or already negotiated codecs for the corresponding #FsSession, @error
457 * will be set and %FALSE will be returned. The @remote_codecs list will be
458 * copied so it must be free'd using fs_codec_list_destroy() when done.
459 *
460 * Returns: %FALSE if the remote codecs couldn't be set.
461 */
462 gboolean
463 fs_stream_set_remote_codecs (FsStream *stream,
464 GList *remote_codecs, GError **error)
465 {
466 FsStreamClass *klass;
467
468 g_return_val_if_fail (stream, FALSE);
469 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
470 klass = FS_STREAM_GET_CLASS (stream);
471
472 if (klass->set_remote_codecs) {
473 return klass->set_remote_codecs (stream, remote_codecs, error);
474 } else {
475 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
476 "set_remote_codecs not defined in class");
477 }
478
479 return FALSE;
480 }
481
482 /**
483 * fs_stream_add_id:
484 * @stream: a #FsStream
485 * @id: The id to add to the stream
486 *
487 * This function is used to add data identifiers that allow the
488 * plugin to recognize packets that are meant for id. For example, in RTP,
489 * one would set the SSRCs that are expected.
490 *
491 * Depending on the protocol, one may be able to add more than one ID
492 * to a stream (in RTP you can have multiple SSRCs in a stream).
493 * If a protocol supports only one id, adding a new one will overwrite it.
494 * If an ID was already set on a stream, adding it to another stream will
495 * override the previdous decision.
496 *
497 * For most protocols, calling this function is optional as the incoming data
498 * can be matched with a stream by its source IP address. This is mostly useful
499 * if one is using multicast or is behind a muxer server.
500 */
501 void
502 fs_stream_add_id (FsStream *stream,
503 guint id)
504 {
505 FsStreamClass *klass;
506
507 g_return_if_fail (stream);
508 g_return_if_fail (FS_IS_STREAM (stream));
509 klass = FS_STREAM_GET_CLASS (stream);
510
511 if (klass->add_id)
512 klass->add_id (stream, id);
513 }
514
515 /**
516 * fs_stream_emit_error:
517 * @stream: #FsStream on which to emit the error signal
518 * @error_no: The number of the error
519 * @error_msg: Error message to be displayed to user
520 *
521 * This function emits the #FsStream::error" signal, it should only be
522 * called by subclasses.
523 */
524 void
525 fs_stream_emit_error (FsStream *stream,
526 gint error_no,
527 const gchar *error_msg)
528 {
529 g_signal_emit (stream, signals[ERROR_SIGNAL], 0, error_no, error_msg);
530 }
531
532
533 static void
534 src_pad_parent_unset (GstObject *srcpad, GstObject *parent, gpointer user_data)
535 {
536 FsStream *stream = FS_STREAM (user_data);
537
538 FS_STREAM_LOCK (stream);
539 stream->priv->src_pads = g_list_remove (stream->priv->src_pads, srcpad);
540 stream->priv->src_pads_cookie++;
541 FS_STREAM_UNLOCK (stream);
542 }
543
544 /**
545 * fs_stream_emit_src_pad_added:
546 * @stream: #FsStream on which to emit the src-pad-added signal
547 * @pad: the #GstPad that this #FsStream has created
548 * @codec: The #FsCodec for this pad
549 *
550 * Emits the #FsStream::src-pad-added" signal, it should only be
551 * called by subclasses.
552 */
553
554 void
555 fs_stream_emit_src_pad_added (FsStream *stream,
556 GstPad *pad,
557 FsCodec *codec)
558 {
559 FS_STREAM_LOCK (stream);
560 g_assert (!g_list_find (stream->priv->src_pads, pad));
561 stream->priv->src_pads = g_list_append (stream->priv->src_pads, pad);
562 stream->priv->src_pads_cookie++;
563 g_signal_connect_object (pad, "parent-unset",
564 G_CALLBACK (src_pad_parent_unset), stream, 0);
565 FS_STREAM_UNLOCK (stream);
566
567 g_signal_emit (stream, signals[SRC_PAD_ADDED], 0, pad, codec);
568 }
569
570 static GstIteratorItem
571 src_pad_iterator_item_func (GstIterator*iter, gpointer item)
572 {
573 gst_object_ref (item);
574
575 return GST_ITERATOR_ITEM_PASS;
576 }
577
578 /**
579 * fs_stream_iterate_src_pads:
580 * @stream: a #FsStream
581 *
582 * Creates a #GstIterator that can be used to iterate the src pads of this
583 * stream. These are the pads that were announced by #FsStream:src-pad-added
584 * and are still valid.
585 *
586 * Returns: (transfer full): The #GstIterator
587 */
588
589 GstIterator *
590 fs_stream_iterate_src_pads (FsStream *stream)
591 {
592 return gst_iterator_new_list (GST_TYPE_PAD, stream->priv->mutex,
593 &stream->priv->src_pads_cookie, &stream->priv->src_pads,
594 g_object_ref (stream), src_pad_iterator_item_func, g_object_unref);
595 }
596
597
598 /**
599 * fs_stream_set_transmitter:
600 * @stream: a #FsStream
601 * @transmitter: Name of the type of transmitter to use for this stream
602 * @stream_transmitter_n_parameters: Number of parametrs passed to the stream
603 * transmitter
604 * @stream_transmitter_parameters:
605 * (array length=stream_transmitter_n_parameters) (allow-none):
606 * an array of n_parameters #GParameter struct that will be passed
607 * to the newly-create #FsStreamTransmitter
608 * @error: location of a #GError, or %NULL if no error occured
609 *
610 * Set the transmitter to use for this stream. This function will only succeed
611 * once.
612 *
613 * Returns: %TRUE if the transmitter could be set, %FALSE otherwise
614 */
615
616 gboolean
617 fs_stream_set_transmitter (FsStream *stream,
618 const gchar *transmitter,
619 GParameter *stream_transmitter_parameters,
620 guint stream_transmitter_n_parameters,
621 GError **error)
622 {
623 FsStreamClass *klass;
624
625 g_return_val_if_fail (stream, FALSE);
626 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
627 klass = FS_STREAM_GET_CLASS (stream);
628
629 if (klass->set_transmitter)
630 return klass->set_transmitter (stream, transmitter,
631 stream_transmitter_parameters, stream_transmitter_n_parameters, error);
632
633
634 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
635 "set_transmitter not defined in class");
636
637 return FALSE;
638 }
639
640 /**
641 * fs_stream_destroy:
642 * @stream: a #FsStream
643 *
644 * This will cause the stream to remove all links to other objects and to
645 * remove itself from the #FsSession. Once a #FsStream has been destroyed, it
646 * can not be used anymore.
647 *
648 * It is strongly recommended to call this function from the main thread because
649 * releasing the application's reference to a stream.
650 */
651
652 void
653 fs_stream_destroy (FsStream *stream)
654 {
655 g_return_if_fail (stream);
656 g_return_if_fail (FS_IS_STREAM (stream));
657
658 g_object_run_dispose (G_OBJECT (stream));
659 }
0 /*
1 * Farstream - Farstream Stream
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream.h - A Farstream Stream (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_STREAM_H__
25 #define __FS_STREAM_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include <farstream/fs-candidate.h>
31 #include <farstream/fs-codec.h>
32
33 G_BEGIN_DECLS
34
35 /**
36 * FsStreamDirection:
37 * @FS_DIRECTION_NONE: No direction specified
38 * @FS_DIRECTION_SEND: Send only
39 * @FS_DIRECTION_RECV: Receive only
40 * @FS_DIRECTION_BOTH: Send and receive
41 *
42 * An enum for specifying the direction of a stream
43 *
44 */
45 typedef enum _FsStreamDirection
46 {
47 FS_DIRECTION_NONE = 0,
48 FS_DIRECTION_SEND = 1<<0,
49 FS_DIRECTION_RECV = 1<<1,
50 FS_DIRECTION_BOTH = FS_DIRECTION_SEND | FS_DIRECTION_RECV
51 } FsStreamDirection;
52
53 /**
54 * FsStreamState:
55 * @FS_STREAM_STATE_FAILED: connectivity checks have been completed,
56 * but connectivity was not established
57 * @FS_STREAM_STATE_DISCONNECTED: no activity scheduled
58 * @FS_STREAM_STATE_GATHERING: gathering local candidates
59 * @FS_STREAM_STATE_CONNECTING: establishing connectivity
60 * @FS_STREAM_STATE_CONNECTED: at least one working candidate pair
61 * @FS_STREAM_STATE_READY: ICE concluded, candidate pair selection is now final
62 *
63 * These are the possible states of a stream, a simple multicast stream
64 * could only be in "disconnected" or "ready" state.
65 * An stream using an ICE transmitter would use all of these.
66 */
67
68 typedef enum _FsStreamState
69 {
70 FS_STREAM_STATE_FAILED,
71 FS_STREAM_STATE_DISCONNECTED,
72 FS_STREAM_STATE_GATHERING,
73 FS_STREAM_STATE_CONNECTING,
74 FS_STREAM_STATE_CONNECTED,
75 FS_STREAM_STATE_READY
76 } FsStreamState;
77
78 /* TYPE MACROS */
79 #define FS_TYPE_STREAM \
80 (fs_stream_get_type ())
81 #define FS_STREAM(obj) \
82 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_STREAM, FsStream))
83 #define FS_STREAM_CLASS(klass) \
84 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_STREAM, FsStreamClass))
85 #define FS_IS_STREAM(obj) \
86 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_STREAM))
87 #define FS_IS_STREAM_CLASS(klass) \
88 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_STREAM))
89 #define FS_STREAM_GET_CLASS(obj) \
90 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_STREAM, FsStreamClass))
91 #define FS_STREAM_CAST(obj) ((FsStream *) (obj))
92
93 typedef struct _FsStream FsStream;
94 typedef struct _FsStreamClass FsStreamClass;
95 typedef struct _FsStreamPrivate FsStreamPrivate;
96
97
98 /**
99 * FsStreamClass:
100 * @parent_class: Our parent
101 * @add_remote_candidates: Set sthe remote candidates
102 * @force_remote_candidates: Forces certain remote candidates
103 * @set_remote_codecs: Sets the list of remote codecs
104 * @add_id: Add a known id to be associated with this stream
105 * @set_transmitter: Set the transmitter to use for this stream
106 *
107 * You must override add_remote_candidate in a subclass.
108 * If you have to negotiate codecs, then you must override set_remote_codecs too
109 */
110
111 struct _FsStreamClass
112 {
113 GstObjectClass parent_class;
114
115 /*virtual functions */
116 gboolean (*add_remote_candidates) (FsStream *stream,
117 GList *candidates,
118 GError **error);
119
120 gboolean (*force_remote_candidates) (FsStream *stream,
121 GList *remote_candidates,
122 GError **error);
123
124 gboolean (*set_remote_codecs) (FsStream *stream,
125 GList *remote_codecs, GError **error);
126
127 void (*add_id) (FsStream *stream,
128 guint id);
129
130 gboolean (*set_transmitter) (FsStream *stream,
131 const gchar *transmitter,
132 GParameter *stream_transmitter_parameters,
133 guint stream_transmitter_n_parameters,
134 GError **error);
135
136 /*< private >*/
137 gpointer _padding[8];
138 };
139
140 /**
141 * FsStream:
142 *
143 * All members are private, access them using methods and properties
144 */
145 struct _FsStream
146 {
147 GstObject parent;
148
149 /*< private >*/
150
151 FsStreamPrivate *priv;
152
153 gpointer _padding[8];
154 };
155
156 GType fs_stream_get_type (void);
157
158 gboolean fs_stream_add_remote_candidates (FsStream *stream,
159 GList *candidates,
160 GError **error);
161
162 gboolean fs_stream_force_remote_candidates (FsStream *stream,
163 GList *remote_candidates,
164 GError **error);
165
166 gboolean fs_stream_set_remote_codecs (FsStream *stream,
167 GList *remote_codecs, GError **error);
168
169 void fs_stream_add_id (FsStream *stream, guint id);
170
171 void fs_stream_emit_error (FsStream *stream,
172 gint error_no,
173 const gchar *error_msg);
174
175 void fs_stream_emit_src_pad_added (FsStream *stream,
176 GstPad *pad,
177 FsCodec *codec);
178
179 GstIterator *fs_stream_iterate_src_pads (FsStream *stream);
180
181 gboolean fs_stream_set_transmitter (FsStream *stream,
182 const gchar *transmitter,
183 GParameter *stream_transmitter_parameters,
184 guint stream_transmitter_n_parameters,
185 GError **error);
186
187 void fs_stream_destroy (FsStream *stream);
188
189 G_END_DECLS
190
191 #endif /* __FS_STREAM_H__ */
0 /*
1 * Farstream - Farstream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-transmitter.c - A Farstream Transmitter gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-transmitter
26 * @short_description: A transmitter object linked to a session
27 *
28 * This object is the base implementation of a Farstream Transmitter.
29 * It needs to be derived and implement by a Farstream transmitter. A
30 * Farstream Transmitter provides a GStreamer network sink and source to be used
31 * for the Farstream Session. It creates #FsStreamTransmitter objects which are
32 * used to set the different per-stream properties
33 *
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "fs-transmitter.h"
41
42 #include <gst/gst.h>
43
44 #include "fs-marshal.h"
45 #include "fs-plugin.h"
46 #include "fs-conference.h"
47 #include "fs-private.h"
48
49 /* Signals */
50 enum
51 {
52 ERROR_SIGNAL,
53 GET_RECVONLY_FILTER_SIGNAL,
54 LAST_SIGNAL
55 };
56
57 /* props */
58 enum
59 {
60 PROP_0,
61 PROP_GST_SINK,
62 PROP_GST_SRC,
63 PROP_COMPONENTS,
64 PROP_TYPE_OF_SERVICE
65 };
66
67 /*
68 struct _FsTransmitterPrivate
69 {
70 };
71 */
72
73 G_DEFINE_ABSTRACT_TYPE(FsTransmitter, fs_transmitter, GST_TYPE_OBJECT);
74
75 #define FS_TRANSMITTER_GET_PRIVATE(o) \
76 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_TRANSMITTER, FsTransmitterPrivate))
77
78 static void fs_transmitter_get_property (GObject *object,
79 guint prop_id,
80 GValue *value,
81 GParamSpec *pspec);
82 static void fs_transmitter_set_property (GObject *object,
83 guint prop_id,
84 const GValue *value,
85 GParamSpec *pspec);
86
87 static guint signals[LAST_SIGNAL] = { 0 };
88
89
90 static void
91 fs_transmitter_class_init (FsTransmitterClass *klass)
92 {
93 GObjectClass *gobject_class;
94
95 _fs_conference_init_debug ();
96
97 gobject_class = (GObjectClass *) klass;
98
99 gobject_class->set_property = fs_transmitter_set_property;
100 gobject_class->get_property = fs_transmitter_get_property;
101
102
103
104 /**
105 * FsTransmitter:gst-src:
106 *
107 * A network source #GstElement to be used by the #FsSession
108 * This element MUST provide a source pad named "src%d" per component.
109 * These pads number must start at 1 (the %d corresponds to the component
110 * number).
111 * These pads MUST be static pads.
112 *
113 */
114 g_object_class_install_property (gobject_class,
115 PROP_GST_SRC,
116 g_param_spec_object ("gst-src",
117 "The network source",
118 "A source GstElement to be used by a FsSession",
119 GST_TYPE_ELEMENT,
120 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
121
122 /**
123 * FsTransmitter:gst-sink:
124 *
125 * A network source #GstElement to be used by the #FsSession
126 * These element's sink must have async=FALSE
127 * This element MUST provide a pad named "sink\%d" per component.
128 * These pads number must start at 1 (the \%d corresponds to the component
129 * number).
130 * These pads MUST be static pads.
131 *
132 */
133 g_object_class_install_property (gobject_class,
134 PROP_GST_SINK,
135 g_param_spec_object ("gst-sink",
136 "The network source",
137 "A source GstElement to be used by a FsSession",
138 GST_TYPE_ELEMENT,
139 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
140
141 /**
142 * FsTransmitter:components:
143 *
144 * The number of components to create
145 */
146 g_object_class_install_property (gobject_class,
147 PROP_COMPONENTS,
148 g_param_spec_uint ("components",
149 "Number of componnets",
150 "The number of components to create",
151 1, 255, 1,
152 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153
154 /**
155 * FsTransmitter:tos:
156 *
157 * Sets the IP ToS field (and if possible the IPv6 TCLASS field
158 */
159 g_object_class_install_property (gobject_class,
160 PROP_TYPE_OF_SERVICE,
161 g_param_spec_uint ("tos",
162 "IP Type of Service",
163 "The IP Type of Service to set on sent packets",
164 0, 255, 0,
165 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
166
167 /**
168 * FsTransmitter::error:
169 * @self: #FsTransmitter that emitted the signal
170 * @errorno: The number of the error
171 * @error_msg: Error message to be displayed to user
172 *
173 * This signal is emitted in any error condition
174 *
175 */
176 signals[ERROR_SIGNAL] = g_signal_new ("error",
177 G_TYPE_FROM_CLASS (klass),
178 G_SIGNAL_RUN_LAST,
179 0,
180 NULL,
181 NULL,
182 _fs_marshal_VOID__ENUM_STRING,
183 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
184
185 /**
186 * FsTransmitter::get-recvonly-filter
187 * @self: #FsTransmitter that emitted the signal
188 * @component: The component that the filter will be used for
189 *
190 * This signal is emitted when the transmitter wants to get a filter for
191 * to use if sending is disabled. If you want to drop all buffers, just
192 * don't listen to the signal.
193 *
194 * This element should have a "sending" property that can be changed with the
195 * sending state of the stream. It should default to %TRUE.
196 *
197 * Returns: (transfer full) (allow-none): the #GstElement to use as the
198 * filter, or %NULL to drop everything
199 */
200
201 signals[GET_RECVONLY_FILTER_SIGNAL] = g_signal_new ("get-recvonly-filter",
202 G_TYPE_FROM_CLASS (klass),
203 G_SIGNAL_RUN_LAST,
204 0,
205 NULL,
206 NULL,
207 _fs_marshal_OBJECT__UINT,
208 GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
209
210
211 //g_type_class_add_private (klass, sizeof (FsTransmitterPrivate));
212 }
213
214 static void
215 fs_transmitter_init (FsTransmitter *self)
216 {
217 // self->priv = FS_TRANSMITTER_GET_PRIVATE (self);
218 }
219
220 static void
221 fs_transmitter_get_property (GObject *object,
222 guint prop_id,
223 GValue *value,
224 GParamSpec *pspec)
225 {
226 GST_WARNING ("Subclass %s of FsTransmitter does not override the %s property"
227 " getter",
228 G_OBJECT_TYPE_NAME(object),
229 g_param_spec_get_name (pspec));
230 }
231
232 static void
233 fs_transmitter_set_property (GObject *object,
234 guint prop_id,
235 const GValue *value,
236 GParamSpec *pspec)
237 {
238 GST_WARNING ("Subclass %s of FsTransmitter does not override the %s property"
239 " setter",
240 G_OBJECT_TYPE_NAME(object),
241 g_param_spec_get_name (pspec));
242 }
243
244
245 /**
246 * fs_transmitter_new_stream_transmitter:
247 * @transmitter: a #FsTranmitter
248 * @participant: the #FsParticipant for which the #FsStream using this
249 * new #FsStreamTransmitter is created
250 * @n_parameters: The number of parameters to pass to the newly created
251 * #FsStreamTransmitter
252 * @parameters: an array of #GParameter
253 * @error: location of a #GError, or NULL if no error occured
254 *
255 * This function will create a new #FsStreamTransmitter element for a
256 * specific participant for this #FsTransmitter
257 *
258 * Returns: (transfer full): a new #FsStreamTransmitter, or NULL if there is an
259 * error
260 */
261
262 FsStreamTransmitter *
263 fs_transmitter_new_stream_transmitter (FsTransmitter *transmitter,
264 FsParticipant *participant,
265 guint n_parameters,
266 GParameter *parameters,
267 GError **error)
268 {
269 FsTransmitterClass *klass;
270
271 g_return_val_if_fail (transmitter, NULL);
272 g_return_val_if_fail (FS_IS_TRANSMITTER (transmitter), NULL);
273 klass = FS_TRANSMITTER_GET_CLASS (transmitter);
274 g_return_val_if_fail (klass->new_stream_transmitter, NULL);
275
276
277 return klass->new_stream_transmitter (transmitter, participant,
278 n_parameters, parameters, error);
279
280 return NULL;
281 }
282
283 /**
284 * fs_transmitter_new:
285 * @type: The type of transmitter to create
286 * @components: The number of components to create
287 * @tos: The Type of Service of the socket, max is 255
288 * @error: location of a #GError, or NULL if no error occured
289 *
290 * This function creates a new transmitter of the requested type.
291 * It will load the appropriate plugin as required.
292 *
293 * Returns: a newly-created #FsTransmitter of the requested type
294 * (or NULL if there is an error)
295 */
296
297 FsTransmitter *
298 fs_transmitter_new (const gchar *type,
299 guint components,
300 guint tos,
301 GError **error)
302 {
303 FsTransmitter *self = NULL;
304
305 g_return_val_if_fail (type != NULL, NULL);
306 g_return_val_if_fail (tos <= 255, NULL);
307
308 self = FS_TRANSMITTER (fs_plugin_create (type, "transmitter", error,
309 "components", components,
310 "tos", tos,
311 NULL));
312
313 if (!self)
314 return NULL;
315
316 if (self->construction_error) {
317 g_propagate_error(error, self->construction_error);
318 g_object_unref (self);
319 self = NULL;
320 }
321
322 return self;
323 }
324
325 /**
326 * fs_transmitter_get_stream_transmitter_type:
327 * @transmitter: A #FsTransmitter object
328 *
329 * This function returns the GObject type for the stream transmitter.
330 * This is meant for bindings that need to introspect the type of arguments
331 * that can be passed to the _new_stream_transmitter.
332 *
333 * Returns: the #GType
334 */
335
336 GType
337 fs_transmitter_get_stream_transmitter_type (FsTransmitter *transmitter)
338 {
339 FsTransmitterClass *klass;
340
341 g_return_val_if_fail (transmitter, 0);
342 g_return_val_if_fail (FS_IS_TRANSMITTER (transmitter), 0);
343 klass = FS_TRANSMITTER_GET_CLASS (transmitter);
344 g_return_val_if_fail (klass->get_stream_transmitter_type, 0);
345
346 return klass->get_stream_transmitter_type (transmitter);
347 }
348
349
350 /**
351 * fs_transmitter_emit_error:
352 * @transmitter: #FsTransmitter on which to emit the error signal
353 * @error_no: The number of the error
354 * @error_msg: Error message to be displayed to user
355 *
356 * This function emit the "error" signal on a #FsTransmitter, it should
357 * only be called by subclasses.
358 */
359 void
360 fs_transmitter_emit_error (FsTransmitter *transmitter,
361 gint error_no,
362 const gchar *error_msg)
363 {
364 g_signal_emit (transmitter, signals[ERROR_SIGNAL], 0, error_no,
365 error_msg);
366 }
367
368 /**
369 * fs_transmitter_list_available:
370 *
371 * Get the list of all available transmitters
372 *
373 * Returns: (transfer full): a newly allocated array of strings containing the
374 * list of all available transmitters or %NULL if there are none. It should
375 * be freed with g_strfreev().
376 */
377
378 char **
379 fs_transmitter_list_available (void)
380 {
381 return fs_plugin_list_available ("transmitter");
382 }
383
384 /**
385 * fs_transmitter_get_recvonly_filter:
386 * @transmitter: A #FsTransmitter object
387 * @component: The component to get the filter for
388 *
389 * Get the filter to add on the send pipeline if sending is disabled.
390 *
391 * Only for use by subclasses.
392 *
393 * Returns: (transfer full) (allow-none): a #GstElement to use as the filter or
394 * %NULL
395 */
396
397 GstElement *
398 fs_transmitter_get_recvonly_filter (FsTransmitter *transmitter,
399 guint component)
400 {
401 GstElement *element = NULL;
402
403 g_signal_emit (transmitter, signals[GET_RECVONLY_FILTER_SIGNAL], 0, component,
404 &element);
405
406 return element;
407 }
0 /*
1 * Farstream - Farstream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-transmitter.h - A Farstream Transmitter (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_TRANSMITTER_H__
25 #define __FS_TRANSMITTER_H__
26
27 #include <gst/gst.h>
28
29 #include <farstream/fs-participant.h>
30 #include <farstream/fs-session.h>
31 #include <farstream/fs-stream-transmitter.h>
32
33 G_BEGIN_DECLS
34
35 /* TYPE MACROS */
36 #define FS_TYPE_TRANSMITTER \
37 (fs_transmitter_get_type ())
38 #define FS_TRANSMITTER(obj) \
39 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_TRANSMITTER, FsTransmitter))
40 #define FS_TRANSMITTER_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_TRANSMITTER, FsTransmitterClass))
42 #define FS_IS_TRANSMITTER(obj) \
43 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_TRANSMITTER))
44 #define FS_IS_TRANSMITTER_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_TRANSMITTER))
46 #define FS_TRANSMITTER_GET_CLASS(obj) \
47 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_TRANSMITTER, FsTransmitterClass))
48 #define FS_TRANSMITTER_CAST(obj) ((FsTransmitter *) (obj))
49
50 typedef struct _FsTransmitter FsTransmitter;
51 typedef struct _FsTransmitterClass FsTransmitterClass;
52 typedef struct _FsTransmitterPrivate FsTransmitterPrivate;
53
54 /**
55 * FsTransmitterClass:
56 * @parent_class: Our parent
57 * @new_stream_transmitter: Creates a new #FsStreamTransmitter
58 * @get_stream_transmitter_type: Returns the #GType of the stream transmitter
59 * created by this class (useful for bindings)
60 *
61 * You must override both methods in a subclass.
62 */
63
64 struct _FsTransmitterClass
65 {
66 GstObjectClass parent_class;
67
68 /*virtual functions */
69 FsStreamTransmitter *(*new_stream_transmitter) (FsTransmitter *transmitter,
70 FsParticipant *participant,
71 guint n_parameters,
72 GParameter *parameters,
73 GError **error);
74 GType (*get_stream_transmitter_type) (FsTransmitter *transmitter);
75
76 /*< private >*/
77 gpointer _padding[8];
78 };
79
80 /**
81 * FsTransmitter:
82 *
83 * All members are private, access them using methods and properties
84 */
85 struct _FsTransmitter
86 {
87 GstObject parent;
88
89 /*< private >*/
90 FsTransmitterPrivate *priv;
91
92 /* This parameter should only be set by the construction methods
93 * of the subclasses
94 */
95 GError *construction_error;
96
97 gpointer _padding[8];
98 };
99
100 GType fs_transmitter_get_type (void);
101
102 FsStreamTransmitter *fs_transmitter_new_stream_transmitter (
103 FsTransmitter *transmitter, FsParticipant *participant,
104 guint n_parameters, GParameter *parameters, GError **error);
105
106 FsTransmitter *fs_transmitter_new (const gchar *type,
107 guint components,
108 guint tos,
109 GError **error);
110
111 GType fs_transmitter_get_stream_transmitter_type (FsTransmitter *transmitter);
112
113 void fs_transmitter_emit_error (FsTransmitter *transmitter,
114 gint error_no,
115 const gchar *error_msg);
116
117 char **fs_transmitter_list_available (void);
118
119 GstElement *
120 fs_transmitter_get_recvonly_filter (FsTransmitter *transmitter,
121 guint component);
122
123 G_END_DECLS
124
125 #endif /* __FS_TRANSMITTER_H__ */
0 /*
1 * Farstream - Miscellaneous useful functions
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include "fs-utils.h"
27
28 #include <string.h>
29
30 #include "fs-rtp.h"
31
32 /**
33 * SECTION:fs-utils
34 * @short_description: Miscellaneous useful functions
35 */
36
37 static GList *
38 load_default_codec_preferences_from_path (const gchar *element_name,
39 const gchar *path)
40 {
41 GList *codec_prefs = NULL;
42 gchar *filename;
43
44 filename = g_build_filename (path, PACKAGE, FS_MAJORMINOR, element_name,
45 "default-codec-preferences", NULL);
46 codec_prefs = fs_codec_list_from_keyfile (filename, NULL);
47 g_free (filename);
48
49 return codec_prefs;
50 }
51
52 static const gchar *
53 factory_name_from_element (GstElement *element)
54 {
55 GstElementFactory *factory = gst_element_get_factory (element);
56
57 if (factory)
58 return gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
59 else
60 return NULL;
61 }
62
63 /**
64 * fs_utils_get_default_codec_preferences:
65 * @element: Element for which to fetch default codec preferences
66 *
67 * These default codec preferences should work with the elements that are
68 * available in the main GStreamer element repositories.
69 * They should be suitable for standards based protocols like SIP or XMPP.
70 *
71 * Returns: (element-type FsCodec) (transfer full):
72 * The default codec preferences for this plugin.
73 * This #GList should be freed with fs_codec_list_destroy()
74 */
75 GList *
76 fs_utils_get_default_codec_preferences (GstElement *element)
77 {
78 const gchar * const * system_data_dirs = g_get_system_data_dirs ();
79 GList *codec_prefs = NULL;
80 guint i;
81 const gchar *factory_name = factory_name_from_element (element);
82
83 if (!factory_name)
84 return NULL;
85
86 codec_prefs = load_default_codec_preferences_from_path (factory_name,
87 g_get_user_data_dir ());
88 if (codec_prefs)
89 return codec_prefs;
90
91 for (i = 0; system_data_dirs[i]; i++)
92 {
93 codec_prefs = load_default_codec_preferences_from_path (factory_name,
94 system_data_dirs[i]);
95 if (codec_prefs)
96 return codec_prefs;
97 }
98
99 return NULL;
100 }
101
102 /**
103 * fs_utils_get_default_element_properties: (skip):
104 * @element: Element for which to fetch default element properties
105 *
106 * This function produces a #GKeyFile that can be fed to
107 * fs_element_added_notifier_set_properties_from_keyfile(). If no
108 * default properties have been found, it will return %NULL.
109 *
110 * Returns: a #GKeyFile containing the default element
111 * properties for this element or %NULL if no properties were found.
112 * Caller must free the #GKeyFile when he is done.
113 */
114
115 GKeyFile *
116 fs_utils_get_default_element_properties (GstElement *element)
117 {
118 gboolean file_loaded;
119 GKeyFile *keyfile = g_key_file_new ();
120 gchar *filename;
121 const gchar *factory_name = factory_name_from_element (element);
122
123 filename = g_build_filename (PACKAGE, FS_MAJORMINOR, factory_name,
124 "default-element-properties", NULL);
125 file_loaded = g_key_file_load_from_data_dirs (keyfile, filename, NULL,
126 G_KEY_FILE_NONE, NULL);
127 g_free (filename);
128
129 if (file_loaded)
130 {
131 return keyfile;
132 }
133 else
134 {
135 g_key_file_free (keyfile);
136 return NULL;
137 }
138 }
139
140 /**
141 * fs_utils_set_bitrate:
142 * @element: The #GstElement
143 * @bitrate: The bitrate in bits/sec
144 *
145 * This allows setting the bitrate on all elements that have a "bitrate"
146 * property without having to know the type or of the unit used by that element.
147 *
148 * This will be obsolete in 0.11 (when all elements use bit/sec for the
149 * "bitrate" property.
150 */
151
152 void
153 fs_utils_set_bitrate (GstElement *element, glong bitrate)
154 {
155 GParamSpec *spec;
156 const char *elements_in_kbps[] = { "lamemp3enc", "lame", "x264enc", "twolame",
157 "mpeg2enc", NULL
158 };
159 int i;
160 GstElementFactory *factory;
161 const gchar *factory_name = NULL;
162
163 g_return_if_fail (GST_IS_ELEMENT (element));
164
165 spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "bitrate");
166 g_return_if_fail (spec != NULL);
167
168 factory = gst_element_get_factory (element);
169 if (factory)
170 factory_name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
171
172 /* divide by 1000 for elements that are known to use kbs */
173 for (i = 0; elements_in_kbps[i]; i++)
174 if (factory_name && !strcmp (factory_name, elements_in_kbps[i]))
175 {
176 bitrate /= 1000;
177 break;
178 }
179
180 if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_LONG)
181 {
182 g_object_set (element, "bitrate", (glong) CLAMP (bitrate,
183 G_PARAM_SPEC_LONG (spec)->minimum,
184 G_PARAM_SPEC_LONG (spec)->maximum), NULL);
185 }
186 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_ULONG)
187 {
188 g_object_set (element, "bitrate", (gulong) CLAMP (bitrate,
189 G_PARAM_SPEC_ULONG (spec)->minimum,
190 G_PARAM_SPEC_ULONG (spec)->maximum), NULL);
191 }
192 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_INT)
193 {
194 gint tmp = MIN (bitrate, G_MAXINT);
195
196 g_object_set (element, "bitrate", (gint) CLAMP (tmp,
197 G_PARAM_SPEC_INT (spec)->minimum,
198 G_PARAM_SPEC_INT (spec)->maximum), NULL);
199 }
200 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_UINT)
201 {
202 guint tmp = MIN (bitrate, G_MAXUINT);
203
204 g_object_set (element, "bitrate", (guint) CLAMP (tmp,
205 G_PARAM_SPEC_UINT (spec)->minimum,
206 G_PARAM_SPEC_UINT (spec)->maximum), NULL);
207 }
208 else
209 {
210 g_warning ("bitrate parameter of unknown type");
211 }
212 }
213
214 static GList *
215 load_default_rtp_hdrext_preferences_from_path (const gchar *element_name,
216 const gchar *path, FsMediaType media_type)
217 {
218 GList *rtp_hdrext_prefs = NULL;
219 gchar *filename;
220
221 filename = g_build_filename (path, PACKAGE, FS_MAJORMINOR, element_name,
222 "default-codec-preferences", NULL);
223 rtp_hdrext_prefs = fs_rtp_header_extension_list_from_keyfile (filename,
224 media_type, NULL);
225 g_free (filename);
226
227 return rtp_hdrext_prefs;
228 }
229
230 /**
231 * fs_utils_get_default_rtp_header_extension_preferences
232 * @element: Element for which to fetch default RTP Header Extension preferences
233 * @media_type: The #FsMediaType for which to get default RTP Header Extension
234 * preferences
235 *
236 * These default rtp header extension preferences should work with the elements
237 * that are available in the main GStreamer element repositories.
238 * They should be suitable for standards based protocols like SIP or XMPP.
239 *
240 * Returns: (element-type FsCodec) (transfer full): The default rtp
241 * header extension preferences for this plugin, this #GList should be
242 * freed with fs_codec_list_destroy()
243 */
244 GList *
245 fs_utils_get_default_rtp_header_extension_preferences (GstElement *element,
246 FsMediaType media_type)
247 {
248 const gchar * const * system_data_dirs = g_get_system_data_dirs ();
249 GList *rtp_hdrext_prefs = NULL;
250 guint i;
251 const gchar *factory_name = factory_name_from_element (element);
252
253 if (!factory_name)
254 return NULL;
255
256 rtp_hdrext_prefs = load_default_rtp_hdrext_preferences_from_path (
257 factory_name, g_get_user_data_dir (), media_type);
258 if (rtp_hdrext_prefs)
259 return rtp_hdrext_prefs;
260
261 for (i = 0; system_data_dirs[i]; i++)
262 {
263 rtp_hdrext_prefs = load_default_rtp_hdrext_preferences_from_path (
264 factory_name, system_data_dirs[i], media_type);
265 if (rtp_hdrext_prefs)
266 return rtp_hdrext_prefs;
267 }
268
269 return NULL;
270 }
0 /*
1 * Farstream - Miscellaneous useful functions
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23
24 #ifndef __FS_UTILS_H__
25 #define __FS_UTILS_H__
26
27 #include <gst/gst.h>
28
29 #include <farstream/fs-codec.h>
30
31 G_BEGIN_DECLS
32
33 GList *fs_utils_get_default_codec_preferences (GstElement *element);
34
35 GKeyFile *fs_utils_get_default_element_properties (GstElement *element);
36
37 void fs_utils_set_bitrate (GstElement *element, glong bitrate);
38
39 GList *fs_utils_get_default_rtp_header_extension_preferences (
40 GstElement *element, FsMediaType media_type);
41
42 G_END_DECLS
43
44 #endif /* __FS_UTILS_H__ */
3737 libfsmsnconference_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
3838 libfsmsnconference_la_LIBADD = \
3939 libfsmsnconference-convenience.la \
40 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
40 $(top_builddir)/farstream/libfarstream-0.10.la \
4141 $(FS_LIBS) \
4242 $(GST_BASE_LIBS) \
4343 $(GST_LIBS) \
2626 #ifndef __FS_MSN_CONFERENCE_H__
2727 #define __FS_MSN_CONFERENCE_H__
2828
29 #include <gst/farstream/fs-conference.h>
29 #include <farstream/fs-conference.h>
3030
3131 G_BEGIN_DECLS
3232
2323 #ifndef __FS_MSN_PARTICIPANT_H__
2424 #define __FS_MSN_PARTICIPANT_H__
2525
26 #include <gst/farstream/fs-participant.h>
26 #include <farstream/fs-participant.h>
2727
2828 G_BEGIN_DECLS
2929
2727
2828 #include <gst/gst.h>
2929
30 #include <gst/farstream/fs-session.h>
30 #include <farstream/fs-session.h>
3131
3232 #include "fs-msn-conference.h"
3333
2525 #ifndef __FS_MSN_STREAM_H__
2626 #define __FS_MSN_STREAM_H__
2727
28 #include <gst/farstream/fs-stream.h>
28 #include <farstream/fs-stream.h>
2929
3030 #include "fs-msn-participant.h"
3131 #include "fs-msn-session.h"
3030 libfsrawconference_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
3131 libfsrawconference_la_LIBADD = \
3232 libfsrawconference-convenience.la \
33 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
33 $(top_builddir)/farstream/libfarstream-0.10.la \
3434 $(FS_LIBS) \
3535 $(GST_BASE_LIBS) \
3636 $(GST_LIBS)
2626 #ifndef __FS_RAW_CONFERENCE_H__
2727 #define __FS_RAW_CONFERENCE_H__
2828
29 #include <gst/farstream/fs-conference.h>
29 #include <farstream/fs-conference.h>
3030
3131 G_BEGIN_DECLS
3232
2525 #ifndef __FS_RAW_PARTICIPANT_H__
2626 #define __FS_RAW_PARTICIPANT_H__
2727
28 #include <gst/farstream/fs-participant.h>
28 #include <farstream/fs-participant.h>
2929
3030 G_BEGIN_DECLS
3131
4545 #include <string.h>
4646
4747 #include <gst/gst.h>
48 #include <gst/farstream/fs-transmitter.h>
48 #include <farstream/fs-transmitter.h>
4949
5050 #include "fs-raw-stream.h"
5151 #include "fs-raw-participant.h"
2828
2929 #include <gst/gst.h>
3030
31 #include <gst/farstream/fs-session.h>
31 #include <farstream/fs-session.h>
3232
3333 #include "fs-raw-conference.h"
3434
2626 #ifndef __FS_RAW_STREAM_H__
2727 #define __FS_RAW_STREAM_H__
2828
29 #include <gst/farstream/fs-stream.h>
30 #include <gst/farstream/fs-stream-transmitter.h>
29 #include <farstream/fs-stream.h>
30 #include <farstream/fs-stream-transmitter.h>
3131
3232 #include "fs-raw-participant.h"
3333 #include "fs-raw-session.h"
6161
6262 libfsrtpconference_la_LIBADD = \
6363 libfsrtpconference-convenience.la \
64 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
64 $(top_builddir)/farstream/libfarstream-0.10.la \
6565 $(FS_LIBS) \
6666 $(GST_PLUGINS_BASE_LIBS) \
6767 $(GST_LIBS) \
3434 #endif
3535 #include <stdio.h>
3636
37 #include <gst/farstream/fs-conference.h>
37 #include <farstream/fs-conference.h>
3838
3939 #include "fs-rtp-conference.h"
4040
2727
2828 #include "fs-rtp-codec-negotiation.h"
2929
30 #include <gst/farstream/fs-rtp.h>
30 #include <farstream/fs-rtp.h>
3131
3232 #include <string.h>
3333
2626 #include <glib.h>
2727 #include <gst/gst.h>
2828
29 #include <gst/farstream/fs-codec.h>
29 #include <farstream/fs-codec.h>
3030
3131 G_BEGIN_DECLS
3232
2525 #ifndef __FS_RTP_CONFERENCE_H__
2626 #define __FS_RTP_CONFERENCE_H__
2727
28 #include <gst/farstream/fs-conference.h>
28 #include <farstream/fs-conference.h>
2929
3030 G_BEGIN_DECLS
3131
3535
3636 #include <string.h>
3737
38 #include <gst/farstream/fs-conference.h>
38 #include <farstream/fs-conference.h>
3939
4040 #include "fs-rtp-conference.h"
4141 #include "fs-rtp-codec-cache.h"
2626
2727 #include <gst/gst.h>
2828
29 #include <gst/farstream/fs-codec.h>
29 #include <farstream/fs-codec.h>
3030
3131 G_BEGIN_DECLS
3232
2828
2929 #include "fs-rtp-dtmf-event-source.h"
3030
31 #include <gst/farstream/fs-conference.h>
31 #include <farstream/fs-conference.h>
3232
3333 #include "fs-rtp-conference.h"
3434 #include "fs-rtp-discover-codecs.h"
2828
2929 #include "fs-rtp-dtmf-sound-source.h"
3030
31 #include <gst/farstream/fs-conference.h>
31 #include <farstream/fs-conference.h>
3232
3333 #include "fs-rtp-conference.h"
3434 #include "fs-rtp-discover-codecs.h"
2626
2727 #include <gst/gst.h>
2828
29 #include <gst/farstream/fs-codec.h>
29 #include <farstream/fs-codec.h>
3030
3131 G_BEGIN_DECLS
3232
2424 #ifndef __FS_RTP_PARTICIPANT_H__
2525 #define __FS_RTP_PARTICIPANT_H__
2626
27 #include <gst/farstream/fs-participant.h>
27 #include <farstream/fs-participant.h>
2828
2929 G_BEGIN_DECLS
3030
6464 #include <gst/rtp/gstrtpbuffer.h>
6565 #include <gst/rtp/gstrtcpbuffer.h>
6666
67 #include <gst/farstream/fs-transmitter.h>
68 #include "gst/farstream/fs-utils.h"
69 #include <gst/farstream/fs-rtp.h>
67 #include <farstream/fs-transmitter.h>
68 #include "farstream/fs-utils.h"
69 #include <farstream/fs-rtp.h>
7070
7171 #include "fs-rtp-bitrate-adapter.h"
7272 #include "fs-rtp-stream.h"
2626
2727 #include <gst/gst.h>
2828
29 #include <gst/farstream/fs-session.h>
29 #include <farstream/fs-session.h>
3030
3131 #include "fs-rtp-conference.h"
3232
2828
2929 #include "fs-rtp-special-source.h"
3030
31 #include <gst/farstream/fs-conference.h>
31 #include <farstream/fs-conference.h>
3232
3333 #include "fs-rtp-conference.h"
3434 #include "fs-rtp-codec-negotiation.h"
2727
2828 #include <gst/gst.h>
2929
30 #include <gst/farstream/fs-session.h>
30 #include <farstream/fs-session.h>
3131
3232 G_BEGIN_DECLS
3333
3838
3939 #include <gst/gst.h>
4040
41 #include <gst/farstream/fs-rtp.h>
41 #include <farstream/fs-rtp.h>
4242
4343 #include "fs-rtp-marshal.h"
4444
2424 #ifndef __FS_RTP_STREAM_H__
2525 #define __FS_RTP_STREAM_H__
2626
27 #include <gst/farstream/fs-stream.h>
28 #include <gst/farstream/fs-stream-transmitter.h>
27 #include <farstream/fs-stream.h>
28 #include <farstream/fs-stream-transmitter.h>
2929
3030 #include "fs-rtp-participant.h"
3131 #include "fs-rtp-session.h"
2828
2929 #include "fs-rtp-substream.h"
3030
31 #include <gst/farstream/fs-stream.h>
32 #include <gst/farstream/fs-session.h>
31 #include <farstream/fs-stream.h>
32 #include <farstream/fs-session.h>
3333
3434 #include "fs-rtp-stream.h"
3535 #include "fs-rtp-marshal.h"
3030 #include <string.h>
3131
3232 #include "fs-rtp-packet-modder.h"
33 #include "gst/farstream/fs-rtp.h"
33 #include "farstream/fs-rtp.h"
3434 #include "fs-rtp-codec-negotiation.h"
3535
3636 #include <gst/rtp/gstrtpbuffer.h>
+0
-1
gst-libs/Makefile.am less more
0 SUBDIRS = gst
+0
-8
gst-libs/gst/Makefile.am less more
0 # The interfaces directory has to be built before the others,
1 # otherwise some generated header files will be missing for the
2 # plugins in the other directories.
3 # Also, the tag directory has to be built before the cdda directory.
4 SUBDIRS = \
5 farstream
6
7 noinst_HEADERS =
+0
-112
gst-libs/gst/farstream/Makefile.am less more
0 libfarstreamincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/farstream
1
2 libfarstreaminclude_HEADERS = \
3 fs-candidate.h \
4 fs-codec.h \
5 fs-participant.h \
6 fs-session.h \
7 fs-stream.h \
8 fs-conference.h \
9 fs-transmitter.h \
10 fs-stream-transmitter.h \
11 fs-plugin.h \
12 fs-element-added-notifier.h \
13 fs-utils.h \
14 fs-rtp.h
15
16 nodist_libfarstreaminclude_HEADERS = \
17 fs-enumtypes.h
18
19
20 lib_LTLIBRARIES = libfarstream-@GST_MAJORMINOR@.la
21
22 BUILT_SOURCES = \
23 $(nodist_libfarstream_@GST_MAJORMINOR@_la_SOURCES) \
24 $(nodist_libfarstreaminclude_HEADERS)
25
26 CLEANFILES = $(BUILT_SOURCES) fs-marshal.list
27
28 libfarstream_@GST_MAJORMINOR@_la_SOURCES = \
29 fs-candidate.c \
30 fs-codec.c \
31 fs-participant.c \
32 fs-session.c \
33 fs-stream.c \
34 fs-conference.c \
35 fs-transmitter.c \
36 fs-stream-transmitter.c \
37 fs-plugin.c \
38 fs-element-added-notifier.c \
39 fs-utils.c \
40 fs-rtp.c \
41 fs-private.h
42
43 nodist_libfarstream_@GST_MAJORMINOR@_la_SOURCES = \
44 fs-marshal.c \
45 fs-marshal.h \
46 fs-enumtypes.c
47
48
49 fs-marshal.list: $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) Makefile.am
50 $(AM_V_GEN) ( cd $(srcdir) && \
51 sed -n -e 's/.*_fs_marshal_\([[:upper:][:digit:]]*__[[:upper:][:digit:]_]*\).*/\1/p' \
52 $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) ) \
53 | sed -e 's/__/:/' -e 'y/_/,/' | sort -u > $@.tmp
54 @if cmp -s $@.tmp $@; then \
55 rm $@.tmp; \
56 touch $@; \
57 else \
58 mv $@.tmp $@; \
59 fi
60
61 libfarstream_@GST_MAJORMINOR@_la_CFLAGS = \
62 $(FS_INTERNAL_CFLAGS) $(FS_CFLAGS) \
63 $(GST_PLUGINS_BASE_CFLAGS) \
64 $(GST_BASE_CFLAGS) \
65 $(GST_CFLAGS)
66 libfarstream_@GST_MAJORMINOR@_la_LIBADD = \
67 $(GST_BASE_LIBS) \
68 $(GST_LIBS)
69 libfarstream_@GST_MAJORMINOR@_la_LDFLAGS = \
70 $(FS_LIB_LDFLAGS) \
71 $(FS_ALL_LDFLAGS) \
72 $(FS_LT_LDFLAGS)
73
74
75 public_headers = fs-candidate.h \
76 fs-codec.h \
77 fs-participant.h \
78 fs-session.h \
79 fs-stream.h \
80 fs-conference.h \
81 fs-utils.h
82
83 glib_enum_headers=$(public_headers)
84 glib_enum_define=FS
85 glib_gen_prefix=_fs
86 glib_gen_basename=fs
87
88 include $(top_srcdir)/common-modified/gst-glib-gen.mak
89
90 if HAVE_INTROSPECTION
91 include $(INTROSPECTION_MAKEFILE)
92 introspection_sources = \
93 $(libfarstream_@GST_MAJORMINOR@_la_SOURCES) \
94 $(nodist_libfarstreaminclude_HEADERS) \
95 $(libfarstreaminclude_HEADERS)
96
97 INTROSPECTION_GIRS = Farstream-@FS_MAJORMINOR@.gir
98 Farstream_0_1_gir_NAMESPACE = Farstream
99 Farstream_0_1_gir_VERSION = @FS_MAJORMINOR@
100 Farstream_0_1_gir_LIBS = libfarstream-@GST_MAJORMINOR@.la
101 Farstream_0_1_gir_FILES = $(introspection_sources)
102 Farstream_0_1_gir_INCLUDES = GObject-2.0 Gst-0.10
103 Farstream_0_1_gir_CFLAGS = $(FS_INTERNAL_CFLAGS)
104 Farstream_0_1_gir_SCANNERFLAGS = --identifier-prefix=fs_ --identifier-prefix=Fs
105
106 girdir = $(datadir)/gir-1.0
107 dist_gir_DATA = Farstream-@FS_MAJORMINOR@.gir
108 typelibdir = $(libdir)/girepository-1.0
109 typelib_DATA = Farstream-@FS_MAJORMINOR@.typelib
110 CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
111 endif
+0
-204
gst-libs/gst/farstream/fs-candidate.c less more
0 /*
1 * Farstream - Farstream Candidate
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-candidate.c - A Farstream candidate
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "fs-candidate.h"
29
30 /**
31 * SECTION:fs-candidate
32 * @short_description: Structure describing a transport candidate.
33 *
34 * An FsCandidate is a way to exchange candidate information between the client
35 * and Farstream. This description is compatible with ICE-13. It can also be a
36 * multicast address. Candidates are linked to streams. The information
37 * specified in this structure is usually representative of the codec
38 * information exchanged in the signaling.
39 */
40
41 GType
42 fs_candidate_get_type (void)
43 {
44 static GType candidate_type = 0;
45 if (candidate_type == 0)
46 {
47 candidate_type = g_boxed_type_register_static (
48 "FsCandidate",
49 (GBoxedCopyFunc)fs_candidate_copy,
50 (GBoxedFreeFunc)fs_candidate_destroy);
51 }
52
53 return candidate_type;
54 }
55
56 GType
57 fs_candidate_list_get_type (void)
58 {
59 static GType candidate_list_type = 0;
60 if (candidate_list_type == 0)
61 {
62 candidate_list_type = g_boxed_type_register_static (
63 "FsCandidateList",
64 (GBoxedCopyFunc)fs_candidate_list_copy,
65 (GBoxedFreeFunc)fs_candidate_list_destroy);
66 }
67
68 return candidate_list_type;
69 }
70
71 /**
72 * fs_candidate_destroy: (skip):
73 * @cand: a #FsCandidate to delete
74 *
75 * Frees a #FsCandidate and all its contents
76 */
77 void
78 fs_candidate_destroy (FsCandidate * cand)
79 {
80 if (cand == NULL)
81 return;
82
83 g_free ((gchar *) cand->foundation);
84 g_free ((gchar *) cand->ip);
85 g_free ((gchar *) cand->base_ip);
86 g_free ((gchar *) cand->username);
87 g_free ((gchar *) cand->password);
88
89 g_slice_free (FsCandidate, cand);
90 }
91
92 /**
93 * fs_candidate_copy:
94 * @cand: a #FsCandidate to copy
95 *
96 * Copies a #FsCandidate and its contents.
97 *
98 * Returns: a new #FsCandidate
99 */
100 FsCandidate *
101 fs_candidate_copy (const FsCandidate * cand)
102 {
103 FsCandidate *copy = g_slice_new0 (FsCandidate);
104
105 if (cand == NULL)
106 return NULL;
107
108 copy->component_id = cand->component_id;
109 copy->port = cand->port;
110 copy->base_port = cand->base_port;
111 copy->proto = cand->proto;
112 copy->priority = cand->priority;
113 copy->type = cand->type;
114 copy->ttl = cand->ttl;
115
116 copy->foundation = g_strdup (cand->foundation);
117 copy->ip = g_strdup (cand->ip);
118 copy->base_ip = g_strdup (cand->base_ip);
119 copy->username = g_strdup (cand->username);
120 copy->password = g_strdup (cand->password);
121
122 return copy;
123 }
124
125 /**
126 * fs_candidate_list_destroy: (skip):
127 * @candidate_list: A GList of #FsCandidate
128 *
129 * Deletes a GList of #FsCandidate and its contents
130 */
131 void
132 fs_candidate_list_destroy (GList *candidate_list)
133 {
134 GList *lp;
135 FsCandidate *cand;
136
137 for (lp = candidate_list; lp; lp = g_list_next (lp)) {
138 cand = (FsCandidate *) lp->data;
139 fs_candidate_destroy (cand);
140 lp->data = NULL;
141 }
142 g_list_free (candidate_list);
143 }
144
145 /**
146 * fs_candidate_list_copy:
147 * @candidate_list: (element-type FsCodec): A GList of #FsCandidate
148 *
149 * Copies a GList of #FsCandidate and its contents
150 *
151 * Returns: (element-type FsCodec) (transfer full): a new GList of #FsCandidate
152 */
153 GList *
154 fs_candidate_list_copy (const GList *candidate_list)
155 {
156 GQueue copy = G_QUEUE_INIT;
157 const GList *lp;
158
159 for (lp = candidate_list; lp; lp = g_list_next (lp)) {
160 FsCandidate *cand = lp->data;
161
162 g_queue_push_tail (&copy, fs_candidate_copy (cand));
163 }
164
165 return copy.head;
166 }
167
168 /**
169 * fs_candidate_new:
170 * @foundation: The foundation of the candidate
171 * @component_id: The component this candidate is for
172 * @type: The type of candidate
173 * @proto: The protocol this component is for
174 * @ip: The IP address of this component (can be NULL for local candidate to
175 * mean any address)
176 * @port: the UDP/TCP port
177 *
178 * Allocates a new #FsCandidate, the rest of the fields can be optionally
179 * filled manually.
180 *
181 * Returns: a newly-allocated #FsCandidate
182 */
183
184 FsCandidate *
185 fs_candidate_new (
186 const gchar *foundation,
187 guint component_id,
188 FsCandidateType type,
189 FsNetworkProtocol proto,
190 const gchar *ip,
191 guint port)
192 {
193 FsCandidate *candidate = g_slice_new0 (FsCandidate);
194
195 candidate->foundation = g_strdup (foundation);
196 candidate->component_id = component_id;
197 candidate->type = type;
198 candidate->proto = proto;
199 candidate->ip = g_strdup (ip);
200 candidate->port = port;
201
202 return candidate;
203 }
+0
-146
gst-libs/gst/farstream/fs-candidate.h less more
0 /*
1 * Farstream - Farstream Candidate
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-candidate.h - A Farstream candidate
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_CANDIDATE_H__
25 #define __FS_CANDIDATE_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 G_BEGIN_DECLS
31
32 #define FS_TYPE_CANDIDATE \
33 (fs_candidate_get_type ())
34
35
36 #define FS_TYPE_CANDIDATE_LIST \
37 (fs_candidate_list_get_type ())
38
39 /**
40 * FsCandidateType:
41 * @FS_CANDIDATE_TYPE_HOST: A host candidate (local)
42 * @FS_CANDIDATE_TYPE_SRFLX: A server reflexive candidate.
43 * @FS_CANDIDATE_TYPE_PRFLX: A peer reflexive candidate
44 * @FS_CANDIDATE_TYPE_RELAY: An relay candidate
45 * @FS_CANDIDATE_TYPE_MULTICAST: A multicast address
46 *
47 * An enum for the type of candidate used/reported
48 */
49 typedef enum _FsCandidateType
50 {
51 FS_CANDIDATE_TYPE_HOST,
52 FS_CANDIDATE_TYPE_SRFLX,
53 FS_CANDIDATE_TYPE_PRFLX,
54 FS_CANDIDATE_TYPE_RELAY, /* An external stream relay */
55 FS_CANDIDATE_TYPE_MULTICAST
56 } FsCandidateType;
57
58 /**
59 * FsNetworkProtocol:
60 * @FS_NETWORK_PROTOCOL_UDP: A UDP based protocol
61 * @FS_NETWORK_PROTOCOL_TCP: A TCP based protocol
62 *
63 * An enum for the base IP protocol
64 */
65 typedef enum _FsNetworkProtocol
66 {
67 FS_NETWORK_PROTOCOL_UDP,
68 FS_NETWORK_PROTOCOL_TCP
69 } FsNetworkProtocol;
70
71 /**
72 * FsComponentType:
73 * @FS_COMPONENT_NONE: Use this when specifying a component is innapropriate
74 * @FS_COMPONENT_RTP: This component is for RTP data
75 * @FS_COMPONENT_RTCP: This component is for RTCP control
76 *
77 * This enum contains the component IDs defined in ICE-19
78 */
79
80 typedef enum _FsComponentType
81 {
82 FS_COMPONENT_NONE = 0,
83 FS_COMPONENT_RTP = 1,
84 FS_COMPONENT_RTCP = 2
85 } FsComponentType;
86
87
88 typedef struct _FsCandidate FsCandidate;
89
90 /**
91 * FsCandidate:
92 * @foundation: a string representing the foundation of this candidate (maximum 32 chars)
93 * @component_id: value between 1 and 256 indicating which component this candidate represents (1 is RTP, 2 is RTCP, #FsComponentType can be used here)
94 * @ip: IP in dotted format
95 * @port: Port to use
96 * @base_ip: IP of base in dotted format as defined in ICE-19.
97 * @base_port: Port of base as defined in ICE-19.
98 * @proto: #FsNetworkProtocol for ip protocol to use as candidate
99 * @priority: Value between 0 and (2^31 - 1) representing the priority
100 * @type: The #FsCandidateType of the candidate
101 * @username: Username to use to connect to client if necessary,
102 * NULL otherwise
103 * @password: Username to use to connect to client if necessary,
104 * NULL otherwise
105 * @ttl: The TTL used when sending Multicast packet (0 = auto)
106 *
107 * Struct to hold information about ICE-19 compliant candidates
108 */
109 struct _FsCandidate
110 {
111 gchar *foundation;
112 guint component_id;
113 const gchar *ip;
114 guint16 port;
115 const gchar *base_ip;
116 guint16 base_port;
117 FsNetworkProtocol proto;
118 guint32 priority;
119 FsCandidateType type;
120 const gchar *username;
121 const gchar *password;
122 guint ttl;
123 };
124
125 GType fs_candidate_get_type (void);
126 GType fs_candidate_list_get_type (void);
127
128 void fs_candidate_destroy (FsCandidate *cand);
129
130 FsCandidate *fs_candidate_copy (const FsCandidate *cand);
131
132 void fs_candidate_list_destroy (GList *candidate_list);
133
134 GList *fs_candidate_list_copy (const GList *candidate_list);
135
136 FsCandidate * fs_candidate_new (
137 const gchar *foundation,
138 guint component_id,
139 FsCandidateType type,
140 FsNetworkProtocol proto,
141 const gchar *ip,
142 guint port);
143
144 G_END_DECLS
145 #endif /* __FS_CANDIDATE_H__ */
+0
-889
gst-libs/gst/farstream/fs-codec.c less more
0 /*
1 * Farstream - Farstream Codec
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * Copyright 2005 Collabora Ltd.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 *
10 * fs-codec.c - A Farstream codec
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "fs-codec.h"
32
33 #include <string.h>
34
35 #include "fs-private.h"
36
37 #define GST_CAT_DEFAULT fs_conference_debug
38
39 /**
40 * SECTION:fs-codec
41 * @short_description: Structure representing a media codec
42 *
43 * An #FsCodec is a way to exchange codec information between the client and
44 * Farstream. The information specified in this structure is usually
45 * representative of the codec information exchanged in the signaling.
46 *
47 */
48
49 /* TODO Make a fs_codec_new() function since there is a _destroy() */
50
51 GType
52 fs_codec_get_type (void)
53 {
54 static GType codec_type = 0;
55 if (codec_type == 0)
56 {
57 codec_type = g_boxed_type_register_static (
58 "FsCodec",
59 (GBoxedCopyFunc)fs_codec_copy,
60 (GBoxedFreeFunc)fs_codec_destroy);
61 }
62
63 return codec_type;
64 }
65
66 GType
67 fs_codec_list_get_type (void)
68 {
69 static GType codec_list_type = 0;
70 if (codec_list_type == 0)
71 {
72 codec_list_type = g_boxed_type_register_static (
73 "FsCodecGList",
74 (GBoxedCopyFunc)fs_codec_list_copy,
75 (GBoxedFreeFunc)fs_codec_list_destroy);
76 }
77
78 return codec_list_type;
79 }
80
81 G_DEFINE_BOXED_TYPE (FsCodecParameter,
82 fs_codec_parameter,
83 fs_codec_parameter_copy,
84 fs_codec_parameter_free);
85
86
87 G_DEFINE_BOXED_TYPE (FsFeedbackParameter,
88 fs_feedback_parameter,
89 fs_feedback_parameter_copy,
90 fs_feedback_parameter_free);
91
92 /**
93 * fs_codec_new:
94 * @id: codec identifier, if RTP this should be based on IETF RTP payload types
95 * @encoding_name: Name of media type this encodes
96 * @media_type: #FsMediaType for type of codec
97 * @clock_rate: The clock rate this codec encodes at, if applicable
98 *
99 * Allocates and initializes a #FsCodec structure
100 *
101 * Returns: A newly allocated #FsCodec
102 */
103 FsCodec *
104 fs_codec_new (int id, const char *encoding_name,
105 FsMediaType media_type, guint clock_rate)
106 {
107 FsCodec *codec = g_slice_new0 (FsCodec);
108
109 codec->id = id;
110 codec->encoding_name = g_strdup (encoding_name);
111 codec->media_type = media_type;
112 codec->clock_rate = clock_rate;
113 codec->minimum_reporting_interval = G_MAXUINT;
114
115 return codec;
116 }
117
118 void
119 fs_codec_parameter_free (FsCodecParameter *param)
120
121 {
122 g_free (param->name);
123 g_free (param->value);
124 g_slice_free (FsCodecParameter, param);
125 }
126
127
128 void
129 fs_feedback_parameter_free (FsFeedbackParameter *param)
130 {
131 g_free (param->type);
132 g_free (param->subtype);
133 g_free (param->extra_params);
134 g_slice_free (FsFeedbackParameter, param);
135 }
136
137 /**
138 * fs_codec_destroy: (skip):
139 * @codec: #FsCodec structure to free
140 *
141 * Deletes a #FsCodec structure and all its data. Is a no-op on %NULL codec
142 */
143 void
144 fs_codec_destroy (FsCodec * codec)
145 {
146 if (codec == NULL)
147 return;
148
149 g_free (codec->encoding_name);
150
151 g_list_foreach (codec->optional_params, (GFunc) fs_codec_parameter_free,
152 NULL);
153 g_list_free (codec->optional_params);
154
155 g_list_foreach (codec->feedback_params,
156 (GFunc) fs_feedback_parameter_free, NULL);
157 g_list_free (codec->feedback_params);
158
159 g_slice_free (FsCodec, codec);
160 }
161
162 /**
163 * fs_codec_copy:
164 * @codec: codec to copy
165 *
166 * Copies a #FsCodec structure.
167 *
168 * Returns: a copy of the codec
169 */
170 FsCodec *
171 fs_codec_copy (const FsCodec * codec)
172 {
173 FsCodec *copy = NULL;
174 GList *lp;
175 GQueue list_copy = G_QUEUE_INIT;
176
177 if (codec == NULL)
178 return NULL;
179
180 copy = fs_codec_new (codec->id, codec->encoding_name, codec->media_type,
181 codec->clock_rate);
182
183 copy->channels = codec->channels;
184 copy->minimum_reporting_interval = codec->minimum_reporting_interval;
185
186 copy->encoding_name = g_strdup (codec->encoding_name);
187
188 for (lp = codec->optional_params; lp; lp = g_list_next (lp))
189 {
190 FsCodecParameter *param_copy;
191 FsCodecParameter *param = lp->data;;
192
193 param_copy = g_slice_new (FsCodecParameter);
194 param_copy->name = g_strdup (param->name);
195 param_copy->value = g_strdup (param->value);
196
197 g_queue_push_tail (&list_copy, param_copy);
198 }
199 copy->optional_params = list_copy.head;
200
201 g_queue_init (&list_copy);
202 for (lp = codec->feedback_params; lp; lp = g_list_next (lp))
203 {
204 FsFeedbackParameter *param_copy;
205 FsFeedbackParameter *param = lp->data;;
206
207 param_copy = g_slice_new (FsFeedbackParameter);
208 param_copy->type = g_strdup (param->type);
209 param_copy->subtype = g_strdup (param->subtype);
210 param_copy->extra_params = g_strdup (param->extra_params);
211
212 g_queue_push_tail (&list_copy, param_copy);
213 }
214 copy->feedback_params = list_copy.head;
215
216 return copy;
217 }
218
219 /**
220 * fs_codec_list_destroy: (skip):
221 * @codec_list: a GList of #FsCodec to delete
222 *
223 * Deletes a list of #FsCodec structures and the list itself.
224 * Does nothing on %NULL lists.
225 */
226 void
227 fs_codec_list_destroy (GList *codec_list)
228 {
229 GList *lp;
230 FsCodec *codec;
231
232 for (lp = codec_list; lp; lp = g_list_next (lp)) {
233 codec = (FsCodec *) lp->data;
234 fs_codec_destroy (codec);
235 lp->data = NULL;
236 }
237 g_list_free (codec_list);
238 }
239
240 /**
241 * fs_codec_list_copy:
242 * @codec_list: a GList of #FsCodec to copy
243 *
244 * Copies a list of #FsCodec structures.
245 *
246 * Returns: (element-type FsCodec) (transfer full): The new list.
247 */
248 GList *
249 fs_codec_list_copy (const GList *codec_list)
250 {
251 GQueue copy = G_QUEUE_INIT;
252 const GList *lp;
253
254 for (lp = codec_list; lp; lp = g_list_next (lp)) {
255 FsCodec *codec = (FsCodec *) lp->data;
256
257 g_queue_push_tail (&copy, fs_codec_copy (codec));
258 }
259
260 return copy.head;
261 }
262
263 /**
264 * fs_codec_list_from_keyfile
265 * @filename: Name of the #GKeyFile to read the codecs parameters from
266 * @error: location of a #GError, or NULL if no error occured
267 *
268 * Reads the content of a #GKeyFile of the following format into
269 * a #GList of #FsCodec structures.
270 *
271 *
272 * Example:
273 * |[
274 * [audio/codec1]
275 * clock-rate=8000
276 *
277 * [audio/codec1:1]
278 * clock-rate=16000
279 *
280 * [audio/codec2]
281 * one_param=QCIF
282 * another_param=WOW
283 *
284 * [video/codec3]
285 * wierd_param=42
286 * feedback:nack/pli=1
287 * feedback:tfrc=
288 * ]|
289 *
290 * Return value: (element-type FsCodec) (transfer full):
291 * The #GList of #FsCodec or %NULL if the keyfile was empty or an error occured.
292 */
293 GList *
294 fs_codec_list_from_keyfile (const gchar *filename, GError **error)
295 {
296 GKeyFile *keyfile = NULL;
297 GList *codecs = NULL;
298 GError *gerror = NULL;
299 gchar **groups = NULL;
300 gsize groups_count = 0;
301 int i;
302
303 g_return_val_if_fail (filename, NULL);
304 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
305
306 keyfile = g_key_file_new ();
307
308 if (!g_key_file_load_from_file (keyfile, filename,
309 G_KEY_FILE_NONE, error)) {
310 goto out;
311 }
312
313 groups = g_key_file_get_groups (keyfile, &groups_count);
314
315 if (!groups)
316 goto out;
317
318 for (i=0; i < groups_count && groups[i]; i++) {
319 FsCodec *codec;
320 gchar **keys = NULL;
321 gsize keys_count;
322 int j;
323 gchar *encoding_name = NULL;
324 gchar *next_tok = NULL;
325 FsMediaType media_type;
326
327 keys = g_key_file_get_keys (keyfile, groups[i], &keys_count, &gerror);
328
329 if (!keys || gerror) {
330 if (gerror)
331 GST_WARNING ("Unable to read parameters for %s: %s\n",
332 groups[i], gerror->message);
333 else
334 GST_WARNING ("Unknown errors while reading parameters for %s",
335 groups[i]);
336
337 g_clear_error (&gerror);
338
339 goto next_codec;
340 }
341
342 next_tok = strchr (groups[i], '/');
343 if (!next_tok)
344 {
345 GST_WARNING ("Invalid codec name: %s", groups[i]);
346 goto next_codec;
347 }
348
349 if ((next_tok - groups[i]) == 5 /* strlen ("audio") */ &&
350 !g_ascii_strncasecmp ("audio", groups[i], 5))
351 {
352 media_type = FS_MEDIA_TYPE_AUDIO;
353 }
354 else if ((next_tok - groups[i]) == 5 /* strlen ("video") */ &&
355 !g_ascii_strncasecmp ("video", groups[i], 5))
356 {
357 media_type = FS_MEDIA_TYPE_VIDEO;
358 }
359 else
360 {
361 GST_WARNING ("Invalid media type in codec name name %s", groups[i]);
362 goto next_codec;
363 }
364
365 encoding_name = next_tok + 1;
366
367 next_tok = strchr (encoding_name, ':');
368
369 if (encoding_name[0] == 0 || next_tok - encoding_name == 1)
370 goto next_codec;
371
372 if (next_tok)
373 encoding_name = g_strndup (encoding_name,
374 next_tok - encoding_name);
375 else
376 encoding_name = g_strdup (encoding_name);
377
378 codec = fs_codec_new (FS_CODEC_ID_ANY, encoding_name, media_type, 0);
379
380 g_free (encoding_name);
381
382 for (j = 0; j < keys_count && keys[j]; j++) {
383 if (!g_ascii_strcasecmp ("clock-rate", keys[j])) {
384 codec->clock_rate = g_key_file_get_integer (keyfile, groups[i], keys[j],
385 &gerror);
386 if (gerror) {
387 codec->clock_rate = 0;
388 goto keyerror;
389 }
390
391 } else if (!g_ascii_strcasecmp ("id", keys[j])) {
392 codec->id = g_key_file_get_integer (keyfile, groups[i], keys[j],
393 &gerror);
394 if (gerror) {
395 codec->id = FS_CODEC_ID_ANY;
396 goto keyerror;
397 }
398
399 if (codec->id < 0)
400 codec->id = FS_CODEC_ID_DISABLE;
401
402 } else if (!g_ascii_strcasecmp ("channels", keys[j])) {
403 codec->channels = g_key_file_get_integer (keyfile, groups[i], keys[j],
404 &gerror);
405 if (gerror) {
406 codec->channels = 0;
407 goto keyerror;
408 }
409 } else if (!g_ascii_strcasecmp ("trr-int", keys[j])) {
410 codec->minimum_reporting_interval =
411 g_key_file_get_integer (keyfile, groups[i], keys[j], &gerror);
412 if (gerror) {
413 codec->minimum_reporting_interval = G_MAXUINT;
414 goto keyerror;
415 }
416 } else if (g_str_has_prefix (keys[j], "feedback:")) {
417 gchar *type = keys[j] + strlen ("feedback:");
418 gchar *subtype = strchr (type, '/');
419 gchar *extra_params;
420
421 extra_params = g_key_file_get_string (keyfile, groups[i], keys[j],
422 &gerror);
423 if (gerror)
424 goto keyerror;
425
426 /* Replace / with \0 and point to name (the next char) */
427 if (subtype)
428 {
429 *subtype=0;
430 subtype++;
431 }
432 else
433 {
434 subtype = "";
435 }
436
437 fs_codec_add_feedback_parameter (codec, type, subtype,
438 extra_params);
439 g_free (extra_params);
440 } else {
441 FsCodecParameter *param = g_slice_new (FsCodecParameter);
442
443 param->name = g_strdup (keys[j]);
444 param->value = g_key_file_get_string (keyfile, groups[i], keys[j],
445 &gerror);
446 if (gerror) {
447 fs_codec_parameter_free (param);
448 goto keyerror;
449 }
450
451 if (!param->name || !param->value)
452 fs_codec_parameter_free (param);
453 else
454 codec->optional_params = g_list_append (codec->optional_params,
455 param);
456 }
457 continue;
458 keyerror:
459 GST_WARNING ("Error reading key %s codec %s: %s", keys[j], groups[i],
460 gerror->message);
461 g_clear_error (&gerror);
462
463 }
464
465 codecs = g_list_append (codecs, codec);
466
467 next_codec:
468 g_strfreev (keys);
469 }
470
471
472 out:
473
474 g_strfreev (groups);
475 g_key_file_free (keyfile);
476
477 return codecs;
478 }
479
480 /**
481 * fs_media_type_to_string
482 * @media_type: A media type
483 *
484 * Gives a user-printable string representing the media type
485 *
486 * Return value: a static string representing the media type
487 */
488
489 const gchar *
490 fs_media_type_to_string (FsMediaType media_type)
491 {
492 if (media_type == FS_MEDIA_TYPE_AUDIO) {
493 return "audio";
494 } else if (media_type == FS_MEDIA_TYPE_VIDEO) {
495 return "video";
496 } else {
497 return NULL;
498 }
499 }
500
501 /**
502 * fs_codec_to_string
503 * @codec: A farstream codec
504 *
505 * Returns a newly-allocated string representing the codec
506 *
507 * Return value: the newly-allocated string
508 */
509 gchar *
510 fs_codec_to_string (const FsCodec *codec)
511 {
512 GString *string = NULL;
513 GList *item;
514 gchar *charstring;
515
516 if (codec == NULL)
517 return g_strdup ("(NULL)");
518
519 string = g_string_new ("");
520
521 g_string_printf (string, "%d: %s %s clock:%d channels:%d",
522 codec->id, fs_media_type_to_string (codec->media_type),
523 codec->encoding_name, codec->clock_rate, codec->channels);
524
525 if (codec->minimum_reporting_interval != G_MAXUINT)
526 g_string_append_printf (string, " trr-int=%u",
527 codec->minimum_reporting_interval);
528
529 for (item = codec->optional_params;
530 item;
531 item = g_list_next (item)) {
532 FsCodecParameter *param = item->data;
533 g_string_append_printf (string, " %s=%s", param->name, param->value);
534 }
535
536 for (item = codec->feedback_params;
537 item;
538 item = g_list_next (item)) {
539 FsFeedbackParameter *param = item->data;
540 g_string_append_printf (string, " %s/%s=%s", param->type, param->subtype,
541 param->extra_params);
542 }
543
544 charstring = string->str;
545 g_string_free (string, FALSE);
546
547 return charstring;
548 }
549
550
551 static gboolean
552 compare_optional_params (const gpointer p1, const gpointer p2)
553 {
554 const FsCodecParameter *param1 = p1;
555 const FsCodecParameter *param2 = p2;
556
557 if (!g_ascii_strcasecmp (param1->name, param2->name) &&
558 !strcmp (param1->value, param2->value))
559 return TRUE;
560 else
561 return FALSE;
562 }
563
564 static gboolean
565 compare_feedback_params (const gpointer p1, const gpointer p2)
566 {
567 const FsFeedbackParameter *param1 = p1;
568 const FsFeedbackParameter *param2 = p2;
569
570 if (!g_ascii_strcasecmp (param1->subtype, param2->subtype) &&
571 !g_ascii_strcasecmp (param1->type, param2->type) &&
572 !g_strcmp0 (param1->extra_params, param2->extra_params))
573 return TRUE;
574 else
575 return FALSE;
576 }
577
578 /*
579 * Check if all of the elements of list1 are in list2
580 * It compares GLists of X using the comparison function
581 */
582 static gboolean
583 compare_lists (GList *list1, GList *list2,
584 gboolean (*compare_params) (const gpointer p1, const gpointer p2))
585 {
586 GList *item1;
587
588 for (item1 = g_list_first (list1);
589 item1;
590 item1 = g_list_next (item1)) {
591 FsCodecParameter *param1 = item1->data;
592 GList *item2 = NULL;
593
594 for (item2 = g_list_first (list2);
595 item2;
596 item2 = g_list_next (item2)) {
597 FsCodecParameter *param2 = item2->data;
598
599 if (compare_params (param1, param2))
600 break;
601 }
602 if (!item2)
603 return FALSE;
604 }
605
606 return TRUE;
607 }
608
609
610 /**
611 * fs_codec_are_equal:
612 * @codec1: First codec
613 * @codec2: Second codec
614 *
615 * Compare two codecs, it will declare two codecs to be identical even
616 * if their optional parameters are in a different order. %NULL encoding names
617 * are ignored.
618 *
619 * Return value: %TRUE of the codecs are identical, %FALSE otherwise
620 */
621
622 gboolean
623 fs_codec_are_equal (const FsCodec *codec1, const FsCodec *codec2)
624 {
625 if (codec1 == codec2)
626 return TRUE;
627
628 if (!codec1 || !codec2)
629 return FALSE;
630
631 if (codec1->id != codec2->id ||
632 codec1->media_type != codec2->media_type ||
633 codec1->clock_rate != codec2->clock_rate ||
634 codec1->channels != codec2->channels ||
635 codec1->minimum_reporting_interval !=
636 codec2->minimum_reporting_interval ||
637 codec1->encoding_name == NULL ||
638 codec2->encoding_name == NULL ||
639 g_ascii_strcasecmp (codec1->encoding_name, codec2->encoding_name))
640 return FALSE;
641
642
643 /* Is there a smarter way to compare to un-ordered linked lists
644 * to make sure they contain exactly the same elements??
645 */
646 if (!compare_lists (codec1->optional_params, codec2->optional_params,
647 compare_optional_params) ||
648 !compare_lists (codec2->optional_params, codec1->optional_params,
649 compare_optional_params))
650 return FALSE;
651
652 if (!compare_lists (codec1->feedback_params,
653 codec2->feedback_params, compare_feedback_params) ||
654 !compare_lists (codec2->feedback_params,
655 codec1->feedback_params, compare_feedback_params))
656 return FALSE;
657
658 return TRUE;
659 }
660
661 /**
662 * fs_codec_list_are_equal:
663 * @list1: (element-type FsCodec): a #GList of #FsCodec
664 * @list2: (element-type FsCodec): a #GList of #FsCodec
665 *
666 * Verifies if two glist of fscodecs are identical
667 *
668 * Returns: %TRUE if they are identical, %FALSE otherwise
669 */
670
671 gboolean
672 fs_codec_list_are_equal (GList *list1, GList *list2)
673 {
674
675 for (;
676 list1 && list2;
677 list1 = g_list_next (list1), list2 = g_list_next (list2))
678 {
679 if (!fs_codec_are_equal (list1->data, list2->data))
680 return FALSE;
681 }
682
683 if (list1 == NULL && list2 == NULL)
684 return TRUE;
685 else
686 return FALSE;
687 }
688
689 /**
690 * fs_codec_add_optional_parameter:
691 * @codec: The #FsCodec to add the parameter to
692 * @name: The name of the optional parameter
693 * @value: The extra_params of the optional parameter
694 *
695 * This function adds an new optional parameter to a #FsCodec
696 */
697
698 void
699 fs_codec_add_optional_parameter (FsCodec *codec,
700 const gchar *name,
701 const gchar *value)
702 {
703 FsCodecParameter *param;
704
705 g_return_if_fail (name != NULL && value != NULL);
706
707 param = g_slice_new (FsCodecParameter);
708
709 param->name = g_strdup (name);
710 param->value = g_strdup (value);
711
712 codec->optional_params = g_list_append (codec->optional_params, param);
713 }
714
715 /**
716 * fs_codec_remove_optional_parameter:
717 * @codec: a #FsCodec
718 * @param: a pointer to the #FsCodecParameter to remove
719 *
720 * Removes an optional parameter from a codec.
721 *
722 * NULL param will do nothing.
723 */
724
725 void
726 fs_codec_remove_optional_parameter (FsCodec *codec,
727 FsCodecParameter *param)
728 {
729 g_return_if_fail (codec);
730
731 if (!param)
732 return;
733
734 fs_codec_parameter_free (param);
735 codec->optional_params = g_list_remove (codec->optional_params, param);
736 }
737
738 /**
739 * fs_codec_get_optional_parameter:
740 * @codec: a #FsCodec
741 * @name: The name of the parameter to search for
742 * @value: The value of the parameter to search for or %NULL for any value
743 *
744 * Finds the #FsCodecParameter in the #FsCodec that has the requested name
745 * and, if not %NULL, the requested value
746 *
747 * Returns: (transfer none) the #FsCodecParameter from the #FsCodec or %NULL
748 */
749
750 FsCodecParameter *
751 fs_codec_get_optional_parameter (FsCodec *codec, const gchar *name,
752 const gchar *value)
753 {
754 GList *item = NULL;
755
756 g_return_val_if_fail (codec != NULL, NULL);
757 g_return_val_if_fail (name != NULL, NULL);
758
759 for (item = g_list_first (codec->optional_params);
760 item;
761 item = g_list_next (item))
762 {
763 FsCodecParameter *param = item->data;
764 if (!g_ascii_strcasecmp (param->name, name) &&
765 (value == NULL || !g_ascii_strcasecmp (param->value, value)))
766 return param;
767 }
768
769 return NULL;
770 }
771
772 /**
773 * fs_codec_add_feedback_parameter:
774 * @codec: The #FsCodec to add the parameter to
775 * @type: The type of the feedback parameter
776 * @subtype: The subtype of the feedback parameter
777 * @extra_params: The extra_params of the feeback parameter
778 *
779 * This function adds an new feedback parameter to a #FsCodec
780 */
781
782 void
783 fs_codec_add_feedback_parameter (FsCodec *codec, const gchar *type,
784 const gchar *subtype, const gchar *extra_params)
785 {
786 FsFeedbackParameter *param;
787
788 g_return_if_fail (type != NULL);
789 g_return_if_fail (subtype != NULL);
790 g_return_if_fail (extra_params != NULL);
791
792 param = g_slice_new (FsFeedbackParameter);
793
794 param->type = g_strdup (type);
795 param->subtype = g_strdup (subtype);
796 param->extra_params = g_strdup (extra_params);
797
798 codec->feedback_params = g_list_append (codec->feedback_params, param);
799 }
800
801
802 /**
803 * fs_codec_get_feedback_parameter:
804 * @codec: a #FsCodec
805 * @type: The subtype of the parameter to search for or %NULL for any type
806 * @subtype: The subtype of the parameter to search for or %NULL for any subtype
807 * @extra_params: The extra_params of the parameter to search for or %NULL for
808 * any extra_params
809 *
810 * Finds the #FsFeedbackParameter in the #FsCodec that has the requested
811 * subtype, type and extra_params. One of which must be non-NULL;
812 *
813 * Returns: the #FsFeedbackParameter from the #FsCodec or %NULL
814 */
815
816 FsFeedbackParameter *
817 fs_codec_get_feedback_parameter (FsCodec *codec,
818 const gchar *type, const gchar *subtype, const gchar *extra_params)
819 {
820 GList *item = NULL;
821
822 g_return_val_if_fail (codec != NULL, NULL);
823 g_return_val_if_fail (type != NULL || subtype != NULL, NULL);
824
825 for (item = g_list_first (codec->feedback_params);
826 item;
827 item = g_list_next (item))
828 {
829 FsFeedbackParameter *param = item->data;
830 if (!g_ascii_strcasecmp (param->type, type) &&
831 (subtype == NULL || !g_ascii_strcasecmp (param->subtype, subtype)) &&
832 (extra_params == NULL || !g_ascii_strcasecmp (param->extra_params,
833 extra_params)))
834 return param;
835 }
836
837 return NULL;
838 }
839
840
841
842 /**
843 * fs_codec_remove_feedback_parameter:
844 * @codec: a #FsCodec
845 * @item: a pointer to the #GList element to remove that contains a
846 * #FsFeedbackParameter
847 *
848 * Removes an optional parameter from a codec.
849 *
850 * NULL param will do nothing.
851 */
852
853 void
854 fs_codec_remove_feedback_parameter (FsCodec *codec, GList *item)
855 {
856 g_return_if_fail (codec);
857
858 if (!item)
859 return;
860
861 fs_feedback_parameter_free (item->data);
862 codec->feedback_params =
863 g_list_delete_link (codec->feedback_params, item);
864 }
865
866 FsCodecParameter *
867 fs_codec_parameter_copy (const FsCodecParameter *param)
868 {
869 FsCodecParameter *outparam = g_slice_new (FsCodecParameter);
870
871 outparam->name = g_strdup (param->name);
872 outparam->value = g_strdup (param->value);
873
874 return outparam;
875 }
876
877
878 FsFeedbackParameter *
879 fs_feedback_parameter_copy (const FsFeedbackParameter *param)
880 {
881 FsFeedbackParameter *outparam = g_slice_new (FsFeedbackParameter);
882
883 outparam->type = g_strdup (param->type);
884 outparam->subtype = g_strdup (param->subtype);
885 outparam->extra_params = g_strdup (param->extra_params);
886
887 return outparam;
888 }
+0
-207
gst-libs/gst/farstream/fs-codec.h less more
0 /*
1 * Farstream - Farstream Codec
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * Copyright 2005 Collabora Ltd.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 *
10 * fs-codec.h - A Farstream codec
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifndef __FS_CODEC_H__
28 #define __FS_CODEC_H__
29
30 #include <gst/gst.h>
31
32 G_BEGIN_DECLS
33
34 typedef struct _FsCodec FsCodec;
35 typedef struct _FsCodecParameter FsCodecParameter;
36 typedef struct _FsFeedbackParameter FsFeedbackParameter;
37
38 #define FS_TYPE_CODEC \
39 (fs_codec_get_type ())
40
41 #define FS_TYPE_CODEC_LIST \
42 (fs_codec_list_get_type ())
43
44 /**
45 * FsMediaType:
46 * @FS_MEDIA_TYPE_AUDIO: A media type that encodes audio.
47 * @FS_MEDIA_TYPE_VIDEO: A media type that encodes video.
48 * @FS_MEDIA_TYPE_LAST: Largest valid #FsMediaType
49 *
50 * Enum used to signify the media type of a codec or stream.
51 */
52 typedef enum _FsMediaType
53 {
54 FS_MEDIA_TYPE_AUDIO,
55 FS_MEDIA_TYPE_VIDEO,
56 FS_MEDIA_TYPE_LAST = FS_MEDIA_TYPE_VIDEO
57 } FsMediaType;
58
59 /**
60 * FS_CODEC_ID_ANY:
61 *
62 * If the id of a #FsCodec is #FS_CODEC_ID_ANY, then it will be replaced
63 * with a dynamic payload type at runtime
64 */
65
66 /**
67 * FS_CODEC_ID_DISABLE:
68 *
69 * If the id of a #FsCodec is #FS_CODEC_ID_DISABLE, then this codec will
70 * not be used
71 */
72
73 #define FS_CODEC_ID_ANY (-1)
74 #define FS_CODEC_ID_DISABLE (-2)
75
76 /**
77 * FsCodec:
78 * @id: numeric identifier for encoding, eg. PT for SDP
79 * @encoding_name: the name of the codec
80 * @media_type: type of media this codec is for
81 * @clock_rate: clock rate of this stream
82 * @channels: Number of channels codec should decode
83 * @ptime: The preferred duration (in ms) of a packet
84 * @maxptime: The maximum duration (in ms) of a packet
85 * @optional_params: (element-type FsCodecParameter): key pairs of param name to param data
86 * @minimum_reporting_interval: The minimum interval between two RTCP reports,
87 * If it is not specified (G_MAXUINT), it is up to the protocol to decide
88 * (it is 5 seconds for RTP).
89 *
90 * This structure reprensents one codec that can be offered or received
91 */
92 /* TODO Should this be made into a GstStructure? */
93 struct _FsCodec
94 {
95 gint id;
96 char *encoding_name;
97 FsMediaType media_type;
98 guint clock_rate;
99 guint channels;
100 guint minimum_reporting_interval;
101 GList *optional_params;
102 GList *feedback_params;
103 };
104
105 /**
106 * FsCodecParameter:
107 * @name: paramter name.
108 * @value: parameter value.
109 *
110 * Used to store arbitary parameters for a codec
111 */
112 struct _FsCodecParameter {
113 gchar *name;
114 gchar *value;
115 };
116
117 /**
118 * FsFeedbackParameter:
119 * @type: the type of feedback, like "ack", "name", "ccm"
120 * @subtype: the subtype of feedback (can be an empty string)
121 * @extra_params: a string containing extra parameters (can be empty)
122 *
123 * Use to store feedback parameters
124 */
125 struct _FsFeedbackParameter {
126 gchar *type;
127 gchar *subtype;
128 gchar *extra_params;
129 };
130
131
132 /**
133 * FS_CODEC_FORMAT:
134 *
135 * A format that can be used in printf like format strings to format a FsCodec
136 */
137
138 /**
139 * FS_CODEC_ARGS:
140 * @codec: a #FsCodec
141 *
142 * Formats the codec in args for FS_CODEC_FORMAT
143 */
144
145 #define FS_CODEC_FORMAT "%d: %s %s clock:%d channels:%d params:%p"
146 #define FS_CODEC_ARGS(codec) \
147 (codec)->id, \
148 fs_media_type_to_string ((codec)->media_type), \
149 (codec)->encoding_name, \
150 (codec)->clock_rate, \
151 (codec)->channels, \
152 (codec)->optional_params
153
154 GType fs_codec_get_type (void);
155 GType fs_codec_list_get_type (void);
156
157
158 FsCodec *fs_codec_new (int id, const char *encoding_name,
159 FsMediaType media_type, guint clock_rate);
160
161 void fs_codec_destroy (FsCodec * codec);
162 FsCodec *fs_codec_copy (const FsCodec * codec);
163 void fs_codec_list_destroy (GList *codec_list);
164 GList *fs_codec_list_copy (const GList *codec_list);
165
166 GList *fs_codec_list_from_keyfile (const gchar *filename, GError **error);
167 gchar *fs_codec_to_string (const FsCodec *codec);
168 const gchar *fs_media_type_to_string (FsMediaType media_type);
169
170 gboolean fs_codec_are_equal (const FsCodec *codec1, const FsCodec *codec2);
171 gboolean fs_codec_list_are_equal (GList *list1, GList *list2);
172
173
174 void fs_codec_add_optional_parameter (FsCodec *codec, const gchar *name,
175 const gchar *value);
176 void fs_codec_remove_optional_parameter (FsCodec *codec,
177 FsCodecParameter *param);
178 FsCodecParameter *fs_codec_get_optional_parameter (FsCodec *codec,
179 const gchar *name, const gchar *value);
180
181 #define FS_TYPE_CODEC_PARAMETER (fs_codec_parameter_get_type ())
182 GType fs_codec_parameter_get_type (void);
183
184 FsCodecParameter *fs_codec_parameter_copy (const FsCodecParameter *param);
185 void fs_codec_parameter_free (FsCodecParameter *param);
186
187
188 void fs_codec_add_feedback_parameter (FsCodec *codec, const gchar *type,
189 const gchar *subtype, const gchar *extra_params);
190 FsFeedbackParameter *fs_codec_get_feedback_parameter (FsCodec *codec,
191 const gchar *type, const gchar *subtype, const gchar *extra_params);
192 void fs_codec_remove_feedback_parameter (FsCodec *codec, GList *item);
193
194
195 #define FS_TYPE_FEEDBACK_PARAMETER (fs_feedback_parameter_get_type ())
196 GType fs_feedback_parameter_get_type (void);
197
198 FsFeedbackParameter *fs_feedback_parameter_copy (
199 const FsFeedbackParameter *param);
200 void fs_feedback_parameter_free (FsFeedbackParameter *param);
201
202
203
204 G_END_DECLS
205
206 #endif /* __FS_CODEC_H__ */
+0
-186
gst-libs/gst/farstream/fs-conference.c less more
0 /*
1 * Farstream - GStreamer interfaces
2 *
3 * Copyright 2007-2011 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * @author: Olivier Crete <olivier.crete@collabora.com>
6 * Copyright 2007-2011 Nokia Corp.
7 *
8 * fs-conference.c - GStreamer interface to be implemented by farstream
9 * conference elements
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "fs-conference.h"
31 #include "fs-session.h"
32 #include "fs-private.h"
33
34 /**
35 * SECTION:fs-conference
36 * @short_description: Interface for farstream conference elements
37 *
38 * A Farstream conference is a conversation space that takes place between 2 or
39 * more participants. Each conference must have one or more Farstream sessions
40 * that are associated to the conference participants.
41 *
42 *
43 * This will communicate asynchronous events to the user through #GstMessage
44 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
45 * </para>
46 * <refsect2><title>The "<literal>farstream-error</literal>" message</title>
47 * |[
48 * "src-object" #GObject The object (#FsConference, #FsSession or #FsStream) that emitted the error
49 * "error-no" #FsError The Error number
50 * "error-msg" #gchar* The error message
51 * ]|
52 * <para>
53 * The message is sent on asynchronous errors.
54 * </para>
55 * </refsect2>
56 * <para>
57 */
58
59
60 GST_DEBUG_CATEGORY (fs_conference_debug);
61 #define GST_CAT_DEFAULT fs_conference_debug
62
63
64 GST_BOILERPLATE (
65 FsConference, fs_conference,
66 GstBin, GST_TYPE_BIN)
67
68
69 GQuark
70 fs_error_quark (void)
71 {
72 return g_quark_from_static_string ("fs-error");
73 }
74
75 void
76 _fs_conference_init_debug (void)
77 {
78 GST_DEBUG_CATEGORY_INIT (fs_conference_debug, "fsconference", 0,
79 "farstream base conference library");
80 }
81
82 static void
83 fs_conference_base_init (gpointer g_class)
84 {
85 _fs_conference_init_debug ();
86 }
87
88
89
90 static void
91 fs_conference_class_init (FsConferenceClass * klass)
92 {
93 }
94
95 static void
96 fs_conference_init (FsConference *conf, FsConferenceClass *bclass)
97 {
98 GST_DEBUG ("fs_conference_init");
99 }
100
101
102 static void
103 fs_conference_error (GObject *signal_src,
104 GObject *error_src,
105 FsError error_no,
106 gchar *error_msg,
107 FsConference *conf)
108 {
109 GstMessage *gst_msg = NULL;
110 GstStructure *error_struct = NULL;
111
112 error_struct = gst_structure_new ("farstream-error",
113 "src-object", G_TYPE_OBJECT, error_src,
114 "error-no", FS_TYPE_ERROR, error_no,
115 "error-msg", G_TYPE_STRING, error_msg,
116 NULL);
117
118 gst_msg = gst_message_new_element (GST_OBJECT (conf), error_struct);
119
120 if (!gst_element_post_message (GST_ELEMENT (conf), gst_msg))
121 GST_WARNING_OBJECT (conf, "Could not post error on bus");
122 }
123
124 /**
125 * fs_conference_new_session
126 * @conference: #FsConference interface of a #GstElement
127 * @media_type: #FsMediaType of the new session
128 * @error: location of a #GError, or %NULL if no error occured
129 *
130 * Create a new Farstream session for the given conference.
131 *
132 * Returns: (transfer full): the new #FsSession that has been created.
133 * The #FsSession must be unref'd by the user when closing the session.
134 */
135
136 FsSession *
137 fs_conference_new_session (FsConference *conf,
138 FsMediaType media_type,
139 GError **error)
140 {
141 FsConferenceClass *klass;
142 FsSession *new_session = NULL;
143
144 g_return_val_if_fail (conf, NULL);
145 g_return_val_if_fail (FS_IS_CONFERENCE (conf), NULL);
146 klass = FS_CONFERENCE_GET_CLASS (conf);
147 g_return_val_if_fail (klass->new_session, NULL);
148
149 new_session = klass->new_session (conf, media_type, error);
150
151 if (!new_session)
152 return NULL;
153
154 /* Let's catch all session errors and send them over the GstBus */
155 g_signal_connect_object (new_session, "error",
156 G_CALLBACK (fs_conference_error), conf, 0);
157
158 return new_session;
159 }
160
161 /**
162 * fs_conference_new_participant
163 * @conference: #FsConference interface of a #GstElement
164 * @error: location of a #GError, or %NULL if no error occured
165 *
166 * Create a new Farstream Participant for the type of the given conference.
167 *
168 * Returns: (transfer full): the new #FsParticipant that has been created.
169 * The #FsParticipant is owned by the user and he must unref it when he is
170 * done with it.
171 */
172 FsParticipant *
173 fs_conference_new_participant (FsConference *conf,
174 GError **error)
175 {
176 FsConferenceClass *klass;
177
178 g_return_val_if_fail (conf, NULL);
179 g_return_val_if_fail (FS_IS_CONFERENCE (conf), NULL);
180 klass = FS_CONFERENCE_GET_CLASS (conf);
181 g_return_val_if_fail (klass->new_participant, NULL);
182
183 return klass->new_participant (conf, error);
184 }
185
+0
-184
gst-libs/gst/farstream/fs-conference.h less more
0 /*
1 * Farstream - FsConference Class
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-conference.h - Header file for farstream Conference base class
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_CONFERENCE_H__
25 #define __FS_CONFERENCE_H__
26
27 #include <gst/gst.h>
28
29 #include <gst/farstream/fs-session.h>
30 #include <gst/farstream/fs-codec.h>
31 #include <gst/farstream/fs-enumtypes.h>
32
33 G_BEGIN_DECLS
34
35
36 #define FS_TYPE_CONFERENCE \
37 (fs_conference_get_type ())
38 #define FS_CONFERENCE(obj) \
39 (G_TYPE_CHECK_INSTANCE_CAST((obj),FS_TYPE_CONFERENCE,FsConference))
40 #define FS_CONFERENCE_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_CAST((klass),FS_TYPE_CONFERENCE,FsConferenceClass))
42 #define FS_CONFERENCE_GET_CLASS(obj) \
43 (G_TYPE_INSTANCE_GET_CLASS((obj),FS_TYPE_CONFERENCE,FsConferenceClass))
44 #define FS_IS_CONFERENCE(obj) \
45 (G_TYPE_CHECK_INSTANCE_TYPE((obj),FS_TYPE_CONFERENCE))
46 #define FS_IS_CONFERENCE_CLASS(klass) \
47 (G_TYPE_CHECK_CLASS_TYPE((klass),FS_TYPE_CONFERENCE))
48 #define FS_CONFERENCE_CAST(obj) \
49 ((FsConference *)(obj))
50
51 /**
52 * FsConference:
53 *
54 * Opaque #FsConference data structure.
55 */
56 typedef struct _FsConference FsConference;
57 typedef struct _FsConferenceClass FsConferenceClass;
58
59 /**
60 * FsConference
61 *
62 * The #FsConference structure, all the members are private
63 */
64
65 struct _FsConference
66 {
67 GstBin parent;
68
69 /*< private >*/
70
71 gpointer _padding[8];
72 };
73
74
75 /**
76 * FsConferenceClass:
77 * @parent: parent GstBin class
78 * @new_session: virtual method to create a new conference session
79 * @new_participant: virtual method to create a new participant
80 *
81 * #FsConferenceClass class structure.
82 */
83 struct _FsConferenceClass {
84 GstBinClass parent;
85
86 /* virtual functions */
87 FsSession *(* new_session) (FsConference *conference, FsMediaType media_type,
88 GError **error);
89
90 FsParticipant *(* new_participant) (FsConference *conference,
91 GError **error);
92
93 /*< private > */
94 gpointer _gst_reserved[GST_PADDING];
95 };
96
97 GType fs_conference_get_type (void);
98
99
100
101 /**
102 * FsError:
103 * @FS_ERROR_CONSTRUCTION: Error constructing some of the sub-elements, this
104 * probably denotes an error in the installation of the gstreamer elements.
105 * It is a fatal error.
106 * @FS_ERROR_INVALID_ARGUMENTS: Invalid arguments to the function, this
107 * is a programming error and should not be reported to the user
108 * @FS_ERROR_INTERNAL: An internal error happened in Farstream, it may be in
109 * an inconsistent state. The object from which this error comes should be
110 * discarded.
111 * @FS_ERROR_NETWORK: A network related error, this should probably be
112 * reported to the user.
113 * @FS_ERROR_NOT_IMPLEMENTED: The optional functionality is not implemented by
114 * this plugin.
115 * @FS_ERROR_NEGOTIATION_FAILED: The codec negotiation has failed, this means
116 * that there are no common codecs between the local and remote codecs.
117 * @FS_ERROR_UNKNOWN_CODEC: Data is received on an unknown codec, this most
118 * likely denotes an error on the remote side, the buffers will be ignored.
119 * It can safely be ignored in most cases (but may result in a call with no
120 * media received).
121 * @FS_ERROR_NO_CODECS: There are no codecs detected for that media type.
122 * @FS_ERROR_NO_CODECS_LEFT: All of the codecs have been disabled by the
123 * codec preferences, one should try less strict codec preferences.
124 * @FS_ERROR_CONNECTION_FAILED: Could not connect to the to remote party.
125 * @FS_ERROR_DISPOSED: The object has been disposed.
126 * @FS_ERROR_ALREADY_EXISTS: The object already exists
127 *
128 * This is the enum of error numbers that will come either on the "error"
129 * signal, from the Gst Bus or for error in the FS_ERROR domain in GErrors
130 */
131
132 typedef enum _FsError
133 {
134 FS_ERROR_CONSTRUCTION = 1,
135 FS_ERROR_INTERNAL,
136 FS_ERROR_INVALID_ARGUMENTS = 100,
137 FS_ERROR_NETWORK,
138 FS_ERROR_NOT_IMPLEMENTED,
139 FS_ERROR_NEGOTIATION_FAILED,
140 FS_ERROR_UNKNOWN_CODEC,
141 FS_ERROR_NO_CODECS,
142 FS_ERROR_NO_CODECS_LEFT,
143 FS_ERROR_CONNECTION_FAILED,
144 FS_ERROR_DISPOSED,
145 FS_ERROR_ALREADY_EXISTS
146 } FsError;
147
148 /**
149 * FS_ERROR:
150 *
151 * This quark is used to denote errors coming from Farstream objects
152 */
153
154 #define FS_ERROR (fs_error_quark ())
155
156 /**
157 * FS_ERROR_IS_FATAL:
158 * @error: a #FsError
159 *
160 * Tells the programmer if an error if fatal or not, if it returns %TRUE,
161 * the error is fatal, and the object that created it should
162 * be discarded. It returns %FALSE otherwise.
163 */
164
165 #define FS_ERROR_IS_FATAL(error) \
166 (error < 100)
167
168 GQuark fs_error_quark (void);
169
170 /* virtual class function wrappers */
171 FsSession *fs_conference_new_session (FsConference *conference,
172 FsMediaType media_type,
173 GError **error);
174
175 FsParticipant *fs_conference_new_participant (FsConference *conference,
176 GError **error);
177
178
179 G_END_DECLS
180
181 #endif /* __FS_CONFERENCE_H__ */
182
183
+0
-448
gst-libs/gst/farstream/fs-element-added-notifier.c less more
0 /*
1 * Farstream - Recursive element addition notifier
2 *
3 * Copyright 2007-2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007-2008 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 /**
24 * SECTION:fs-element-added-notifier
25 * @short_description: Recursive element addition notifier
26 *
27 * This object can be attach to any #GstBin and will emit a the
28 * #FsElementAddedNotifier::element-added signal for every element inside the
29 * #GstBin or any sub-bin and any element added in the future to the bin or
30 * its sub-bins. There is also a utility method to have it used to
31 * set the properties of elements based on a GKeyfile.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37
38 #include "fs-element-added-notifier.h"
39
40 #include <stdlib.h>
41
42 #include "fs-utils.h"
43
44 #include "fs-marshal.h"
45
46
47 /* Signals */
48 enum
49 {
50 ELEMENT_ADDED,
51 LAST_SIGNAL
52 };
53
54 #define FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(o) \
55 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
56 FsElementAddedNotifierPrivate))
57
58 struct _FsElementAddedNotifierPrivate {
59 GList *keyfiles;
60 };
61
62 static void _element_added_callback (GstBin *parent, GstElement *element,
63 gpointer user_data);
64
65 static void fs_element_added_notifier_finalize (GObject *object);
66
67
68 G_DEFINE_TYPE(FsElementAddedNotifier, fs_element_added_notifier, G_TYPE_OBJECT);
69
70 static guint signals[LAST_SIGNAL] = { 0 };
71
72 static void
73 fs_element_added_notifier_class_init (FsElementAddedNotifierClass *klass)
74 {
75 GObjectClass *gobject_class;
76
77 gobject_class = (GObjectClass *) klass;
78
79 gobject_class->finalize = fs_element_added_notifier_finalize;
80
81 /**
82 * FsElementAddedNotifier::element-added:
83 * @self: #FsElementAddedNotifier that emitted the signal
84 * @bin: The #GstBin to which this object was added
85 * @element: The #GstElement that was added
86 *
87 * This signal is emitted when an element is added to a #GstBin that was added
88 * to this object or one of its sub-bins.
89 * Be careful, there is no guarantee that this will be emitted on your
90 * main thread, it will be emitted in the thread that added the element.
91 * The bin may be %NULL if this is the top-level bin.
92 */
93 signals[ELEMENT_ADDED] = g_signal_new ("element-added",
94 G_TYPE_FROM_CLASS (klass),
95 G_SIGNAL_RUN_LAST,
96 0,
97 NULL,
98 NULL,
99 _fs_marshal_VOID__OBJECT_OBJECT,
100 G_TYPE_NONE, 2, GST_TYPE_BIN, GST_TYPE_ELEMENT);
101
102 g_type_class_add_private (klass, sizeof (FsElementAddedNotifierPrivate));
103 }
104
105
106 static void
107 fs_element_added_notifier_init (FsElementAddedNotifier *notifier)
108 {
109 notifier->priv = FS_ELEMENT_ADDED_NOTIFIER_GET_PRIVATE(notifier);
110 }
111
112
113
114 static void
115 fs_element_added_notifier_finalize (GObject *object)
116 {
117 FsElementAddedNotifier *self = FS_ELEMENT_ADDED_NOTIFIER (object);
118
119 g_list_foreach (self->priv->keyfiles, (GFunc) g_key_file_free, NULL);
120 g_list_free (self->priv->keyfiles);
121 self->priv->keyfiles = NULL;
122 }
123
124 /**
125 * fs_element_added_notifier_new:
126 *
127 * Creates a new #FsElementAddedNotifier object
128 *
129 * Returns: the newly-created #FsElementAddedNotifier
130 */
131
132 FsElementAddedNotifier *
133 fs_element_added_notifier_new (void)
134 {
135 return (FsElementAddedNotifier *)
136 g_object_new (FS_TYPE_ELEMENT_ADDED_NOTIFIER, NULL);
137 }
138
139 /**
140 * fs_element_added_notifier_add:
141 * @notifier: a #FsElementAddedNotifier
142 * @bin: A #GstBin to watch to added elements
143 *
144 * Add a #GstBin to on which the #FsElementAddedNotifier::element-added signal
145 * will be called on every element and sub-element present and added in the
146 * future.
147 */
148
149 void
150 fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
151 GstBin *bin)
152 {
153 g_return_if_fail (notifier && FS_IS_ELEMENT_ADDED_NOTIFIER (notifier));
154 g_return_if_fail (bin && GST_IS_BIN (bin));
155
156 _element_added_callback (NULL, GST_ELEMENT_CAST (bin), notifier);
157 }
158
159
160 static void
161 _bin_unparented_cb (GstObject *object, GstObject *parent, gpointer user_data)
162 {
163 GstIterator *iter = NULL;
164 gboolean done;
165
166 /* Return if there was no handler connected */
167 if (g_signal_handlers_disconnect_by_func (object, _element_added_callback,
168 user_data) == 0)
169 return;
170
171 iter = gst_bin_iterate_elements (GST_BIN (object));
172
173 done = FALSE;
174 while (!done)
175 {
176 gpointer item;
177
178 switch (gst_iterator_next (iter, &item)) {
179 case GST_ITERATOR_OK:
180 if (GST_IS_BIN (item))
181 _bin_unparented_cb (GST_OBJECT (item), object, user_data);
182 gst_object_unref (item);
183 break;
184 case GST_ITERATOR_RESYNC:
185 // We don't rollback anything, we just ignore already processed ones
186 gst_iterator_resync (iter);
187 break;
188 case GST_ITERATOR_ERROR:
189 g_error ("Wrong parameters were given?");
190 done = TRUE;
191 break;
192 case GST_ITERATOR_DONE:
193 done = TRUE;
194 break;
195 }
196 }
197
198 gst_iterator_free (iter);
199 }
200
201
202 /**
203 * fs_element_added_notifier_remove:
204 * @notifier: a #FsElementAddedNotifier
205 * @bin: A #GstBin to stop watching
206 *
207 * Stop watching the passed bin and its subbins.
208 *
209 * Returns: %TRUE if the #GstBin was being watched, %FALSE otherwise
210 */
211
212 gboolean
213 fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
214 GstBin *bin)
215 {
216 g_return_val_if_fail (FS_IS_ELEMENT_ADDED_NOTIFIER (notifier), FALSE);
217 g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
218
219 if (g_signal_handler_find (bin,
220 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
221 0, 0, NULL, /* id, detail, closure */
222 _element_added_callback, notifier) != 0)
223 {
224 _bin_unparented_cb (GST_OBJECT (bin), NULL, notifier);
225 return TRUE;
226 }
227 else
228 {
229 return FALSE;
230 }
231 }
232
233
234 #if 1
235 # define DEBUG(...) do {} while (0)
236 #else
237 # define DEBUG g_debug
238 #endif
239
240 static void
241 _bin_added_from_keyfile (FsElementAddedNotifier *notifier, GstBin *bin,
242 GstElement *element, gpointer user_data)
243 {
244 GKeyFile *keyfile = user_data;
245 const gchar *name = NULL;
246 gchar *free_name = NULL;
247 gchar **keys;
248 gint i;
249 GstElementFactory *factory = gst_element_get_factory (element);
250
251 if (factory)
252 {
253 name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
254 if (name && !g_key_file_has_group (keyfile, name))
255 name = NULL;
256 }
257
258 if (!name)
259 {
260 GST_OBJECT_LOCK (element);
261 if (GST_OBJECT_NAME (element) &&
262 g_key_file_has_group (keyfile, GST_OBJECT_NAME (element)))
263 name = free_name = g_strdup (GST_OBJECT_NAME (element));
264 GST_OBJECT_UNLOCK (element);
265 }
266
267 if (!name)
268 return;
269
270 DEBUG ("Found config for %s", name);
271 keys = g_key_file_get_keys (keyfile, name, NULL, NULL);
272
273 for (i = 0; keys[i]; i++)
274 {
275 GParamSpec *param_spec;
276 GValue prop_value = { 0 };
277 gchar *str_value;
278
279 DEBUG ("getting %s", keys[i]);
280 param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS(element),
281 keys[i]);
282
283 if (!param_spec)
284 {
285 DEBUG ("Property %s does not exist in element %s, ignoring",
286 keys[i], name);
287 continue;
288 }
289
290 g_value_init (&prop_value, param_spec->value_type);
291
292 str_value = g_key_file_get_value (keyfile, name, keys[i], NULL);
293 if (str_value && gst_value_deserialize (&prop_value, str_value))
294 {
295 DEBUG ("Setting %s to on %s", keys[i], name);
296 g_object_set_property (G_OBJECT (element), keys[i], &prop_value);
297 }
298 else
299 {
300 DEBUG ("Could not read value for property %s", keys[i]);
301 }
302 g_free (str_value);
303 g_value_unset (&prop_value);
304 }
305
306 g_strfreev (keys);
307 g_free (free_name);
308 }
309
310
311 /**
312 * fs_element_added_notifier_set_properties_from_keyfile:
313 * @notifier: a #FsElementAddedNotifier
314 * @keyfile: a #GKeyFile
315 *
316 * Using a #GKeyFile where the groups are the element's type or name
317 * and the key=value are the property and its value, this function
318 * will set the properties on the elements added to this object after
319 * this function has been called. It will take ownership of the
320 * GKeyFile structure. It will first try the group as the element type, if that
321 * does not match, it will check its name.
322 */
323 void
324 fs_element_added_notifier_set_properties_from_keyfile (
325 FsElementAddedNotifier *notifier,
326 GKeyFile *keyfile)
327 {
328 g_return_if_fail (FS_IS_ELEMENT_ADDED_NOTIFIER (notifier));
329 g_return_if_fail (keyfile);
330
331 g_signal_connect (notifier, "element-added",
332 G_CALLBACK (_bin_added_from_keyfile), keyfile);
333
334 notifier->priv->keyfiles =
335 g_list_prepend (notifier->priv->keyfiles, keyfile);
336 }
337
338
339 /**
340 * fs_element_added_notifier_set_properties_from_file:
341 * @notifier: a #FsElementAddedNotifier
342 * @filename: The name of the keyfile to use
343 * @error: location of a #GError, or %NULL if no error occured
344 *
345 * Same as fs_element_added_notifier_set_properties_from_keyfile() but using
346 * the name of the file to load instead of the #GKeyFile directly.
347 *
348 * Returns: %TRUE if the file was successfully loaded, %FALSE otherwise
349 */
350 gboolean
351 fs_element_added_notifier_set_properties_from_file (
352 FsElementAddedNotifier *notifier,
353 const gchar *filename,
354 GError **error)
355 {
356 GKeyFile *keyfile = g_key_file_new ();
357
358 if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error))
359 {
360 g_key_file_free (keyfile);
361 return FALSE;
362 }
363
364 fs_element_added_notifier_set_properties_from_keyfile(notifier, keyfile);
365
366 return TRUE;
367 }
368
369 static void
370 _element_added_callback (GstBin *parent, GstElement *element,
371 gpointer user_data)
372 {
373 FsElementAddedNotifier *notifier = FS_ELEMENT_ADDED_NOTIFIER (user_data);
374
375 if (GST_IS_BIN (element)) {
376 GstIterator *iter = NULL;
377 gboolean done;
378
379 g_signal_connect_object (element, "element-added",
380 G_CALLBACK (_element_added_callback), notifier, 0);
381
382 if (parent)
383 g_signal_connect_object (element, "parent-unset",
384 G_CALLBACK (_bin_unparented_cb), notifier, 0);
385
386 iter = gst_bin_iterate_elements (GST_BIN (element));
387
388 done = FALSE;
389 while (!done)
390 {
391 gpointer item = NULL;
392
393 switch (gst_iterator_next (iter, &item)) {
394 case GST_ITERATOR_OK:
395 /* We make sure the callback has not already been added */
396 if (g_signal_handler_find (item,
397 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
398 0, 0, NULL, /* id, detail, closure */
399 _element_added_callback, notifier) == 0)
400 _element_added_callback (GST_BIN_CAST (element), item, notifier);
401 gst_object_unref (item);
402 break;
403 case GST_ITERATOR_RESYNC:
404 // We don't rollback anything, we just ignore already processed ones
405 gst_iterator_resync (iter);
406 break;
407 case GST_ITERATOR_ERROR:
408 g_error ("Wrong parameters were given?");
409 done = TRUE;
410 break;
411 case GST_ITERATOR_DONE:
412 done = TRUE;
413 break;
414 }
415 }
416
417 gst_iterator_free (iter);
418 }
419
420 g_signal_emit (notifier, signals[ELEMENT_ADDED], 0, parent, element);
421 }
422
423
424 /**
425 * fs_element_added_notifier_set_default_properties:
426 * @notifier: a #FsElementAddedNotifier
427 * @element: Element for which to set the default codec
428 * preferences
429 *
430 * Same as first calling fs_utils_get_default_element_properties() and using
431 * the result with
432 * fs_element_added_notifier_set_properties_from_keyfile() .
433 *
434 * This is binding friendly (since GKeyFile doesn't have a boxed type).
435 */
436 void
437 fs_element_added_notifier_set_default_properties (
438 FsElementAddedNotifier *notifier,
439 GstElement *element)
440 {
441 GKeyFile *keyfile = fs_utils_get_default_element_properties (element);
442
443 if (!keyfile)
444 return;
445
446 fs_element_added_notifier_set_properties_from_keyfile(notifier, keyfile);
447 }
+0
-105
gst-libs/gst/farstream/fs-element-added-notifier.h less more
0 /*
1 * Farstream - Recursive element addition notifier
2 *
3 * Copyright 2007-2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007-2008 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifndef __FS_ELEMENT_ADDED_NOTIFIER_H__
23 #define __FS_ELEMENT_ADDED_NOTIFIER_H__
24
25 #include <gst/gst.h>
26
27 G_BEGIN_DECLS
28
29
30 /* TYPE MACROS */
31 #define FS_TYPE_ELEMENT_ADDED_NOTIFIER \
32 (fs_element_added_notifier_get_type ())
33 #define FS_ELEMENT_ADDED_NOTIFIER(obj) \
34 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
35 FsElementAddedNotifier))
36 #define FS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
37 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
38 FsElementAddedNotifierClass))
39 #define FS_IS_ELEMENT_ADDED_NOTIFIER(obj) \
40 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
41 #define FS_IS_ELEMENT_ADDED_NOTIFIER_CLASS(klass) \
42 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_ELEMENT_ADDED_NOTIFIER))
43 #define FS_ELEMENT_ADDED_NOTIFIER_GET_CLASS(obj) \
44 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_ELEMENT_ADDED_NOTIFIER, \
45 FsElementAddedNotifierClass))
46
47
48 typedef struct _FsElementAddedNotifier FsElementAddedNotifier;
49 typedef struct _FsElementAddedNotifierClass FsElementAddedNotifierClass;
50 typedef struct _FsElementAddedNotifierPrivate FsElementAddedNotifierPrivate;
51
52 /**
53 * FsElementAddedNotifier:
54 *
55 * All members are private
56 */
57
58 struct _FsElementAddedNotifier
59 {
60 GObject parent;
61
62 /*< private >*/
63
64 FsElementAddedNotifierPrivate *priv;
65 };
66
67 /**
68 * FsElementAddedNotifierClass:
69 * @parent_class: the #GObjectClass parent
70 *
71 * All members are private
72 */
73 struct _FsElementAddedNotifierClass
74 {
75 GObjectClass parent_class;
76 };
77
78
79 GType fs_element_added_notifier_get_type (void);
80
81 FsElementAddedNotifier *fs_element_added_notifier_new (void);
82
83 void fs_element_added_notifier_add (FsElementAddedNotifier *notifier,
84 GstBin *bin);
85
86 gboolean fs_element_added_notifier_remove (FsElementAddedNotifier *notifier,
87 GstBin *bin);
88
89 void fs_element_added_notifier_set_properties_from_keyfile (
90 FsElementAddedNotifier *notifier,
91 GKeyFile *keyfile);
92
93 gboolean fs_element_added_notifier_set_properties_from_file (
94 FsElementAddedNotifier *notifier,
95 const gchar *filename,
96 GError **error);
97
98 void fs_element_added_notifier_set_default_properties (
99 FsElementAddedNotifier *notifier,
100 GstElement *element);
101
102 G_END_DECLS
103
104 #endif /* __FS_ELEMENT_ADDED_NOTIFIER_H__ */
+0
-98
gst-libs/gst/farstream/fs-participant.c less more
0 /*
1 * Farstream - Farstream Participant
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-participant.c - A Farstream Participant gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-participant
26 * @short_description: A participant in a conference
27 *
28 * This object is the base implementation of a Farstream Participant. It needs to be
29 * derived and implemented by a farstream conference gstreamer element. A
30 * participant represents any source of media in a conference. This could be a
31 * human-participant or an automaton.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "fs-participant.h"
39 #include "fs-enumtypes.h"
40 #include "fs-marshal.h"
41
42 /* Signals */
43 enum
44 {
45 LAST_SIGNAL
46 };
47
48 /* props */
49 enum
50 {
51 PROP_0
52 };
53
54 /*
55 struct _FsParticipantPrivate
56 {
57 };
58 */
59
60 G_DEFINE_ABSTRACT_TYPE(FsParticipant, fs_participant, GST_TYPE_OBJECT);
61
62 #define FS_PARTICIPANT_GET_PRIVATE(o) \
63 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_PARTICIPANT, \
64 FsParticipantPrivate))
65
66 static void fs_participant_finalize (GObject *object);
67
68
69 // static guint signals[LAST_SIGNAL] = { 0 };
70
71 static void
72 fs_participant_class_init (FsParticipantClass *klass)
73 {
74 GObjectClass *gobject_class;
75
76 gobject_class = (GObjectClass *) klass;
77
78 gobject_class->finalize = fs_participant_finalize;
79
80 // g_type_class_add_private (klass, sizeof (FsParticipantPrivate));
81 }
82
83 static void
84 fs_participant_init (FsParticipant *self)
85 {
86 //self->priv = FS_PARTICIPANT_GET_PRIVATE (self);
87 self->mutex = g_mutex_new ();
88 }
89
90 static void
91 fs_participant_finalize (GObject *object)
92 {
93 FsParticipant *self = FS_PARTICIPANT (object);
94 g_mutex_free (self->mutex);
95
96 G_OBJECT_CLASS (fs_participant_parent_class)->finalize (object);
97 }
+0
-114
gst-libs/gst/farstream/fs-participant.h less more
0 /*
1 * Farstream - Farstream Participant
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-participant.h - A Farstream Participant gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_PARTICIPANT_H__
25 #define __FS_PARTICIPANT_H__
26
27 #include <gst/gst.h>
28
29 G_BEGIN_DECLS
30
31 /* TYPE MACROS */
32 #define FS_TYPE_PARTICIPANT \
33 (fs_participant_get_type ())
34 #define FS_PARTICIPANT(obj) \
35 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_PARTICIPANT, FsParticipant))
36 #define FS_PARTICIPANT_CLASS(klass) \
37 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_PARTICIPANT, FsParticipantClass))
38 #define FS_IS_PARTICIPANT(obj) \
39 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_PARTICIPANT))
40 #define FS_IS_PARTICIPANT_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_PARTICIPANT))
42 #define FS_PARTICIPANT_GET_CLASS(obj) \
43 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_PARTICIPANT, FsParticipantClass))
44 #define FS_PARTICIPANT_CAST(obj) ((FsParticipant *) (obj))
45
46 typedef struct _FsParticipant FsParticipant;
47 typedef struct _FsParticipantClass FsParticipantClass;
48 typedef struct _FsParticipantPrivate FsParticipantPrivate;
49
50 /**
51 * FsParticipantClass:
52 * @parent_class: Our parent
53 *
54 * The FsParticipant class has no virtual methods to implement,
55 * but you may want to override the properties or attach more date to it
56 */
57
58 struct _FsParticipantClass
59 {
60 GstObjectClass parent_class;
61
62 /* virtual functions */
63
64 /*< private >*/
65 FsParticipantPrivate *priv;
66 gpointer _padding[8];
67 };
68
69 /**
70 * FsParticipant:
71 *
72 * All members are private (access them using the properties)
73 */
74 struct _FsParticipant
75 {
76 GstObject parent;
77
78 /*< private >*/
79
80 GMutex *mutex;
81
82 FsParticipantPrivate *priv;
83
84 gpointer _padding[8];
85 };
86
87 /**
88 * FS_PARTICIPANT_DATA_LOCK
89 * @participant: A #FsParticipant
90 *
91 * Locks the participant for data set with g_object_set_data() or
92 * g_object_set_qdata().
93 */
94
95 #define FS_PARTICIPANT_DATA_LOCK(participant) \
96 g_mutex_lock ((participant)->mutex)
97
98 /**
99 * FS_PARTICIPANT_DATA_UNLOCK
100 * @participant: A #FsParticipant
101 *
102 * Unlocks the participant for data set with g_object_set_data() or
103 * g_object_set_qdata().
104 */
105
106 #define FS_PARTICIPANT_DATA_UNLOCK(participant) \
107 g_mutex_unlock ((participant)->mutex)
108
109 GType fs_participant_get_type (void);
110
111 G_END_DECLS
112
113 #endif /* __FS_PARTICIPANT_H__ */
+0
-390
gst-libs/gst/farstream/fs-plugin.c less more
0 /*
1 * fs-plugin.c - Source for farstream plugin infrastructure
2 *
3 * Farstream Voice+Video library
4 * Copyright (c) 2005 INdT.
5 * @author Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
6 * Copyright 2005-2007 Collabora Ltd.
7 * Copyright 2005-2007 Nokia Corp.
8 * @author Rob Taylor <rob.taylor@collabora.co.uk>
9 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
10 *
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "fs-plugin.h"
32
33 #include <string.h>
34
35 #include "fs-conference.h"
36 #include "fs-private.h"
37
38 #define GST_CAT_DEFAULT fs_conference_debug
39
40 /**
41 * SECTION:fs-plugin
42 * @short_description: A class for defining Farstream plugins
43 *
44 * This class is a generic class to load GType plugins based on their name.
45 * With this simple class, you can only have one type per plugin.
46 */
47
48 #define FS_PLUGIN_GET_PRIVATE(o) \
49 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_PLUGIN, FsPluginPrivate))
50
51 static gboolean fs_plugin_load (GTypeModule *module);
52
53
54 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
55 static gchar **search_paths = NULL;
56 static GList *plugins = NULL;
57
58 struct _FsPluginPrivate
59 {
60 GModule *handle;
61 };
62
63 G_DEFINE_TYPE(FsPlugin, fs_plugin, G_TYPE_TYPE_MODULE);
64
65 static void
66 fs_plugin_search_path_init (void)
67 {
68 const gchar *env;
69
70 if (search_paths)
71 return;
72
73 env = g_getenv ("FS_PLUGIN_PATH");
74
75 if (env == NULL)
76 {
77 search_paths = g_new (gchar *, 2);
78 search_paths[0] = g_strdup (FS_PLUGIN_PATH);
79 search_paths[1] = NULL;
80 return;
81 }
82 else
83 {
84 gchar *path;
85
86 path = g_strjoin (":", env, FS_PLUGIN_PATH, NULL);
87 search_paths = g_strsplit (path, ":", -1);
88 g_free (path);
89 }
90 }
91
92 static void
93 fs_plugin_class_init (FsPluginClass * klass)
94 {
95 GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
96
97 module_class->load = fs_plugin_load;
98
99 g_type_class_add_private (klass, sizeof (FsPluginPrivate));
100
101 /* Calling from class initializer so it only gets init'ed once */
102 fs_plugin_search_path_init ();
103 }
104
105
106
107 static void
108 fs_plugin_init (FsPlugin * plugin)
109 {
110 /* member init */
111 plugin->priv = FS_PLUGIN_GET_PRIVATE (plugin);
112 plugin->priv->handle = NULL;
113 }
114
115 static gboolean fs_plugin_load (GTypeModule *module)
116 {
117 FsPlugin *plugin = FS_PLUGIN(module);
118 gchar **search_path = NULL;
119 gchar *path=NULL;
120
121 gboolean (*fs_init_plugin) (FsPlugin *);
122
123 g_return_val_if_fail (plugin != NULL, FALSE);
124 g_return_val_if_fail (plugin->name != NULL && plugin->name[0] != '\0', FALSE);
125
126 for (search_path = search_paths; *search_path; search_path++) {
127 GST_DEBUG("looking for plugins in %s", *search_path);
128
129 path = g_module_build_path (*search_path, plugin->name);
130
131 plugin->priv->handle = g_module_open (path, G_MODULE_BIND_LOCAL);
132 GST_INFO ("opening module %s: %s\n", path,
133 (plugin->priv->handle != NULL) ? "succeeded" : g_module_error ());
134 g_free (path);
135
136 if (!plugin->priv->handle) {
137 continue;
138 }
139
140 else if (!g_module_symbol (plugin->priv->handle,
141 "fs_init_plugin",
142 (gpointer) & fs_init_plugin)) {
143 g_module_close (plugin->priv->handle);
144 plugin->priv->handle = NULL;
145 GST_WARNING ("could not find init function in plugin\n");
146 continue;
147 }
148
149 else
150 break;
151 }
152
153 if (!plugin->priv->handle) {
154 return FALSE;
155 }
156
157 fs_init_plugin (plugin);
158 if (!plugin->type) {
159 /* TODO error handling (init error or no info defined) */
160 GST_WARNING ("init error or no info defined");
161 goto err_close_module;
162 }
163
164 return TRUE;
165
166 err_close_module:
167 g_module_close (plugin->priv->handle);
168 return FALSE;
169
170 }
171
172 static FsPlugin *
173 fs_plugin_get_by_name_locked (const gchar * name, const gchar * type_suffix)
174 {
175 gchar *fullname;
176 FsPlugin *plugin = NULL;
177 GList *plugin_item;
178
179 g_return_val_if_fail (name != NULL, NULL);
180 g_return_val_if_fail (type_suffix != NULL, NULL);
181
182 fullname = g_strdup_printf ("%s-%s",name,type_suffix);
183
184 for (plugin_item = plugins;
185 plugin_item;
186 plugin_item = g_list_next (plugin_item)) {
187 plugin = plugin_item->data;
188 if (plugin->name == NULL || plugin->name[0] == 0)
189 continue;
190 if (!strcmp (plugin->name, fullname)) {
191 break;
192 }
193
194 }
195 g_free (fullname);
196
197 if (plugin_item)
198 return plugin;
199
200 return NULL;
201 }
202
203
204 /**
205 * fs_plugin_create_valist:
206 * @name: The name of the plugin to load
207 * @type_suffix: The type of plugin to load (normally "transmitter")
208 * @error: location of a #GError, or NULL if no error occured
209 * @first_property_name: The name of the first property to be set on the
210 * object
211 * @var_args: The rest of the arguments
212 *
213 * Loads the appropriate plugin if necessary and creates a GObject of
214 * the requested type
215 *
216 * Returns: (transfer full): The object created (or NULL if there is an error)
217 **/
218
219 GObject *
220 fs_plugin_create_valist (const gchar *name, const gchar *type_suffix,
221 GError **error, const gchar *first_property_name, va_list var_args)
222 {
223 GObject *object;
224 FsPlugin *plugin;
225
226 g_return_val_if_fail (name, NULL);
227 g_return_val_if_fail (type_suffix, NULL);
228
229 _fs_conference_init_debug ();
230
231 g_static_mutex_lock (&mutex);
232
233 plugin = fs_plugin_get_by_name_locked (name, type_suffix);
234
235 if (!plugin) {
236 plugin = g_object_new (FS_TYPE_PLUGIN, NULL);
237 if (!plugin) {
238 g_static_mutex_unlock (&mutex);
239 g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
240 "Could not create a fsplugin object");
241 return NULL;
242 }
243 plugin->name = g_strdup_printf ("%s-%s",name,type_suffix);
244 g_type_module_set_name (G_TYPE_MODULE (plugin), plugin->name);
245 plugins = g_list_append (plugins, plugin);
246
247 /* We do the use once and then we keep it loaded forever because
248 * the gstreamer libraries can't be unloaded
249 */
250 if (!g_type_module_use (G_TYPE_MODULE (plugin))) {
251 g_static_mutex_unlock (&mutex);
252 g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
253 "Could not load the %s-%s transmitter plugin", name, type_suffix);
254 return NULL;
255 }
256 }
257
258 g_static_mutex_unlock (&mutex);
259
260 object = g_object_new_valist (plugin->type, first_property_name, var_args);
261
262 return object;
263 }
264
265
266 /**
267 * fs_plugin_create:
268 * @name: The name of the plugin to load
269 * @type_suffix: The type of plugin to load (normally "transmitter")
270 * @error: location of a #GError, or NULL if no error occured
271 * @first_property_name: The name of the first property to be set on the
272 * object
273 * @...: The NULL-terminated list of properties to set on the transmitter
274 *
275 * Loads the appropriate plugin if necessary and creates a GObject of
276 * the requested type
277 *
278 * Returns: (transfer full): The object created (or NULL if there is an error)
279 **/
280
281 GObject *
282 fs_plugin_create (const gchar *name, const gchar *type_suffix,
283 GError **error, const gchar *first_property_name, ...)
284 {
285 va_list var_args;
286 GObject *obj;
287
288 va_start (var_args, first_property_name);
289 obj = fs_plugin_create_valist (name, type_suffix, error, first_property_name,
290 var_args);
291 va_end (var_args);
292
293 return obj;
294 }
295
296 /**
297 * fs_plugin_list_available:
298 * @type_suffix: Get list of plugins with this type suffix
299 *
300 * Gets the list of all available plugins of a certain type
301 *
302 * Returns: (transfer full): a newly allocated NULL terminated array of
303 * strings or %NULL if no strings were found.
304 * It should be freed with g_strfreev().
305 */
306
307 gchar **
308 fs_plugin_list_available (const gchar *type_suffix)
309 {
310 GPtrArray *list = g_ptr_array_new ();
311 gchar **retval = NULL;
312 gchar **search_path = NULL;
313 GRegex *matcher;
314 GError *error = NULL;
315 gchar *tmp1, *tmp2, *tmp3;
316
317 g_static_mutex_lock (&mutex);
318
319 fs_plugin_search_path_init ();
320
321 tmp1 = g_strdup_printf ("(.+)-%s", type_suffix);
322 tmp2 = g_module_build_path ("", tmp1);
323 tmp3 = g_strconcat ("^", tmp2, NULL);
324 matcher = g_regex_new (tmp3, 0, 0, NULL);
325 g_free (tmp1);
326 g_free (tmp2);
327 g_free (tmp3);
328
329
330 for (search_path = search_paths; *search_path; search_path++)
331 {
332 GDir *dir = NULL;
333 const gchar *entry;
334
335 dir = g_dir_open (*search_path, 0, &error);
336 if (!dir)
337 {
338 GST_WARNING ("Could not open path %s to look for plugins: %s",
339 *search_path, error ? error->message : "Unknown error");
340 g_clear_error (&error);
341 continue;
342 }
343
344 while ((entry = g_dir_read_name (dir)))
345 {
346 gchar **matches = NULL;
347
348 matches = g_regex_split (matcher, entry, 0);
349
350 if (matches && g_strv_length (matches) == 3)
351 {
352 gint i;
353 gboolean found = FALSE;
354
355 for (i = 0; i < list->len; i++)
356 {
357 if (!strcmp (matches[1], g_ptr_array_index (list, i)))
358 {
359 found = TRUE;
360 break;
361 }
362 }
363 if (!found)
364 g_ptr_array_add (list, g_strdup (matches[1]));
365 }
366
367 g_strfreev (matches);
368 }
369
370 g_dir_close (dir);
371 }
372
373 g_regex_unref (matcher);
374
375 if (list->len)
376 {
377 g_ptr_array_add (list, NULL);
378 retval = (gchar**) list->pdata;
379 g_ptr_array_free (list, FALSE);
380 }
381 else
382 {
383 g_ptr_array_free (list, TRUE);
384 }
385
386 g_static_mutex_unlock (&mutex);
387
388 return retval;
389 }
+0
-123
gst-libs/gst/farstream/fs-plugin.h less more
0 /*
1 * fs-plugin.h - Header for farstream plugin infrastructure
2 *
3 * Farstream Voice+Video library
4 * Copyright (c) 2005 INdT.
5 * @author: Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
6 * Copyright (c) 2005-2007 Collabora Ltd.
7 * Copyright (c) 2005-2007 Nokia Corp.
8 * @author: Rob Taylor <rob.taylor@collabora.co.uk>
9 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #ifndef __FS_PLUGIN_H__
27 #define __FS_PLUGIN_H__
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <gmodule.h>
32 #include <gst/gst.h>
33
34 #include <stdarg.h>
35
36 G_BEGIN_DECLS
37
38
39 /* TYPE MACROS */
40 #define FS_TYPE_PLUGIN \
41 (fs_plugin_get_type ())
42 #define FS_PLUGIN(obj) \
43 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_PLUGIN, FsPlugin))
44 #define FS_PLUGIN_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_PLUGIN, FsPluginClass))
46 #define FS_IS_PLUGIN(obj) \
47 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_PLUGIN))
48 #define FS_IS_PLUGIN_CLASS(klass) \
49 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_PLUGIN))
50 #define FS_PLUGIN_GET_CLASS(obj) \
51 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_PLUGIN, FsPluginClass))
52
53 /**
54 * FsPlugin:
55 * @parent: the parent object
56 *
57 * This structure represents a plugin, it is opaque.
58 */
59
60 typedef struct _FsPlugin FsPlugin;
61 typedef struct _FsPluginClass FsPluginClass;
62 typedef struct _FsPluginPrivate FsPluginPrivate;
63
64 struct _FsPlugin
65 {
66 GTypeModule parent;
67
68 /*< private >*/
69
70 GType type;
71
72 gchar *name; /* name of the plugin */
73
74 /*< private >*/
75
76 FsPluginPrivate *priv;
77
78 gpointer unused[8];
79 };
80
81 struct _FsPluginClass
82 {
83 GTypeModuleClass parent_class;
84
85 /*< private >*/
86
87 gpointer unused[8];
88 };
89
90 GType fs_plugin_get_type (void);
91
92
93 GObject *fs_plugin_create_valist (const gchar *name,
94 const gchar *type_suffix,
95 GError **error,
96 const gchar *first_property_name,
97 va_list var_args);
98
99 GObject *fs_plugin_create (const gchar *name,
100 const gchar *type_suffix,
101 GError **error,
102 const gchar *first_property_name, ...);
103
104 gchar **fs_plugin_list_available (const gchar *type_suffix);
105
106 /**
107 * FS_INIT_PLUGIN:
108 * @type_register_func: A function that register a #GType and returns it
109 *
110 * This macro is used to declare Farstream plugins and must be used once
111 * in any farstream plugin.
112 */
113
114 #define FS_INIT_PLUGIN(type_register_func) \
115 G_MODULE_EXPORT void fs_init_plugin (FsPlugin *plugin) { \
116 plugin->type = (type_register_func (plugin)); \
117 }
118
119
120 G_END_DECLS
121 #endif
122
+0
-40
gst-libs/gst/farstream/fs-private.h less more
0 /*
1 * Farstream - Private declarations
2 *
3 * Copyright 2008 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2008 Nokia Corp.
6 *
7 * fs-conference.h - Header file for gstreamer interface to be
8 * implemented by farstream conference elements
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef __FS_PRIVATE_H__
26 #define __FS_PRIVATE_H__
27
28 #include <gst/gst.h>
29
30 G_BEGIN_DECLS
31
32 void _fs_conference_init_debug (void);
33
34 GST_DEBUG_CATEGORY_EXTERN (fs_conference_debug);
35
36 G_END_DECLS
37
38 #endif /* __FS_PRIVATE_H__ */
39
+0
-318
gst-libs/gst/farstream/fs-rtp.c less more
0 /*
1 * Farstream - Farstream RTP specific types
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * fs-rtp.c - Farstream RTP specific types
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "fs-rtp.h"
30
31 #include <string.h>
32
33 typedef GList FsRtpHeaderExtensionGList;
34
35 G_DEFINE_BOXED_TYPE (FsRtpHeaderExtension, fs_rtp_header_extension,
36 fs_rtp_header_extension_copy, fs_rtp_header_extension_destroy)
37 G_DEFINE_BOXED_TYPE (FsRtpHeaderExtensionGList, fs_rtp_header_extension_list,
38 fs_rtp_header_extension_list_copy, fs_rtp_header_extension_list_destroy)
39
40
41 /**
42 * fs_rtp_header_extension_new:
43 * @id: The identifier of the RTP header extension
44 * @direction: the direction in which this extension can be used
45 * @uri: The URI that defines this extension
46 *
47 * Creates a new #FsRtpHeaderExtension
48 *
49 * Returns: a new #FsRtpHeaderExtension
50 */
51
52 FsRtpHeaderExtension *
53 fs_rtp_header_extension_new (guint id, FsStreamDirection direction,
54 const gchar *uri)
55 {
56 FsRtpHeaderExtension *extension;
57
58 extension = g_slice_new (FsRtpHeaderExtension);
59
60 extension->id = id;
61 extension->direction = direction;
62 extension->uri = g_strdup (uri);
63
64 return extension;
65 }
66
67 /**
68 * fs_rtp_header_extension_copy:
69 * @extension: The RTP header extension definition to copy
70 *
71 * Copies a #FsRtpHeaderExtension
72 *
73 * Returns: a new #FsRtpHeaderExtension
74 */
75
76 FsRtpHeaderExtension *
77 fs_rtp_header_extension_copy (FsRtpHeaderExtension *extension)
78 {
79 if (extension)
80 return fs_rtp_header_extension_new (extension->id, extension->direction,
81 extension->uri);
82 else
83 return NULL;
84 }
85
86 /**
87 * fs_rtp_header_extension_are_equal:
88 * @extension1: The first #FsRtpHeaderExtension
89 * @extension2: The second #FsRtpHeaderExtension
90 *
91 * Compares two #FsRtpHeaderExtension structures
92 *
93 * Returns: %TRUE if they are identical, %FALSE otherwise
94 */
95
96 gboolean
97 fs_rtp_header_extension_are_equal (FsRtpHeaderExtension *extension1,
98 FsRtpHeaderExtension *extension2)
99 {
100 if (extension1 == extension2)
101 return TRUE;
102
103 if (!extension2 || !extension2)
104 return FALSE;
105
106 if (extension1->id == extension2->id &&
107 extension1->direction == extension2->direction &&
108 (extension1->uri == extension2->uri ||
109 (extension1->uri && extension2->uri &&
110 !strcmp (extension1->uri, extension2->uri))))
111 return TRUE;
112 else
113 return FALSE;
114 }
115
116 /**
117 * fs_rtp_header_extension_destroy:
118 * @extension: A RTP header extension to free
119 *
120 * Frees the passed #FsRtpHeaderExtension
121 */
122
123 void
124 fs_rtp_header_extension_destroy (FsRtpHeaderExtension *extension)
125 {
126 if (extension)
127 {
128 g_free (extension->uri);
129 g_slice_free (FsRtpHeaderExtension, extension);
130 }
131 }
132
133 /**
134 * fs_rtp_header_extension_list_copy:
135 * @extensions: a #GList of #FsRtpHeaderExtension
136 *
137 * Does a deep copy of a #GList of #FsRtpHeaderExtension
138 *
139 * Returns: (element-type FsRtpHeaderExtension) (transfer full): a new
140 * #GList of #FsRtpHeaderExtension
141 */
142
143 GList *
144 fs_rtp_header_extension_list_copy (GList *extensions)
145 {
146 GQueue copy = G_QUEUE_INIT;
147 const GList *lp;
148
149 for (lp = extensions; lp; lp = g_list_next (lp)) {
150 FsRtpHeaderExtension *ext = lp->data;
151
152 g_queue_push_tail (&copy, fs_rtp_header_extension_copy (ext));
153 }
154
155 return copy.head;
156 }
157
158 /**
159 * fs_rtp_header_extension_list_destroy:
160 * @extensions: a #GList of #FsRtpHeaderExtension
161 *
162 * Frees the passed #GList of #FsRtpHeaderExtension
163 */
164
165 void
166 fs_rtp_header_extension_list_destroy (GList *extensions)
167 {
168 g_list_foreach (extensions, (GFunc) fs_rtp_header_extension_destroy, NULL);
169 g_list_free (extensions);
170 }
171
172 #define RTP_HDREXT_PREFIX "rtp-hdrext:"
173 #define RTP_HDREXT_AUDIO_PREFIX "audio:"
174 #define RTP_HDREXT_VIDEO_PREFIX "video:"
175
176 /**
177 * fs_rtp_header_extension_list_from_keyfile:
178 * @filename: Name of the #GKeyFile to read the RTP Header Extensions from
179 * @media_type: The media type for which to get header extensions
180 * @error: location of a #GError, or NULL if no error occured
181 *
182 * Reads the content of a #GKeyFile of the following format into a
183 * #GList of #FsRtpHeaderExtension structures.
184 *
185 * The groups have a format "rtp-hdrext:audio:XXX" or
186 * "rtp-hdrext:video:XXX" where XXX is a unique string (per media type).
187 *
188 * The valid keys are:
189 * <itemizedlist>
190 * <listitem>id: a int between in the 1-255 and 4096-4351 ranges</listitem>
191 * <listitem>uri: a URI describing the RTP Header Extension</listitem>
192 * <listitem>direction (optional): To only send or receive a RTP Header
193 * Extension, possible values are "send", "receive", "none" or "both".
194 * Defaults to "both"</listitem>
195 * </itemizedlist>
196 *
197 * Example:
198 * |[
199 * [rtp-hdrext:audio:a]
200 * id=1
201 * uri=urn:ietf:params:rtp-hdrext:toffset
202 *
203 * [rtp-hdrext:audio:abc]
204 * id=3
205 * uri=urn:ietf:params:rtp-hdrext:ntp-64
206 * direction=receive
207 * ]|
208 *
209 * Returns: (element-type FsRtpHeaderExtension) (transfer full): a
210 * #GList of #FsRtpHeaderExtension that must be freed with
211 * fs_rtp_header_extension_list_destroy()
212 */
213
214 GList *
215 fs_rtp_header_extension_list_from_keyfile (const gchar *filename,
216 FsMediaType media_type,
217 GError **error)
218 {
219 GKeyFile *keyfile = NULL;
220 GList *extensions = NULL;
221 gchar **groups = NULL;
222 gsize groups_count = 0;
223 int i;
224
225 g_return_val_if_fail (filename, NULL);
226 g_return_val_if_fail (media_type <= FS_MEDIA_TYPE_LAST, NULL);
227 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
228
229 keyfile = g_key_file_new ();
230
231 if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, error))
232 goto out;
233
234 groups = g_key_file_get_groups (keyfile, &groups_count);
235
236 if (!groups)
237 goto out;
238
239 for (i=0; i < groups_count && groups[i]; i++)
240 {
241 FsStreamDirection direction = FS_DIRECTION_BOTH;
242 gint id;
243 gchar *uri;
244 GError *gerror = NULL;
245 gchar *str;
246
247 if (g_ascii_strncasecmp (RTP_HDREXT_PREFIX, groups[i],
248 strlen (RTP_HDREXT_PREFIX)))
249 continue;
250
251 if (!g_ascii_strncasecmp (RTP_HDREXT_AUDIO_PREFIX,
252 groups[i] + strlen (RTP_HDREXT_PREFIX),
253 strlen (RTP_HDREXT_AUDIO_PREFIX)))
254 {
255 if (media_type != FS_MEDIA_TYPE_AUDIO)
256 continue;
257 }
258 else if (!g_ascii_strncasecmp (RTP_HDREXT_VIDEO_PREFIX,
259 groups[i] + strlen (RTP_HDREXT_PREFIX),
260 strlen (RTP_HDREXT_VIDEO_PREFIX)))
261 {
262 if (media_type != FS_MEDIA_TYPE_VIDEO)
263 continue;
264 }
265 else
266 {
267 continue;
268 }
269
270 id = g_key_file_get_integer (keyfile, groups[i], "id", &gerror);
271 if (gerror)
272 {
273 g_clear_error (&gerror);
274 continue;
275 }
276
277 str = g_key_file_get_string (keyfile, groups[i], "direction", &gerror);
278 if (gerror)
279 {
280 GQuark domain = gerror->domain;
281 gint code = gerror->code;
282
283 g_clear_error (&gerror);
284 if (domain != G_KEY_FILE_ERROR || code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
285 continue;
286 }
287 else
288 {
289 if (!g_ascii_strcasecmp (str, "none"))
290 direction = FS_DIRECTION_NONE;
291 else if (!g_ascii_strcasecmp (str, "send"))
292 direction = FS_DIRECTION_SEND;
293 else if (!g_ascii_strcasecmp (str, "recv") ||
294 !g_ascii_strcasecmp (str, "receive"))
295 direction = FS_DIRECTION_RECV;
296 g_free (str);
297 }
298
299 uri = g_key_file_get_string (keyfile, groups[i], "uri", &gerror);
300 if (gerror)
301 {
302 g_clear_error (&gerror);
303 continue;
304 }
305
306 extensions = g_list_append (extensions, fs_rtp_header_extension_new (id,
307 direction, uri));
308 g_free (uri);
309 }
310
311 out:
312
313 g_strfreev (groups);
314 g_key_file_free (keyfile);
315
316 return extensions;
317 }
+0
-117
gst-libs/gst/farstream/fs-rtp.h less more
0 /*
1 * Farstream - Farstream RTP specific types
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * fs-rtp.h - Farstream RTP specific types
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_RTP_H__
25 #define __FS_RTP_H__
26
27 #include <gst/gst.h>
28 #include <gst/farstream/fs-stream.h>
29
30 G_BEGIN_DECLS
31
32 /**
33 * FsRtpHeaderExtension:
34 * @id: The identifier of the RTP header extension
35 * @direction: the direction in which this extension can be used
36 * @uri: The URI that defines this extension
37 *
38 * Defines a RTP header extension with its negotiated identifier, direction
39 * and URI. They should only be created with fs_rtp_header_extension_new().
40 */
41
42 typedef struct _FsRtpHeaderExtension {
43 guint id;
44 FsStreamDirection direction;
45 gchar *uri;
46 } FsRtpHeaderExtension;
47
48 /**
49 * FS_TYPE_RTP_HEADER_EXTENSION:
50 *
51 * Boxed type for #FsRtpHeaderExtension
52 */
53
54 /**
55 * FS_TYPE_RTP_HEADER_EXTENSION_LIST:
56 *
57 * Boxed type for a #GList of #FsRtpHeaderExtension
58 */
59
60 #define FS_TYPE_RTP_HEADER_EXTENSION \
61 fs_rtp_header_extension_get_type ()
62 #define FS_TYPE_RTP_HEADER_EXTENSION_LIST \
63 fs_rtp_header_extension_list_get_type ()
64
65 GType fs_rtp_header_extension_get_type (void);
66 GType fs_rtp_header_extension_list_get_type (void);
67
68
69 FsRtpHeaderExtension *
70 fs_rtp_header_extension_new (guint id, FsStreamDirection direction,
71 const gchar *uri);
72
73 FsRtpHeaderExtension *
74 fs_rtp_header_extension_copy (FsRtpHeaderExtension *extension);
75 void
76 fs_rtp_header_extension_destroy (FsRtpHeaderExtension *extension);
77
78 gboolean
79 fs_rtp_header_extension_are_equal (FsRtpHeaderExtension *extension1,
80 FsRtpHeaderExtension *extension2);
81
82 GList *
83 fs_rtp_header_extension_list_copy (GList *extensions);
84 void
85 fs_rtp_header_extension_list_destroy (GList *extensions);
86
87 GList *
88 fs_rtp_header_extension_list_from_keyfile (const gchar *filename,
89 FsMediaType media_type,
90 GError **error);
91
92 /**
93 * FS_RTP_HEADER_EXTENSION_FORMAT:
94 *
95 * A format that can be used in printf like format strings to format a
96 * FsRtpHeaderExtension
97 */
98
99 /**
100 * FS_RTP_HEADER_EXTENSION_ARGS:
101 * @hdrext: a #FsRtpHeaderExtension
102 *
103 * Formats the codec in args for FS_RTP_HEADER_EXTENSION_ARGS
104 */
105
106 #define FS_RTP_HEADER_EXTENSION_FORMAT "%d: (%s) %s"
107 #define FS_RTP_HEADER_EXTENSION_ARGS(hdrext) \
108 (hdrext)->id, \
109 (hdrext)->direction == FS_DIRECTION_BOTH ? "both" : \
110 ((hdrext)->direction == FS_DIRECTION_RECV? "recv" : \
111 ((hdrext)->direction == FS_DIRECTION_SEND ? "send" : "none")), \
112 (hdrext)->uri
113
114 G_END_DECLS
115
116 #endif /* __FS_RTP_H__ */
+0
-682
gst-libs/gst/farstream/fs-session.c less more
0 /*
1 * Farstream - Farstream Session
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-session.c - A Farstream Session gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24
25
26 /**
27 * SECTION:fs-session
28 * @short_description: A session in a conference
29 *
30 * This object is the base implementation of a Farstream Session. It needs to be
31 * derived and implemented by a farstream conference gstreamer element. A
32 * Farstream session is defined in the same way as an RTP session. It can contain
33 * one or more participants but represents only one media stream (i.e. One
34 * session for video and one session for audio in an AV conference). Sessions
35 * contained in the same conference will be synchronised together during
36 * playback.
37 *
38 *
39 * This will communicate asynchronous events to the user through #GstMessage
40 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
41 * </para>
42 * <refsect2><title>The "<literal>farstream-send-codec-changed</literal>"
43 * message</title>
44 * |[
45 * "session" #FsSession The session that emits the message
46 * "codec" #FsCodec The new send codec
47 * "secondary-codecs" #GList A #GList of #FsCodec (to be freed
48 * with fs_codec_list_destroy())
49 * ]|
50 * <para>
51 * This message is sent on the bus when the value of the
52 * #FsSession:current-send-codec property changes.
53 * </para>
54 * </refsect2>
55 * <refsect2><title>The "<literal>farstream-codecs-changed</literal>"
56 * message</title>
57 * |[
58 * "session" #FsSession The session that emits the message
59 * ]|
60 * <para>
61 * This message is sent on the bus when the value of the
62 * #FsSession:codecs or #FsSession:codecs-without-config properties change.
63 * If one is using codecs that have configuration data that needs to be
64 * transmitted reliably, one should fetch #FsSession:codecs, otherwise,
65 * #FsSession:codecs-without-config should be enough.
66 * </para>
67 * </refsect2>
68 * <para>
69 */
70
71 #ifdef HAVE_CONFIG_H
72 #include "config.h"
73 #endif
74
75 #include "fs-session.h"
76
77 #include <gst/gst.h>
78
79 #include "fs-conference.h"
80 #include "fs-codec.h"
81 #include "fs-marshal.h"
82 #include "fs-enumtypes.h"
83 #include "fs-private.h"
84
85 #define GST_CAT_DEFAULT fs_conference_debug
86
87 /* Signals */
88 enum
89 {
90 ERROR_SIGNAL,
91 LAST_SIGNAL
92 };
93
94 /* props */
95 enum
96 {
97 PROP_0,
98 PROP_MEDIA_TYPE,
99 PROP_ID,
100 PROP_SINK_PAD,
101 PROP_CODEC_PREFERENCES,
102 PROP_CODECS,
103 PROP_CODECS_WITHOUT_CONFIG,
104 PROP_CURRENT_SEND_CODEC,
105 PROP_TYPE_OF_SERVICE
106 };
107
108 /*
109 struct _FsSessionPrivate
110 {
111 };
112
113 #define FS_SESSION_GET_PRIVATE(o) \
114 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_SESSION, FsSessionPrivate))
115 */
116
117 G_DEFINE_ABSTRACT_TYPE(FsSession, fs_session, GST_TYPE_OBJECT);
118
119 static void fs_session_get_property (GObject *object,
120 guint prop_id,
121 GValue *value,
122 GParamSpec *pspec);
123 static void fs_session_set_property (GObject *object,
124 guint prop_id,
125 const GValue *value,
126 GParamSpec *pspec);
127
128 static guint signals[LAST_SIGNAL] = { 0 };
129
130 static void
131 fs_session_class_init (FsSessionClass *klass)
132 {
133 GObjectClass *gobject_class;
134
135 gobject_class = (GObjectClass *) klass;
136
137 gobject_class->set_property = fs_session_set_property;
138 gobject_class->get_property = fs_session_get_property;
139
140 /**
141 * FsSession:media-type:
142 *
143 * The media-type of the session. This is either Audio, Video or both.
144 * This is a constructor parameter that cannot be changed.
145 *
146 */
147 g_object_class_install_property (gobject_class,
148 PROP_MEDIA_TYPE,
149 g_param_spec_enum ("media-type",
150 "The media type of the session",
151 "An enum that specifies the media type of the session",
152 FS_TYPE_MEDIA_TYPE,
153 FS_MEDIA_TYPE_AUDIO,
154 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
155
156 /**
157 * FsSession:id:
158 *
159 * The ID of the session, the first number of the pads linked to this session
160 * will be this id
161 *
162 */
163 g_object_class_install_property (gobject_class,
164 PROP_ID,
165 g_param_spec_uint ("id",
166 "The ID of the session",
167 "This ID is used on pad related to this session",
168 0, G_MAXUINT, 0,
169 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
170
171 /**
172 * FsSession:sink-pad:
173 *
174 * The Gstreamer sink pad that must be used to send media data on this
175 * session. User must unref this GstPad when done with it.
176 *
177 */
178 g_object_class_install_property (gobject_class,
179 PROP_SINK_PAD,
180 g_param_spec_object ("sink-pad",
181 "A gstreamer sink pad for this session",
182 "A pad used for sending data on this session",
183 GST_TYPE_PAD,
184 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
185
186 /**
187 * FsSession:codec-preferences:
188 *
189 * Type: GLib.List<FsCodec>
190 * Transfer: full
191 *
192 * This is the current preferences list for the local codecs. It is
193 * set by the user to specify the codec options and priorities. The user may
194 * change its value with fs_session_set_codec_preferences() at any time
195 * during a session. It is a #GList of #FsCodec.
196 * The user must free this codec list using fs_codec_list_destroy() when done.
197 *
198 * The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
199 * or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
200 * payload type of the codec will be "reserved" and not be used by any
201 * dynamically assigned payload type.
202 */
203 g_object_class_install_property (gobject_class,
204 PROP_CODEC_PREFERENCES,
205 g_param_spec_boxed ("codec-preferences",
206 "List of user preferences for the codecs",
207 "A GList of FsCodecs that allows user to set his codec options and"
208 " priorities",
209 FS_TYPE_CODEC_LIST,
210 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
211
212 /**
213 * FsSession:codecs:
214 *
215 * Type: GLib.List<FsCodec>
216 * Transfer: full
217 *
218 * This is the list of codecs used for this session. It will include the
219 * codecs and payload type used to receive media on this session. It will
220 * also include any configuration parameter that must be transmitted reliably
221 * for the other end to decode the content.
222 *
223 * It may change when the codec preferences are set, when codecs are set
224 * on a #FsStream in this session, when a #FsStream is destroyed or
225 * asynchronously when new config data is discovered.
226 *
227 * If any configuration parameter needs to be discovered, this property
228 * will be %NULL until they have been discovered. One can always get
229 * the codecs from #FsSession:codecs-without-config.
230 * The "farstream-codecs-changed" message will be emitted whenever the value
231 * of this property changes.
232 *
233 * It is a #GList of #FsCodec. User must free this codec list using
234 * fs_codec_list_destroy() when done.
235 *
236 */
237 g_object_class_install_property (gobject_class,
238 PROP_CODECS,
239 g_param_spec_boxed ("codecs",
240 "List of codecs",
241 "A GList of FsCodecs indicating the codecs for this session",
242 FS_TYPE_CODEC_LIST,
243 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
244
245 /**
246 * FsSession:codecs-without-config:
247 *
248 * Type: GLib.List<FsCodec>
249 * Transfer: full
250 *
251 * This is the same list of codecs as #FsSession:codecs without
252 * the configuration information that describes the data sent. It is suitable
253 * for configurations where a list of codecs is shared by many senders.
254 * If one is using codecs such as Theora, Vorbis or H.264 that require
255 * such information to be transmitted, the configuration data should be
256 * included in the stream and retransmitted regularly.
257 *
258 * It may change when the codec preferences are set, when codecs are set
259 * on a #FsStream in this session, when a #FsStream is destroyed or
260 * asynchronously when new config data is discovered.
261 *
262 * The "farstream-codecs-changed" message will be emitted whenever the value
263 * of this property changes.
264 *
265 * It is a #GList of #FsCodec. User must free this codec list using
266 * fs_codec_list_destroy() when done.
267 *
268 */
269 g_object_class_install_property (gobject_class,
270 PROP_CODECS_WITHOUT_CONFIG,
271 g_param_spec_boxed ("codecs-without-config",
272 "List of codecs without the configuration data",
273 "A GList of FsCodecs indicating the codecs for this session without "
274 "any configuration data",
275 FS_TYPE_CODEC_LIST,
276 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
277
278 /**
279 * FsSession:current-send-codec:
280 *
281 * Indicates the currently active send codec. A user can change the active
282 * send codec by calling fs_session_set_send_codec(). The send codec could
283 * also be automatically changed by Farstream. This property is an
284 * #FsCodec. User must free the codec using fs_codec_destroy() when done.
285 * The "farstream-send-codec-changed" message is emitted on the bus when
286 * the value of this property changes.
287 */
288 g_object_class_install_property (gobject_class,
289 PROP_CURRENT_SEND_CODEC,
290 g_param_spec_boxed ("current-send-codec",
291 "Current active send codec",
292 "An FsCodec indicating the currently active send codec",
293 FS_TYPE_CODEC,
294 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
295
296 /**
297 * FsSession:tos
298 *
299 * Sets the IP ToS field (and if possible the IPv6 TCLASS field
300 */
301 g_object_class_install_property (gobject_class,
302 PROP_TYPE_OF_SERVICE,
303 g_param_spec_uint ("tos",
304 "IP Type of Service",
305 "The IP Type of Service to set on sent packets",
306 0, 255, 0,
307 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
308
309
310 /**
311 * FsSession::error:
312 * @self: #FsSession that emitted the signal
313 * @object: The #Gobject that emitted the signal
314 * @error_no: The number of the error
315 * @error_msg: Error message
316 *
317 * This signal is emitted in any error condition, it can be emitted on any
318 * thread. Applications should listen to the GstBus for errors.
319 *
320 */
321 signals[ERROR_SIGNAL] = g_signal_new ("error",
322 G_TYPE_FROM_CLASS (klass),
323 G_SIGNAL_RUN_LAST,
324 0,
325 NULL,
326 NULL,
327 _fs_marshal_VOID__OBJECT_ENUM_STRING,
328 G_TYPE_NONE, 3, G_TYPE_OBJECT, FS_TYPE_ERROR, G_TYPE_STRING);
329 }
330
331 static void
332 fs_session_init (FsSession *self)
333 {
334 /* member init */
335 // self->priv = FS_SESSION_GET_PRIVATE (self);
336 }
337
338 static void
339 fs_session_get_property (GObject *object,
340 guint prop_id,
341 GValue *value,
342 GParamSpec *pspec)
343 {
344 GST_WARNING ("Subclass %s of FsSession does not override the %s property"
345 " getter",
346 G_OBJECT_TYPE_NAME(object),
347 g_param_spec_get_name (pspec));
348 }
349
350 static void
351 fs_session_set_property (GObject *object,
352 guint prop_id,
353 const GValue *value,
354 GParamSpec *pspec)
355 {
356 GST_WARNING ("Subclass %s of FsSession does not override the %s property"
357 " setter",
358 G_OBJECT_TYPE_NAME(object),
359 g_param_spec_get_name (pspec));
360 }
361
362 static void
363 fs_session_error_forward (GObject *signal_src,
364 FsError error_no, gchar *error_msg,
365 FsSession *session)
366 {
367 /* We just need to forward the error signal including a ref to the stream
368 * object (signal_src) */
369 g_signal_emit (session, signals[ERROR_SIGNAL], 0, signal_src, error_no,
370 error_msg);
371 }
372
373 /**
374 * fs_session_new_stream:
375 * @session: a #FsSession
376 * @participant: #FsParticipant of a participant for the new stream
377 * @direction: #FsStreamDirection describing the direction of the new stream that will
378 * be created for this participant
379 * @error: location of a #GError, or %NULL if no error occured
380 *
381 * This function creates a stream for the given participant into the active session.
382 *
383 * Returns: (transfer full): the new #FsStream that has been created.
384 * User must unref the #FsStream when the stream is ended. If an error occured,
385 * returns NULL.
386 */
387 FsStream *
388 fs_session_new_stream (FsSession *session,
389 FsParticipant *participant,
390 FsStreamDirection direction,
391 GError **error)
392 {
393 FsSessionClass *klass;
394 FsStream *new_stream = NULL;
395
396 g_return_val_if_fail (session, NULL);
397 g_return_val_if_fail (FS_IS_SESSION (session), NULL);
398 klass = FS_SESSION_GET_CLASS (session);
399 g_return_val_if_fail (klass->new_stream, NULL);
400
401 new_stream = klass->new_stream (session, participant, direction, error);
402
403 if (!new_stream)
404 return NULL;
405
406 /* Let's catch all stream errors and forward them */
407 g_signal_connect_object (new_stream, "error",
408 G_CALLBACK (fs_session_error_forward), session, 0);
409
410 return new_stream;
411 }
412
413 /**
414 * fs_session_start_telephony_event:
415 * @session: a #FsSession
416 * @event: A #FsStreamDTMFEvent or another number defined at
417 * http://www.iana.org/assignments/audio-telephone-event-registry
418 * @volume: The volume in dBm0 without the negative sign. Should be between
419 * 0 and 36. Higher values mean lower volume
420 * @method: The method used to send the event
421 *
422 * This function will start sending a telephony event (such as a DTMF
423 * tone) on the #FsSession. You have to call the function
424 * fs_session_stop_telephony_event() to stop it.
425 * This function will use any available method, if you want to use a specific
426 * method only, use fs_session_start_telephony_event_full()
427 *
428 * Returns: %TRUE if sucessful, it can return %FALSE if the #FsStream
429 * does not support this telephony event.
430 */
431 gboolean
432 fs_session_start_telephony_event (FsSession *session, guint8 event,
433 guint8 volume, FsDTMFMethod method)
434 {
435 FsSessionClass *klass;
436
437 g_return_val_if_fail (session, FALSE);
438 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
439 klass = FS_SESSION_GET_CLASS (session);
440
441 if (klass->start_telephony_event) {
442 return klass->start_telephony_event (session, event, volume, method);
443 } else {
444 GST_WARNING ("start_telephony_event not defined in class");
445 }
446 return FALSE;
447 }
448
449 /**
450 * fs_session_stop_telephony_event:
451 * @session: an #FsSession
452 * @method: The method used to send the event
453 *
454 * This function will stop sending a telephony event started by
455 * fs_session_start_telephony_event(). If the event was being sent
456 * for less than 50ms, it will be sent for 50ms minimum. If the
457 * duration was a positive and the event is not over, it will cut it
458 * short.
459 *
460 * Returns: %TRUE if sucessful, it can return %FALSE if the #FsSession
461 * does not support telephony events or if no telephony event is being sent
462 */
463 gboolean
464 fs_session_stop_telephony_event (FsSession *session, FsDTMFMethod method)
465 {
466 FsSessionClass *klass;
467
468 g_return_val_if_fail (session, FALSE);
469 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
470 klass = FS_SESSION_GET_CLASS (session);
471
472 if (klass->stop_telephony_event) {
473 return klass->stop_telephony_event (session, method);
474 } else {
475 GST_WARNING ("stop_telephony_event not defined in class");
476 }
477 return FALSE;
478 }
479
480 /**
481 * fs_session_set_send_codec:
482 * @session: a #FsSession
483 * @send_codec: a #FsCodec representing the codec to send
484 * @error: location of a #GError, or %NULL if no error occured
485 *
486 * This function will set the currently being sent codec for all streams in this
487 * session. The given #FsCodec must be taken directly from the #codecs
488 * property of the session. If the given codec is not in the codecs
489 * list, @error will be set and %FALSE will be returned. The @send_codec will be
490 * copied so it must be free'd using fs_codec_destroy() when done.
491 *
492 * Returns: %FALSE if the send codec couldn't be set.
493 */
494 gboolean
495 fs_session_set_send_codec (FsSession *session, FsCodec *send_codec,
496 GError **error)
497 {
498 FsSessionClass *klass;
499
500 g_return_val_if_fail (session, FALSE);
501 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
502 klass = FS_SESSION_GET_CLASS (session);
503
504 if (klass->set_send_codec) {
505 return klass->set_send_codec (session, send_codec, error);
506 } else {
507 GST_WARNING ("set_send_codec not defined in class");
508 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
509 "set_send_codec not defined in class");
510 }
511 return FALSE;
512 }
513
514 /**
515 * fs_session_set_codec_preferences:
516 * @session: a #FsSession
517 * @codec_preferences: (element-type FsCodec): a #GList of #FsCodec with the
518 * desired configuration
519 * @error: location of a #GError, or %NULL if no error occured
520 *
521 * Set the list of desired codec preferences. The user may
522 * change this value during an ongoing session. Note that doing this can cause
523 * the codecs to change. Therefore this requires the user to fetch
524 * the new codecs and renegotiate them with the peers. It is a #GList
525 * of #FsCodec. The changes are immediately effective.
526 * The function does not take ownership of the list.
527 *
528 * The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
529 * or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
530 * payload type of the codec will be "reserved" and not be used by any
531 * dynamically assigned payload type.
532 *
533 * If the list of specifications would invalidate all codecs, an error will
534 * be returned.
535 *
536 * Returns: %TRUE on success, %FALSE on error.
537 */
538 gboolean
539 fs_session_set_codec_preferences (FsSession *session,
540 GList *codec_preferences,
541 GError **error)
542 {
543 FsSessionClass *klass;
544
545 g_return_val_if_fail (session, FALSE);
546 g_return_val_if_fail (FS_IS_SESSION (session), FALSE);
547 klass = FS_SESSION_GET_CLASS (session);
548
549 if (klass->set_codec_preferences) {
550 return klass->set_codec_preferences (session, codec_preferences, error);
551 } else {
552 GST_WARNING ("set_send_preferences not defined in class");
553 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
554 "set_codec_preferences not defined in class");
555 }
556 return FALSE;
557 }
558
559 /**
560 * fs_session_emit_error:
561 * @session: #FsSession on which to emit the error signal
562 * @error_no: The number of the error of type #FsError
563 * @error_msg: Error message
564 *
565 * This function emit the "error" signal on a #FsSession, it should only be
566 * called by subclasses.
567 */
568 void
569 fs_session_emit_error (FsSession *session,
570 gint error_no,
571 const gchar *error_msg)
572 {
573 g_signal_emit (session, signals[ERROR_SIGNAL], 0, session, error_no,
574 error_msg);
575 }
576
577 /**
578 * fs_session_list_transmitters:
579 * @session: A #FsSession
580 *
581 * Get the list of all available transmitters for this session.
582 *
583 * Returns: (transfer full): a newly-allocagted %NULL terminated array of
584 * named of transmitters or %NULL if no transmitter is needed for this type of
585 * session. It should be freed with g_strfreev().
586 */
587
588 gchar **
589 fs_session_list_transmitters (FsSession *session)
590 {
591 FsSessionClass *klass;
592
593 g_return_val_if_fail (session, NULL);
594 g_return_val_if_fail (FS_IS_SESSION (session), NULL);
595 klass = FS_SESSION_GET_CLASS (session);
596
597 if (klass->list_transmitters) {
598 return klass->list_transmitters (session);
599 } else {
600 return NULL;
601 }
602 }
603
604
605 /**
606 * fs_session_get_stream_transmitter_type:
607 * @session: A #FsSession
608 * @transmitter: The name of the transmitter
609 *
610 * Returns the GType of the stream transmitter, bindings can use it
611 * to validate/convert the parameters passed to fs_session_new_stream().
612 *
613 * Returns: The #GType of the stream transmitter
614 */
615 GType
616 fs_session_get_stream_transmitter_type (FsSession *session,
617 const gchar *transmitter)
618 {
619 FsSessionClass *klass;
620
621 g_return_val_if_fail (session, 0);
622 g_return_val_if_fail (FS_IS_SESSION (session), 0);
623 klass = FS_SESSION_GET_CLASS (session);
624
625 if (klass->get_stream_transmitter_type)
626 return klass->get_stream_transmitter_type (session, transmitter);
627
628 return 0;
629 }
630
631 /**
632 * fs_session_codecs_need_resend:
633 * @session: a #FsSession
634 * @old_codecs: Codecs previously retrieved from the #FsSession:codecs property
635 * @new_codecs: Codecs recently retrieved from the #FsSession:codecs property
636 *
637 * Some codec updates need to be reliably transmitted to the other side
638 * because they contain important parameters required to decode the media.
639 * Other codec updates, caused by user action, don't.
640 *
641 * Returns: (element-type FsCodec) (transfer full): A new #GList of
642 * #FsCodec that need to be resent or %NULL if there are none. This
643 * list must be freed with fs_codec_list_destroy().
644 */
645 GList *
646 fs_session_codecs_need_resend (FsSession *session,
647 GList *old_codecs, GList *new_codecs)
648 {
649 FsSessionClass *klass;
650
651 g_return_val_if_fail (session, 0);
652 g_return_val_if_fail (FS_IS_SESSION (session), 0);
653 klass = FS_SESSION_GET_CLASS (session);
654
655 if (klass->codecs_need_resend)
656 return klass->codecs_need_resend (session, old_codecs, new_codecs);
657
658 return NULL;
659 }
660
661 /**
662 * fs_session_destroy:
663 * @session: a #FsSession
664 *
665 * This will cause the session to remove all links to other objects and to
666 * remove itself from the #FsConference, it will also destroy all #FsStream
667 * inside this #FsSession Once a #FsSession has been destroyed, it
668 * can not be used anymore.
669 *
670 * It is strongly recommended to call this function from the main thread because
671 * releasing the application's reference to a session.
672 */
673
674 void
675 fs_session_destroy (FsSession *session)
676 {
677 g_return_if_fail (session);
678 g_return_if_fail (FS_IS_SESSION (session));
679
680 g_object_run_dispose (G_OBJECT (session));
681 }
+0
-204
gst-libs/gst/farstream/fs-session.h less more
0 /*
1 * Farstream - Farstream Session
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-session.h - A Farstream Session gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_SESSION_H__
25 #define __FS_SESSION_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include <gst/farstream/fs-stream.h>
31 #include <gst/farstream/fs-participant.h>
32 #include <gst/farstream/fs-codec.h>
33
34 G_BEGIN_DECLS
35
36 /* TYPE MACROS */
37 #define FS_TYPE_SESSION \
38 (fs_session_get_type ())
39 #define FS_SESSION(obj) \
40 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_SESSION, FsSession))
41 #define FS_SESSION_CLASS(klass) \
42 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_SESSION, FsSessionClass))
43 #define FS_IS_SESSION(obj) \
44 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_SESSION))
45 #define FS_IS_SESSION_CLASS(klass) \
46 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_SESSION))
47 #define FS_SESSION_GET_CLASS(obj) \
48 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_SESSION, FsSessionClass))
49 #define FS_SESSION_CAST(obj) ((FsSession *) (obj))
50
51 typedef struct _FsSession FsSession;
52 typedef struct _FsSessionClass FsSessionClass;
53 typedef struct _FsSessionPrivate FsSessionPrivate;
54
55 /**
56 * FsDTMFEvent:
57 *
58 * An enum that represents the different DTMF event that can be sent to a
59 * #FsSession. The values corresponds those those defined in RFC 4733
60 * The rest of the possibles values are in the IANA registry at:
61 * http://www.iana.org/assignments/audio-telephone-event-registry
62 *
63 */
64 typedef enum _FsDTMFEvent
65 {
66 /*< protected >*/
67 FS_DTMF_EVENT_0 = 0,
68 FS_DTMF_EVENT_1 = 1,
69 FS_DTMF_EVENT_2 = 2,
70 FS_DTMF_EVENT_3 = 3,
71 FS_DTMF_EVENT_4 = 4,
72 FS_DTMF_EVENT_5 = 5,
73 FS_DTMF_EVENT_6 = 6,
74 FS_DTMF_EVENT_7 = 7,
75 FS_DTMF_EVENT_8 = 8,
76 FS_DTMF_EVENT_9 = 9,
77 FS_DTMF_EVENT_STAR = 10,
78 FS_DTMF_EVENT_POUND = 11,
79 FS_DTMF_EVENT_A = 12,
80 FS_DTMF_EVENT_B = 13,
81 FS_DTMF_EVENT_C = 14,
82 FS_DTMF_EVENT_D = 15
83 } FsDTMFEvent;
84
85 /**
86 * FsDTMFMethod:
87 * @FS_DTMF_METHOD_AUTO: Send in any possible way
88 * @FS_DTMF_METHOD_RTP_RFC4733: Send as a special payload type defined by RFC 4733
89 * (which obsoletes RFC 2833)
90 * @FS_DTMF_METHOD_SOUND: Send as tones as in-band audio sound
91 *
92 * An enum that represents the different ways a DTMF event can be sent
93 *
94 */
95 typedef enum _FsDTMFMethod
96 {
97 FS_DTMF_METHOD_AUTO = 0,
98 FS_DTMF_METHOD_RTP_RFC4733,
99 FS_DTMF_METHOD_SOUND
100 } FsDTMFMethod;
101
102 /**
103 * FsSessionClass:
104 * @parent_class: Our parent
105 * @new_stream: Create a new #FsStream
106 * @start_telephony_event: Starts a telephony event
107 * @stop_telephony_event: Stops a telephony event
108 * @set_send_codec: Forces sending with a specific codec
109 * @set_codec_preferences: Specifies the codec preferences
110 * @list_transmitters: Returns a list of the available transmitters
111 * @get_stream_transmitter_type: Returns the GType of the stream transmitter
112 * @codecs_need_resend: Returns the list of codecs that need resending
113 *
114 * You must override at least new_stream in a subclass.
115 */
116
117
118 struct _FsSessionClass
119 {
120 GstObjectClass parent_class;
121
122 /*virtual functions */
123 FsStream *(* new_stream) (FsSession *session,
124 FsParticipant *participant,
125 FsStreamDirection direction,
126 GError **error);
127
128 gboolean (* start_telephony_event) (FsSession *session, guint8 event,
129 guint8 volume, FsDTMFMethod method);
130 gboolean (* stop_telephony_event) (FsSession *session, FsDTMFMethod method);
131
132 gboolean (* set_send_codec) (FsSession *session, FsCodec *send_codec,
133 GError **error);
134 gboolean (* set_codec_preferences) (FsSession *session,
135 GList *codec_preferences,
136 GError **error);
137
138 gchar** (* list_transmitters) (FsSession *session);
139
140 GType (* get_stream_transmitter_type) (FsSession *session,
141 const gchar *transmitter);
142
143 GList* (* codecs_need_resend) (FsSession *session, GList *old_codecs,
144 GList *new_codecs);
145
146 /*< private >*/
147 gpointer _padding[8];
148 };
149
150 /**
151 * FsSession:
152 *
153 * All members are private, access them using methods and properties
154 */
155 struct _FsSession
156 {
157 GstObject parent;
158 /*< private >*/
159
160 FsSessionPrivate *priv;
161
162
163 gpointer _padding[8];
164 };
165
166 GType fs_session_get_type (void);
167
168 FsStream *fs_session_new_stream (FsSession *session,
169 FsParticipant *participant,
170 FsStreamDirection direction,
171 GError **error);
172
173 gboolean fs_session_start_telephony_event (FsSession *session, guint8 event,
174 guint8 volume, FsDTMFMethod method);
175
176 gboolean fs_session_stop_telephony_event (FsSession *session,
177 FsDTMFMethod method);
178
179 gboolean fs_session_set_send_codec (FsSession *session, FsCodec *send_codec,
180 GError **error);
181
182 gboolean fs_session_set_codec_preferences (FsSession *session,
183 GList *codec_preferences,
184 GError **error);
185
186 gchar **fs_session_list_transmitters (FsSession *session);
187
188 void fs_session_emit_error (FsSession *session,
189 gint error_no,
190 const gchar *error_msg);
191
192 GType fs_session_get_stream_transmitter_type (FsSession *session,
193 const gchar *transmitter);
194
195 GList* fs_session_codecs_need_resend (FsSession *session,
196 GList *old_codecs, GList *new_codecs);
197
198 void fs_session_destroy (FsSession *session);
199
200
201 G_END_DECLS
202
203 #endif /* __FS_SESSION_H__ */
+0
-453
gst-libs/gst/farstream/fs-stream-transmitter.c less more
0 /*
1 * Farstream - Farstream Stream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream-transmitter.c - A Farstream Stream Transmitter gobject
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-stream-transmitter
26 * @short_description: A stream transmitter object used to convey per-stream
27 * information to a transmitter.
28 *
29 * This object is the base implementation of a Farstream Stream Transmitter.
30 * It needs to be derived and implement by a Farstream transmitter.
31 * A Farstream Stream transmitter is used to convery per-stream information
32 * to a transmitter, this is mostly local and remote candidates
33 *
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "fs-stream-transmitter.h"
41
42 #include <gst/gst.h>
43
44 #include "fs-marshal.h"
45 #include "fs-conference.h"
46 #include "fs-private.h"
47
48 #define GST_CAT_DEFAULT fs_conference_debug
49
50 /* Signals */
51 enum
52 {
53 ERROR_SIGNAL,
54 NEW_LOCAL_CANDIDATE,
55 NEW_ACTIVE_CANDIDATE_PAIR,
56 LOCAL_CANDIDATES_PREPARED,
57 KNOWN_SOURCE_PACKET_RECEIVED,
58 STATE_CHANGED,
59 LAST_SIGNAL
60 };
61
62 /* props */
63 enum
64 {
65 PROP_0,
66 PROP_SENDING,
67 PROP_PREFERRED_LOCAL_CANDIDATES,
68 PROP_ASSOCIATE_ON_SOURCE
69 };
70
71 struct _FsStreamTransmitterPrivate
72 {
73 gboolean disposed;
74 };
75
76 G_DEFINE_ABSTRACT_TYPE(FsStreamTransmitter, fs_stream_transmitter,
77 GST_TYPE_OBJECT);
78
79
80 #define FS_STREAM_TRANSMITTER_GET_PRIVATE(o) \
81 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_STREAM_TRANSMITTER, \
82 FsStreamTransmitterPrivate))
83
84 static void fs_stream_transmitter_get_property (GObject *object,
85 guint prop_id,
86 GValue *value,
87 GParamSpec *pspec);
88 static void fs_stream_transmitter_set_property (GObject *object,
89 guint prop_id,
90 const GValue *value,
91 GParamSpec *pspec);
92
93 static guint signals[LAST_SIGNAL] = { 0 };
94
95 static void
96 fs_stream_transmitter_class_init (FsStreamTransmitterClass *klass)
97 {
98 GObjectClass *gobject_class;
99
100 gobject_class = (GObjectClass *) klass;
101
102 gobject_class->set_property = fs_stream_transmitter_set_property;
103 gobject_class->get_property = fs_stream_transmitter_get_property;
104
105
106 /**
107 * FsStreamTransmitter:sending:
108 *
109 * A network source #GstElement to be used by the #FsSession
110 *
111 */
112 g_object_class_install_property (gobject_class,
113 PROP_SENDING,
114 g_param_spec_boolean ("sending",
115 "Whether to send from this transmitter",
116 "If set to FALSE, the transmitter will stop sending to this person",
117 TRUE,
118 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
119
120 /**
121 * FsStreamTransmitter:preferred-local-candidate:
122 *
123 * The list of preferred local candidates for this stream
124 * It is a #GList of #FsCandidates
125 *
126 */
127 g_object_class_install_property (gobject_class,
128 PROP_PREFERRED_LOCAL_CANDIDATES,
129 g_param_spec_boxed ("preferred-local-candidates",
130 "The preferred candidates",
131 "A GList of FsCandidates",
132 FS_TYPE_CANDIDATE_LIST,
133 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
134
135 /**
136 * FsStreamTransmitter:associate-on-source
137 *
138 * This tells the stream transmitter to associate incoming data with this
139 * based on the source without looking at the content if possible.
140 *
141 */
142
143 g_object_class_install_property (gobject_class,
144 PROP_ASSOCIATE_ON_SOURCE,
145 g_param_spec_boolean ("associate-on-source",
146 "Associate incoming data based on the source address",
147 "Whether to associate incoming data stream based on the source address",
148 TRUE,
149 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150
151 /**
152 * FsStreamTransmitter::error:
153 * @self: #FsStreamTransmitter that emitted the signal
154 * @errorno: The number of the error
155 * @error_msg: Error message (for the programmer)
156 *
157 * This signal is emitted in any error condition
158 *
159 */
160 signals[ERROR_SIGNAL] = g_signal_new ("error",
161 G_TYPE_FROM_CLASS (klass),
162 G_SIGNAL_RUN_LAST,
163 0,
164 NULL,
165 NULL,
166 _fs_marshal_VOID__ENUM_STRING,
167 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
168
169 /**
170 * FsStreamTransmitter::new-active-candidate-pair:
171 * @self: #FsStreamTransmitter that emitted the signal
172 * @local_candidate: #FsCandidate of the local candidate being used
173 * @remote_candidate: #FsCandidate of the remote candidate being used
174 *
175 * This signal is emitted when there is a new active chandidate pair that has
176 * been established. This is specially useful for ICE where the active
177 * candidate pair can change automatically due to network conditions. The user
178 * must not modify the candidates and must copy them if he wants to use them
179 * outside the callback scope.
180 *
181 */
182 signals[NEW_ACTIVE_CANDIDATE_PAIR] = g_signal_new
183 ("new-active-candidate-pair",
184 G_TYPE_FROM_CLASS (klass),
185 G_SIGNAL_RUN_LAST,
186 0,
187 NULL,
188 NULL,
189 _fs_marshal_VOID__BOXED_BOXED,
190 G_TYPE_NONE, 2, FS_TYPE_CANDIDATE, FS_TYPE_CANDIDATE);
191
192 /**
193 * FsStreamTransmitter::new-local-candidate:
194 * @self: #FsStream that emitted the signal
195 * @local_candidate: #FsCandidate of the local candidate
196 *
197 * This signal is emitted when a new local candidate is discovered.
198 *
199 */
200 signals[NEW_LOCAL_CANDIDATE] = g_signal_new
201 ("new-local-candidate",
202 G_TYPE_FROM_CLASS (klass),
203 G_SIGNAL_RUN_LAST,
204 0,
205 NULL,
206 NULL,
207 g_cclosure_marshal_VOID__BOXED,
208 G_TYPE_NONE, 1, FS_TYPE_CANDIDATE);
209
210 /**
211 * FsStreamTransmitter::local-candidates-prepared:
212 * @self: #FsStreamTransmitter that emitted the signal
213 *
214 * This signal is emitted when all local candidates have been
215 * prepared, an ICE implementation would send its SDP offer or answer.
216 *
217 */
218 signals[LOCAL_CANDIDATES_PREPARED] = g_signal_new
219 ("local-candidates-prepared",
220 G_TYPE_FROM_CLASS (klass),
221 G_SIGNAL_RUN_LAST,
222 0,
223 NULL,
224 NULL,
225 g_cclosure_marshal_VOID__VOID,
226 G_TYPE_NONE, 0);
227
228 /**
229 * FsStreamTransmitter::known-source-packet-received:
230 * @self: #FsStreamTransmitter that emitted the signal
231 * @component: The Component on which this buffer was received
232 * @buffer: the #GstBuffer coming from the known source
233 *
234 * This signal is emitted when a buffer coming from a confirmed known source
235 * is received.
236 */
237 signals[KNOWN_SOURCE_PACKET_RECEIVED] = g_signal_new
238 ("known-source-packet-received",
239 G_TYPE_FROM_CLASS (klass),
240 G_SIGNAL_RUN_LAST,
241 0,
242 NULL,
243 NULL,
244 _fs_marshal_VOID__UINT_POINTER,
245 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
246
247
248 /**
249 * FsStreamTransmitter::state-changed
250 * @self: #FsStreamTransmitter that emitted the signal
251 * @component: the id of the component which state has changed
252 * @state: the new state of the component
253 *
254 * This signal is emitted when the ICE state (or equivalent) of the component
255 * changes
256 */
257 signals[STATE_CHANGED] = g_signal_new
258 ("state-changed",
259 G_TYPE_FROM_CLASS (klass),
260 G_SIGNAL_RUN_LAST,
261 0,
262 NULL,
263 NULL,
264 _fs_marshal_VOID__UINT_ENUM,
265 G_TYPE_NONE, 2, G_TYPE_UINT, FS_TYPE_STREAM_STATE);
266
267
268 g_type_class_add_private (klass, sizeof (FsStreamTransmitterPrivate));
269 }
270
271 static void
272 fs_stream_transmitter_init (FsStreamTransmitter *self)
273 {
274 /* member init */
275 self->priv = FS_STREAM_TRANSMITTER_GET_PRIVATE (self);
276 self->priv->disposed = FALSE;
277 }
278
279 static void
280 fs_stream_transmitter_get_property (GObject *object,
281 guint prop_id,
282 GValue *value,
283 GParamSpec *pspec)
284 {
285 GST_WARNING ("Subclass %s of FsStreamTransmitter does not override the %s"
286 " property getter",
287 G_OBJECT_TYPE_NAME(object),
288 g_param_spec_get_name (pspec));
289 }
290
291 static void
292 fs_stream_transmitter_set_property (GObject *object,
293 guint prop_id,
294 const GValue *value,
295 GParamSpec *pspec)
296 {
297 switch (prop_id)
298 {
299 /* These properties, we can safely not override */
300 case PROP_ASSOCIATE_ON_SOURCE:
301 break;
302 default:
303 GST_WARNING ("Subclass %s of FsStreamTransmitter does not override the %s"
304 " property setter",
305 G_OBJECT_TYPE_NAME(object),
306 g_param_spec_get_name (pspec));
307 break;
308 }
309 }
310
311
312 /**
313 * fs_stream_transmitter_add_remote_candidates
314 * @streamtransmitter: a #FsStreamTranmitter
315 * @candidates: (element-type FsCandidate): a #GList of the remote candidates
316 * @error: location of a #GError, or NULL if no error occured
317 *
318 * This function is used to add remote candidates to the transmitter
319 *
320 * Returns: TRUE of the candidate could be added, FALSE if it couldnt
321 * (and the #GError will be set)
322 */
323
324 gboolean
325 fs_stream_transmitter_add_remote_candidates (
326 FsStreamTransmitter *streamtransmitter,
327 GList *candidates,
328 GError **error)
329 {
330 FsStreamTransmitterClass *klass;
331
332 g_return_val_if_fail (streamtransmitter, FALSE);
333 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
334 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
335
336 if (klass->add_remote_candidates) {
337 return klass->add_remote_candidates (streamtransmitter, candidates, error);
338 } else {
339 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
340 "add_remote_candidate not defined in stream transmitter class");
341 }
342
343 return FALSE;
344 }
345
346 /**
347 * fs_stream_transmitter_force_remote_candidates:
348 * @streamtransmitter: a #FsStreamTransmitter
349 * @remote_candidates: (element-type FsCandidate): a #GList of #FsCandidate to
350 * force
351 * @error: location of a #GError, or NULL if no error occured
352 *
353 * This function forces data to be sent immediately to the selected remote
354 * candidate, by-passing any connectivity checks. There should be at most
355 * one candidate per component.
356 *
357 * Returns: %TRUE if the candidates could be forced, %FALSE otherwise
358 */
359
360 gboolean
361 fs_stream_transmitter_force_remote_candidates (
362 FsStreamTransmitter *streamtransmitter,
363 GList *remote_candidates,
364 GError **error)
365 {
366 FsStreamTransmitterClass *klass;
367
368 g_return_val_if_fail (streamtransmitter, FALSE);
369 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
370 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
371
372 if (klass->force_remote_candidates) {
373 return klass->force_remote_candidates (streamtransmitter,
374 remote_candidates, error);
375 } else {
376 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
377 "force_remote_candidates not defined in stream transmitter class");
378 }
379
380 return FALSE;
381 }
382
383 /**
384 * fs_stream_transmitter_gather_local_candidates:
385 * @streamtransmitter: a #FsStreamTransmitter
386 * @error: location of a #GErrorh, or NULL if no error occured
387 *
388 * This function tells the transmitter to start gathering local candidates,
389 * signals for new candidates and newly active candidates can be emitted
390 * during the call to this function.
391 *
392 * Returns: %TRUE if it succeeds (or is not implemented), %FALSE otherwise
393 */
394
395 gboolean
396 fs_stream_transmitter_gather_local_candidates (
397 FsStreamTransmitter *streamtransmitter,
398 GError **error)
399 {
400 FsStreamTransmitterClass *klass;
401
402 g_return_val_if_fail (streamtransmitter, FALSE);
403 g_return_val_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter), FALSE);
404 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
405
406 if (klass->gather_local_candidates)
407 return klass->gather_local_candidates (streamtransmitter, error);
408 else
409 return TRUE;
410 }
411
412
413
414 /**
415 * fs_stream_transmitter_stop:
416 * @streamtransmitter: a #FsStreamTransmitter
417 *
418 * This functions stops the #FsStreamTransmitter, it must be called before
419 * the last reference is dropped.
420 */
421
422 void
423 fs_stream_transmitter_stop (FsStreamTransmitter *streamtransmitter)
424 {
425 FsStreamTransmitterClass *klass;
426
427 g_return_if_fail (streamtransmitter);
428 g_return_if_fail (FS_IS_STREAM_TRANSMITTER (streamtransmitter));
429 klass = FS_STREAM_TRANSMITTER_GET_CLASS (streamtransmitter);
430
431 if (klass->stop)
432 klass->stop (streamtransmitter);
433 }
434
435
436 /**
437 * fs_stream_transmitter_emit_error:
438 * @streamtransmitter: #FsStreamTransmitter on which to emit the error signal
439 * @error_no: The number of the error
440 * @error_msg: Error message (for the programmer)
441 *
442 * This function emit the "error" signal on a #FsStreamTransmitter, it should
443 * only be called by subclasses.
444 */
445 void
446 fs_stream_transmitter_emit_error (FsStreamTransmitter *streamtransmitter,
447 gint error_no,
448 const gchar *error_msg)
449 {
450 g_signal_emit (streamtransmitter, signals[ERROR_SIGNAL], 0, error_no,
451 error_msg);
452 }
+0
-126
gst-libs/gst/farstream/fs-stream-transmitter.h less more
0 /*
1 * Farstream - Farstream Stream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream-transmitter.h - A Farstream Stream Transmitter (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_STREAM_TRANSMITTER_H__
25 #define __FS_STREAM_TRANSMITTER_H__
26
27 #include <gst/gst.h>
28
29 #include <gst/farstream/fs-candidate.h>
30
31 G_BEGIN_DECLS
32
33 /* TYPE MACROS */
34 #define FS_TYPE_STREAM_TRANSMITTER \
35 (fs_stream_transmitter_get_type ())
36 #define FS_STREAM_TRANSMITTER(obj) \
37 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_STREAM_TRANSMITTER, \
38 FsStreamTransmitter))
39 #define FS_STREAM_TRANSMITTER_CLASS(klass) \
40 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_STREAM_TRANSMITTER, \
41 FsStreamTransmitterClass))
42 #define FS_IS_STREAM_TRANSMITTER(obj) \
43 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_STREAM_TRANSMITTER))
44 #define FS_IS_STREAM_TRANSMITTER_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_STREAM_TRANSMITTER))
46 #define FS_STREAM_TRANSMITTER_GET_CLASS(obj) \
47 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_STREAM_TRANSMITTER, \
48 FsStreamTransmitterClass))
49 #define FS_STREAM_TRANSMITTER_CAST(obj) ((FsStreamTransmitter *) (obj))
50
51 typedef struct _FsStreamTransmitter FsStreamTransmitter;
52 typedef struct _FsStreamTransmitterClass FsStreamTransmitterClass;
53 typedef struct _FsStreamTransmitterPrivate FsStreamTransmitterPrivate;
54
55 /**
56 * FsStreamTransmitterClass:
57 * @parent_class: Our parent
58 * @add_remote_candidates: Sets the remote candidates
59 * @force_remote_candidates: Forces certain remote candidates
60 * @gather_local_candidates: Starts the gathering of local candidates
61 * @stop: Stop the stream transmitter synchronously (does any Gst stopping
62 * that needs to be done)
63 *
64 * You must override the add_remote_candidate in a subclass
65 */
66
67 struct _FsStreamTransmitterClass
68 {
69 GstObjectClass parent_class;
70
71 /*virtual functions */
72 gboolean (*add_remote_candidates) (FsStreamTransmitter *streamtransmitter,
73 GList *candidates, GError **error);
74
75 gboolean (*force_remote_candidates) (FsStreamTransmitter *streamtransmitter,
76 GList *remote_candidates,
77 GError **error);
78 gboolean (*gather_local_candidates) (FsStreamTransmitter *streamtransmitter,
79 GError **error);
80 void (*stop) (FsStreamTransmitter *streamtransmitter);
81
82 /*< private >*/
83 gpointer _padding[8];
84 };
85
86 /**
87 * FsStreamTransmitter:
88 *
89 * All members are private, access them using methods and properties
90 */
91 struct _FsStreamTransmitter
92 {
93 GstObject parent;
94
95 /*< private >*/
96 FsStreamTransmitterPrivate *priv;
97 gpointer _padding[8];
98 };
99
100 GType fs_stream_transmitter_get_type (void);
101
102 gboolean fs_stream_transmitter_add_remote_candidates (
103 FsStreamTransmitter *streamtransmitter,
104 GList *candidates,
105 GError **error);
106
107 gboolean fs_stream_transmitter_force_remote_candidates (
108 FsStreamTransmitter *streamtransmitter,
109 GList *remote_candidates,
110 GError **error);
111
112 gboolean
113 fs_stream_transmitter_gather_local_candidates (
114 FsStreamTransmitter *streamtransmitter,
115 GError **error);
116
117 void fs_stream_transmitter_stop (FsStreamTransmitter *streamtransmitter);
118
119 void fs_stream_transmitter_emit_error (FsStreamTransmitter *streamtransmitter,
120 gint error_no,
121 const gchar *error_msg);
122
123 G_END_DECLS
124
125 #endif /* __FS_STREAM_TRANSMITTER_H__ */
+0
-660
gst-libs/gst/farstream/fs-stream.c less more
0 /*
1 * Farstream - Farstream Stream
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream.c - A Farstream Stream gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-stream
26 * @short_description: A stream in a session in a conference
27 *
28 * This object is the base implementation of a Farstream Stream. It
29 * needs to be derived and implemented by a Farstream conference GStreamer
30 * element. A Farstream Stream is a media stream originating from a
31 * #FsParticipant inside a #FsSession. In fact, a #FsStream instance is
32 * obtained by adding a participant into a session using
33 * fs_session_new_stream().
34 *
35 *
36 * This will communicate asynchronous events to the user through #GstMessage
37 * of type #GST_MESSAGE_ELEMENT sent over the #GstBus.
38 * </para>
39 * <refsect2><title>The "<literal>farstream-new-local-candidate</literal>" message</title>
40 * |[
41 * "stream" #FsStream The stream that emits the message
42 * "candidate" #FsCandidate The new candidate
43 * ]|
44 * <para>
45 * This message is emitted when a new local candidate is discovered.
46 * </para>
47 * </refsect2>
48 * <refsect2><title>The "<literal>farstream-local-candidates-prepared</literal>" message</title>
49 * |[
50 * "stream" #FsStream The stream that emits the message
51 * ]|
52 * <para>
53 * This signal is emitted when all local candidates have been
54 * prepared, an ICE implementation would send its SDP offer or answer.
55 * </para>
56 * </refsect2>
57 * <refsect2><title>The "<literal>farstream-new-active-candidate-pair</literal>" message</title>
58 * |[
59 * "stream" #FsStream The stream that emits the message
60 * "local-candidate" #FsCandidate Local candidate being used
61 * "remote-candidate" #FsCandidate Remote candidate being used
62 * ]|
63 * <para>
64 * This message is emitted when there is a new active candidate pair that has
65 * been established. This is specially useful for ICE where the active
66 * candidate pair can change automatically due to network conditions. The user
67 * must not modify the candidates and must copy them if he wants to use them
68 * outside the callback scope. This message is emitted once per component.
69 * </para>
70 * </refsect2>
71 * <refsect2><title>The "<literal>farstream-recv-codecs-changed</literal>" message</title>
72 * |[
73 * "stream" #FsStream The stream that emits the message
74 * "codecs" #FsCodecGList A #GList of #FsCodec
75 * ]|
76 * <para>
77 * This message is emitted when the content of the
78 * #FsStream:current-recv-codecs property changes. It is normally emitted
79 * right after the #FsStream::src-pad-added signal only if that codec was not
80 * previously received in this stream, but it can also be emitted if the pad
81 * already exists, but the source material that will come to it is different.
82 * The list of new recv-codecs is included in the message
83 * </para>
84 * </refsect2>
85 * <refsect2><title>The "<literal>farstream-component-state-changed</literal>" message</title>
86 * |[
87 * "stream" #FsStream The stream that emits the message
88 * "component" #guint The component whose state changed
89 * "state" #FsStreamState The new state of the component
90 * ]|
91 * <para>
92 * This message is emitted the state of a component of a stream changes.
93 * </para>
94 * </refsect2>
95 * <para>
96 */
97
98 #ifdef HAVE_CONFIG_H
99 #include "config.h"
100 #endif
101
102 #include "fs-stream.h"
103
104 #include <gst/gst.h>
105
106 #include "fs-session.h"
107 #include "fs-marshal.h"
108 #include "fs-codec.h"
109 #include "fs-candidate.h"
110 #include "fs-stream-transmitter.h"
111 #include "fs-conference.h"
112 #include "fs-enumtypes.h"
113 #include "fs-private.h"
114
115 /* Signals */
116 enum
117 {
118 ERROR_SIGNAL,
119 SRC_PAD_ADDED,
120 LAST_SIGNAL
121 };
122
123 /* props */
124 enum
125 {
126 PROP_0,
127 PROP_REMOTE_CODECS,
128 PROP_NEGOTIATED_CODECS,
129 PROP_CURRENT_RECV_CODECS,
130 PROP_DIRECTION,
131 PROP_PARTICIPANT,
132 PROP_SESSION
133 };
134
135
136 struct _FsStreamPrivate
137 {
138 GMutex *mutex;
139 GList *src_pads;
140 guint32 src_pads_cookie;
141 };
142
143 #define FS_STREAM_GET_PRIVATE(o) \
144 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_STREAM, FsStreamPrivate))
145
146
147 G_DEFINE_ABSTRACT_TYPE(FsStream, fs_stream, GST_TYPE_OBJECT);
148
149 static void fs_stream_get_property (GObject *object,
150 guint prop_id,
151 GValue *value,
152 GParamSpec *pspec);
153 static void fs_stream_set_property (GObject *object,
154 guint prop_id,
155 const GValue *value,
156 GParamSpec *pspec);
157 static void fs_stream_finalize (GObject *obj);
158
159 static guint signals[LAST_SIGNAL] = { 0 };
160
161 #define FS_STREAM_LOCK(self) g_mutex_lock((self)->priv->mutex)
162 #define FS_STREAM_UNLOCK(self) g_mutex_unlock((self)->priv->mutex)
163
164 static void
165 fs_stream_class_init (FsStreamClass *klass)
166 {
167 GObjectClass *gobject_class;
168
169 gobject_class = (GObjectClass *) klass;
170
171 gobject_class->set_property = fs_stream_set_property;
172 gobject_class->get_property = fs_stream_get_property;
173 gobject_class->finalize = fs_stream_finalize;
174
175 /**
176 * FsStream:remote-codecs:
177 *
178 * Type: GLib.List<FsCodec>
179 * Transfer: full
180 *
181 * This is the list of remote codecs for this stream. They must be set by the
182 * user as soon as they are known using fs_stream_set_remote_codecs()
183 * (generally through external signaling). It is a #GList of #FsCodec.
184 *
185 */
186 g_object_class_install_property (gobject_class,
187 PROP_REMOTE_CODECS,
188 g_param_spec_boxed ("remote-codecs",
189 "List of remote codecs",
190 "A GList of FsCodecs of the remote codecs",
191 FS_TYPE_CODEC_LIST,
192 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
193
194 /**
195 * FsStream:negotiated-codecs:
196 *
197 * Type: GLib.List<FsCodec>
198 * Transfer: full
199 *
200 * This is the list of negotiatied codecs, it is the same list as the list
201 * of #FsCodec from the parent #FsSession, except that the codec config data
202 * has been replaced with the data from the remote codecs for this stream.
203 * This is the list of #FsCodec used to receive data from this stream.
204 * It is a #GList of #FsCodec.
205 *
206 */
207 g_object_class_install_property (gobject_class,
208 PROP_NEGOTIATED_CODECS,
209 g_param_spec_boxed ("negotiated-codecs",
210 "List of remote codecs",
211 "A GList of FsCodecs of the negotiated codecs for this stream",
212 FS_TYPE_CODEC_LIST,
213 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
214
215 /**
216 * FsStream:current-recv-codecs:
217 *
218 * Type: GLib.List<FsCodec>
219 * Transfer: full
220 *
221 * This is the list of codecs that have been received by this stream.
222 * The user must free the list if fs_codec_list_destroy().
223 * The "farstream-recv-codecs-changed" message is send on the #GstBus
224 * when the value of this property changes.
225 * It is normally emitted right after #FsStream::src-pad-added
226 * only if that codec was not previously received in this stream, but it can
227 * also be emitted if the pad already exists, but the source material that
228 * will come to it is different.
229 *
230 */
231 g_object_class_install_property (gobject_class,
232 PROP_CURRENT_RECV_CODECS,
233 g_param_spec_boxed ("current-recv-codecs",
234 "The codecs currently being received",
235 "A GList of FsCodec representing the codecs that have been received",
236 FS_TYPE_CODEC_LIST,
237 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
238
239 /**
240 * FsStream:direction:
241 *
242 * The direction of the stream. This property is set initially as a parameter
243 * to the fs_session_new_stream() function. It can be changed later if
244 * required by setting this property.
245 *
246 */
247 g_object_class_install_property (gobject_class,
248 PROP_DIRECTION,
249 g_param_spec_flags ("direction",
250 "The direction of the stream",
251 "An enum to set and get the direction of the stream",
252 FS_TYPE_STREAM_DIRECTION,
253 FS_DIRECTION_NONE,
254 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
255
256 /**
257 * FsStream:participant:
258 *
259 * The #FsParticipant for this stream. This property is a construct param and
260 * is read-only construction.
261 *
262 */
263 g_object_class_install_property (gobject_class,
264 PROP_PARTICIPANT,
265 g_param_spec_object ("participant",
266 "The participant of the stream",
267 "An FsParticipant represented by the stream",
268 FS_TYPE_PARTICIPANT,
269 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
270
271 /**
272 * FsStream:session:
273 *
274 * The #FsSession for this stream. This property is a construct param and
275 * is read-only construction.
276 *
277 */
278 g_object_class_install_property (gobject_class,
279 PROP_SESSION,
280 g_param_spec_object ("session",
281 "The session of the stream",
282 "An FsSession represented by the stream",
283 FS_TYPE_SESSION,
284 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
285
286 /**
287 * FsStream::error:
288 * @self: #FsStream that emitted the signal
289 * @errorno: The number of the error
290 * @error_msg: Error message to be displayed to user
291 *
292 * This signal is emitted in any error condition
293 *
294 */
295 signals[ERROR_SIGNAL] = g_signal_new ("error",
296 G_TYPE_FROM_CLASS (klass),
297 G_SIGNAL_RUN_LAST,
298 0,
299 NULL,
300 NULL,
301 _fs_marshal_VOID__ENUM_STRING,
302 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
303
304 /**
305 * FsStream::src-pad-added:
306 * @self: #FsStream that emitted the signal
307 * @pad: #GstPad of the new source pad
308 * @codec: #FsCodec of the codec being received on the new source pad
309 *
310 * This signal is emitted when a new gst source pad has been created for a
311 * specific codec being received. There will be a different source pad for
312 * each codec that is received. The user must ref the #GstPad if he wants to
313 * keep it. The user should not modify the #FsCodec and must copy it if he
314 * wants to use it outside the callback scope.
315 *
316 * This signal is not emitted on the main thread, but on GStreamer's streaming
317 * thread!
318 *
319 */
320 signals[SRC_PAD_ADDED] = g_signal_new ("src-pad-added",
321 G_TYPE_FROM_CLASS (klass),
322 G_SIGNAL_RUN_LAST,
323 0,
324 NULL,
325 NULL,
326 _fs_marshal_VOID__BOXED_BOXED,
327 G_TYPE_NONE, 2, GST_TYPE_PAD, FS_TYPE_CODEC);
328
329 g_type_class_add_private (klass, sizeof (FsStreamPrivate));
330 }
331
332 static void
333 fs_stream_init (FsStream *self)
334 {
335 /* member init */
336 self->priv = FS_STREAM_GET_PRIVATE (self);
337 self->priv->mutex = g_mutex_new ();
338 }
339
340 static void
341 fs_stream_finalize (GObject *obj)
342 {
343 FsStream *stream = FS_STREAM (obj);
344
345 g_list_free (stream->priv->src_pads);
346 g_mutex_free (stream->priv->mutex);
347
348 G_OBJECT_CLASS (fs_stream_parent_class)->finalize (obj);
349 }
350
351 static void
352 fs_stream_get_property (GObject *object,
353 guint prop_id,
354 GValue *value,
355 GParamSpec *pspec)
356 {
357 GST_WARNING ("Subclass %s of FsStream does not override the %s property"
358 " getter",
359 G_OBJECT_TYPE_NAME(object),
360 g_param_spec_get_name (pspec));
361 }
362
363 static void
364 fs_stream_set_property (GObject *object,
365 guint prop_id,
366 const GValue *value,
367 GParamSpec *pspec)
368 {
369 GST_WARNING ("Subclass %s of FsStream does not override the %s property"
370 " setter",
371 G_OBJECT_TYPE_NAME(object),
372 g_param_spec_get_name (pspec));
373 }
374
375 /**
376 * fs_stream_add_remote_candidates:
377 * @stream: an #FsStream
378 * @candidates: (element-type FsCandidate): an #GList of #FsCandidate
379 * representing the remote candidates
380 * @error: location of a #GError, or %NULL if no error occured
381 *
382 * This function adds remote candidates. Any new candidates are
383 * added to the list. The candidates will be used to establish a connection
384 * with the peer. A copy will be made so the user must free the
385 * passed candidate using fs_candidate_destroy() when done.
386 *
387 * Return value: TRUE if the candidate was valid, FALSE otherwise
388 */
389 gboolean
390 fs_stream_add_remote_candidates (FsStream *stream,
391 GList *candidates,
392 GError **error)
393 {
394 FsStreamClass *klass;
395
396 g_return_val_if_fail (stream, FALSE);
397 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
398 klass = FS_STREAM_GET_CLASS (stream);
399
400 if (klass->add_remote_candidates) {
401 return klass->add_remote_candidates (stream, candidates, error);
402 } else {
403 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
404 "add_remote_candidate not defined in class");
405 }
406
407 return FALSE;
408 }
409
410 /**
411 * fs_stream_force_remote_candidates:
412 * @stream: a #FsStream
413 * @remote_candidates: (element-type FsCandidate):
414 * a #GList of #FsCandidate to force
415 * @error: location of a #GError, or %NULL if no error occured
416 *
417 * This function forces data to be sent immediately to the selected remote
418 * candidate, by-passing any connectivity checks. There should be at most
419 * one candidate per component.
420 *
421 * Returns: %TRUE if the candidates could be forced, %FALSE otherwise
422 */
423
424 gboolean
425 fs_stream_force_remote_candidates (FsStream *stream,
426 GList *remote_candidates,
427 GError **error)
428 {
429 FsStreamClass *klass;
430
431 g_return_val_if_fail (stream, FALSE);
432 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
433 klass = FS_STREAM_GET_CLASS (stream);
434
435 if (klass->force_remote_candidates) {
436 return klass->force_remote_candidates (stream,
437 remote_candidates,
438 error);
439 } else {
440 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
441 "force_remote_candidates not defined in class");
442 }
443
444 return FALSE;
445 }
446
447 /**
448 * fs_stream_set_remote_codecs:
449 * @stream: a #FsStream
450 * @remote_codecs: (element-type FsCodec): a #GList of #FsCodec representing
451 * the remote codecs
452 * @error: location of a #GError, or %NULL if no error occured
453 *
454 * This function will set the list of remote codecs for this stream. If
455 * the given remote codecs couldn't be negotiated with the list of local
456 * codecs or already negotiated codecs for the corresponding #FsSession, @error
457 * will be set and %FALSE will be returned. The @remote_codecs list will be
458 * copied so it must be free'd using fs_codec_list_destroy() when done.
459 *
460 * Returns: %FALSE if the remote codecs couldn't be set.
461 */
462 gboolean
463 fs_stream_set_remote_codecs (FsStream *stream,
464 GList *remote_codecs, GError **error)
465 {
466 FsStreamClass *klass;
467
468 g_return_val_if_fail (stream, FALSE);
469 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
470 klass = FS_STREAM_GET_CLASS (stream);
471
472 if (klass->set_remote_codecs) {
473 return klass->set_remote_codecs (stream, remote_codecs, error);
474 } else {
475 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
476 "set_remote_codecs not defined in class");
477 }
478
479 return FALSE;
480 }
481
482 /**
483 * fs_stream_add_id:
484 * @stream: a #FsStream
485 * @id: The id to add to the stream
486 *
487 * This function is used to add data identifiers that allow the
488 * plugin to recognize packets that are meant for id. For example, in RTP,
489 * one would set the SSRCs that are expected.
490 *
491 * Depending on the protocol, one may be able to add more than one ID
492 * to a stream (in RTP you can have multiple SSRCs in a stream).
493 * If a protocol supports only one id, adding a new one will overwrite it.
494 * If an ID was already set on a stream, adding it to another stream will
495 * override the previdous decision.
496 *
497 * For most protocols, calling this function is optional as the incoming data
498 * can be matched with a stream by its source IP address. This is mostly useful
499 * if one is using multicast or is behind a muxer server.
500 */
501 void
502 fs_stream_add_id (FsStream *stream,
503 guint id)
504 {
505 FsStreamClass *klass;
506
507 g_return_if_fail (stream);
508 g_return_if_fail (FS_IS_STREAM (stream));
509 klass = FS_STREAM_GET_CLASS (stream);
510
511 if (klass->add_id)
512 klass->add_id (stream, id);
513 }
514
515 /**
516 * fs_stream_emit_error:
517 * @stream: #FsStream on which to emit the error signal
518 * @error_no: The number of the error
519 * @error_msg: Error message to be displayed to user
520 *
521 * This function emits the #FsStream::error" signal, it should only be
522 * called by subclasses.
523 */
524 void
525 fs_stream_emit_error (FsStream *stream,
526 gint error_no,
527 const gchar *error_msg)
528 {
529 g_signal_emit (stream, signals[ERROR_SIGNAL], 0, error_no, error_msg);
530 }
531
532
533 static void
534 src_pad_parent_unset (GstObject *srcpad, GstObject *parent, gpointer user_data)
535 {
536 FsStream *stream = FS_STREAM (user_data);
537
538 FS_STREAM_LOCK (stream);
539 stream->priv->src_pads = g_list_remove (stream->priv->src_pads, srcpad);
540 stream->priv->src_pads_cookie++;
541 FS_STREAM_UNLOCK (stream);
542 }
543
544 /**
545 * fs_stream_emit_src_pad_added:
546 * @stream: #FsStream on which to emit the src-pad-added signal
547 * @pad: the #GstPad that this #FsStream has created
548 * @codec: The #FsCodec for this pad
549 *
550 * Emits the #FsStream::src-pad-added" signal, it should only be
551 * called by subclasses.
552 */
553
554 void
555 fs_stream_emit_src_pad_added (FsStream *stream,
556 GstPad *pad,
557 FsCodec *codec)
558 {
559 FS_STREAM_LOCK (stream);
560 g_assert (!g_list_find (stream->priv->src_pads, pad));
561 stream->priv->src_pads = g_list_append (stream->priv->src_pads, pad);
562 stream->priv->src_pads_cookie++;
563 g_signal_connect_object (pad, "parent-unset",
564 G_CALLBACK (src_pad_parent_unset), stream, 0);
565 FS_STREAM_UNLOCK (stream);
566
567 g_signal_emit (stream, signals[SRC_PAD_ADDED], 0, pad, codec);
568 }
569
570 static GstIteratorItem
571 src_pad_iterator_item_func (GstIterator*iter, gpointer item)
572 {
573 gst_object_ref (item);
574
575 return GST_ITERATOR_ITEM_PASS;
576 }
577
578 /**
579 * fs_stream_iterate_src_pads:
580 * @stream: a #FsStream
581 *
582 * Creates a #GstIterator that can be used to iterate the src pads of this
583 * stream. These are the pads that were announced by #FsStream:src-pad-added
584 * and are still valid.
585 *
586 * Returns: (transfer full): The #GstIterator
587 */
588
589 GstIterator *
590 fs_stream_iterate_src_pads (FsStream *stream)
591 {
592 return gst_iterator_new_list (GST_TYPE_PAD, stream->priv->mutex,
593 &stream->priv->src_pads_cookie, &stream->priv->src_pads,
594 g_object_ref (stream), src_pad_iterator_item_func, g_object_unref);
595 }
596
597
598 /**
599 * fs_stream_set_transmitter:
600 * @stream: a #FsStream
601 * @transmitter: Name of the type of transmitter to use for this stream
602 * @stream_transmitter_n_parameters: Number of parametrs passed to the stream
603 * transmitter
604 * @stream_transmitter_parameters:
605 * (array length=stream_transmitter_n_parameters) (allow-none):
606 * an array of n_parameters #GParameter struct that will be passed
607 * to the newly-create #FsStreamTransmitter
608 * @error: location of a #GError, or %NULL if no error occured
609 *
610 * Set the transmitter to use for this stream. This function will only succeed
611 * once.
612 *
613 * Returns: %TRUE if the transmitter could be set, %FALSE otherwise
614 */
615
616 gboolean
617 fs_stream_set_transmitter (FsStream *stream,
618 const gchar *transmitter,
619 GParameter *stream_transmitter_parameters,
620 guint stream_transmitter_n_parameters,
621 GError **error)
622 {
623 FsStreamClass *klass;
624
625 g_return_val_if_fail (stream, FALSE);
626 g_return_val_if_fail (FS_IS_STREAM (stream), FALSE);
627 klass = FS_STREAM_GET_CLASS (stream);
628
629 if (klass->set_transmitter)
630 return klass->set_transmitter (stream, transmitter,
631 stream_transmitter_parameters, stream_transmitter_n_parameters, error);
632
633
634 g_set_error (error, FS_ERROR, FS_ERROR_NOT_IMPLEMENTED,
635 "set_transmitter not defined in class");
636
637 return FALSE;
638 }
639
640 /**
641 * fs_stream_destroy:
642 * @stream: a #FsStream
643 *
644 * This will cause the stream to remove all links to other objects and to
645 * remove itself from the #FsSession. Once a #FsStream has been destroyed, it
646 * can not be used anymore.
647 *
648 * It is strongly recommended to call this function from the main thread because
649 * releasing the application's reference to a stream.
650 */
651
652 void
653 fs_stream_destroy (FsStream *stream)
654 {
655 g_return_if_fail (stream);
656 g_return_if_fail (FS_IS_STREAM (stream));
657
658 g_object_run_dispose (G_OBJECT (stream));
659 }
+0
-192
gst-libs/gst/farstream/fs-stream.h less more
0 /*
1 * Farstream - Farstream Stream
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-stream.h - A Farstream Stream (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_STREAM_H__
25 #define __FS_STREAM_H__
26
27 #include <glib.h>
28 #include <glib-object.h>
29
30 #include <gst/farstream/fs-candidate.h>
31 #include <gst/farstream/fs-codec.h>
32
33 G_BEGIN_DECLS
34
35 /**
36 * FsStreamDirection:
37 * @FS_DIRECTION_NONE: No direction specified
38 * @FS_DIRECTION_SEND: Send only
39 * @FS_DIRECTION_RECV: Receive only
40 * @FS_DIRECTION_BOTH: Send and receive
41 *
42 * An enum for specifying the direction of a stream
43 *
44 */
45 typedef enum _FsStreamDirection
46 {
47 FS_DIRECTION_NONE = 0,
48 FS_DIRECTION_SEND = 1<<0,
49 FS_DIRECTION_RECV = 1<<1,
50 FS_DIRECTION_BOTH = FS_DIRECTION_SEND | FS_DIRECTION_RECV
51 } FsStreamDirection;
52
53 /**
54 * FsStreamState:
55 * @FS_STREAM_STATE_FAILED: connectivity checks have been completed,
56 * but connectivity was not established
57 * @FS_STREAM_STATE_DISCONNECTED: no activity scheduled
58 * @FS_STREAM_STATE_GATHERING: gathering local candidates
59 * @FS_STREAM_STATE_CONNECTING: establishing connectivity
60 * @FS_STREAM_STATE_CONNECTED: at least one working candidate pair
61 * @FS_STREAM_STATE_READY: ICE concluded, candidate pair selection is now final
62 *
63 * These are the possible states of a stream, a simple multicast stream
64 * could only be in "disconnected" or "ready" state.
65 * An stream using an ICE transmitter would use all of these.
66 */
67
68 typedef enum _FsStreamState
69 {
70 FS_STREAM_STATE_FAILED,
71 FS_STREAM_STATE_DISCONNECTED,
72 FS_STREAM_STATE_GATHERING,
73 FS_STREAM_STATE_CONNECTING,
74 FS_STREAM_STATE_CONNECTED,
75 FS_STREAM_STATE_READY
76 } FsStreamState;
77
78 /* TYPE MACROS */
79 #define FS_TYPE_STREAM \
80 (fs_stream_get_type ())
81 #define FS_STREAM(obj) \
82 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_STREAM, FsStream))
83 #define FS_STREAM_CLASS(klass) \
84 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_STREAM, FsStreamClass))
85 #define FS_IS_STREAM(obj) \
86 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_STREAM))
87 #define FS_IS_STREAM_CLASS(klass) \
88 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_STREAM))
89 #define FS_STREAM_GET_CLASS(obj) \
90 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_STREAM, FsStreamClass))
91 #define FS_STREAM_CAST(obj) ((FsStream *) (obj))
92
93 typedef struct _FsStream FsStream;
94 typedef struct _FsStreamClass FsStreamClass;
95 typedef struct _FsStreamPrivate FsStreamPrivate;
96
97
98 /**
99 * FsStreamClass:
100 * @parent_class: Our parent
101 * @add_remote_candidates: Set sthe remote candidates
102 * @force_remote_candidates: Forces certain remote candidates
103 * @set_remote_codecs: Sets the list of remote codecs
104 * @add_id: Add a known id to be associated with this stream
105 * @set_transmitter: Set the transmitter to use for this stream
106 *
107 * You must override add_remote_candidate in a subclass.
108 * If you have to negotiate codecs, then you must override set_remote_codecs too
109 */
110
111 struct _FsStreamClass
112 {
113 GstObjectClass parent_class;
114
115 /*virtual functions */
116 gboolean (*add_remote_candidates) (FsStream *stream,
117 GList *candidates,
118 GError **error);
119
120 gboolean (*force_remote_candidates) (FsStream *stream,
121 GList *remote_candidates,
122 GError **error);
123
124 gboolean (*set_remote_codecs) (FsStream *stream,
125 GList *remote_codecs, GError **error);
126
127 void (*add_id) (FsStream *stream,
128 guint id);
129
130 gboolean (*set_transmitter) (FsStream *stream,
131 const gchar *transmitter,
132 GParameter *stream_transmitter_parameters,
133 guint stream_transmitter_n_parameters,
134 GError **error);
135
136 /*< private >*/
137 gpointer _padding[8];
138 };
139
140 /**
141 * FsStream:
142 *
143 * All members are private, access them using methods and properties
144 */
145 struct _FsStream
146 {
147 GstObject parent;
148
149 /*< private >*/
150
151 FsStreamPrivate *priv;
152
153 gpointer _padding[8];
154 };
155
156 GType fs_stream_get_type (void);
157
158 gboolean fs_stream_add_remote_candidates (FsStream *stream,
159 GList *candidates,
160 GError **error);
161
162 gboolean fs_stream_force_remote_candidates (FsStream *stream,
163 GList *remote_candidates,
164 GError **error);
165
166 gboolean fs_stream_set_remote_codecs (FsStream *stream,
167 GList *remote_codecs, GError **error);
168
169 void fs_stream_add_id (FsStream *stream, guint id);
170
171 void fs_stream_emit_error (FsStream *stream,
172 gint error_no,
173 const gchar *error_msg);
174
175 void fs_stream_emit_src_pad_added (FsStream *stream,
176 GstPad *pad,
177 FsCodec *codec);
178
179 GstIterator *fs_stream_iterate_src_pads (FsStream *stream);
180
181 gboolean fs_stream_set_transmitter (FsStream *stream,
182 const gchar *transmitter,
183 GParameter *stream_transmitter_parameters,
184 guint stream_transmitter_n_parameters,
185 GError **error);
186
187 void fs_stream_destroy (FsStream *stream);
188
189 G_END_DECLS
190
191 #endif /* __FS_STREAM_H__ */
+0
-408
gst-libs/gst/farstream/fs-transmitter.c less more
0 /*
1 * Farstream - Farstream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-transmitter.c - A Farstream Transmitter gobject (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * SECTION:fs-transmitter
26 * @short_description: A transmitter object linked to a session
27 *
28 * This object is the base implementation of a Farstream Transmitter.
29 * It needs to be derived and implement by a Farstream transmitter. A
30 * Farstream Transmitter provides a GStreamer network sink and source to be used
31 * for the Farstream Session. It creates #FsStreamTransmitter objects which are
32 * used to set the different per-stream properties
33 *
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "fs-transmitter.h"
41
42 #include <gst/gst.h>
43
44 #include "fs-marshal.h"
45 #include "fs-plugin.h"
46 #include "fs-conference.h"
47 #include "fs-private.h"
48
49 /* Signals */
50 enum
51 {
52 ERROR_SIGNAL,
53 GET_RECVONLY_FILTER_SIGNAL,
54 LAST_SIGNAL
55 };
56
57 /* props */
58 enum
59 {
60 PROP_0,
61 PROP_GST_SINK,
62 PROP_GST_SRC,
63 PROP_COMPONENTS,
64 PROP_TYPE_OF_SERVICE
65 };
66
67 /*
68 struct _FsTransmitterPrivate
69 {
70 };
71 */
72
73 G_DEFINE_ABSTRACT_TYPE(FsTransmitter, fs_transmitter, GST_TYPE_OBJECT);
74
75 #define FS_TRANSMITTER_GET_PRIVATE(o) \
76 (G_TYPE_INSTANCE_GET_PRIVATE ((o), FS_TYPE_TRANSMITTER, FsTransmitterPrivate))
77
78 static void fs_transmitter_get_property (GObject *object,
79 guint prop_id,
80 GValue *value,
81 GParamSpec *pspec);
82 static void fs_transmitter_set_property (GObject *object,
83 guint prop_id,
84 const GValue *value,
85 GParamSpec *pspec);
86
87 static guint signals[LAST_SIGNAL] = { 0 };
88
89
90 static void
91 fs_transmitter_class_init (FsTransmitterClass *klass)
92 {
93 GObjectClass *gobject_class;
94
95 _fs_conference_init_debug ();
96
97 gobject_class = (GObjectClass *) klass;
98
99 gobject_class->set_property = fs_transmitter_set_property;
100 gobject_class->get_property = fs_transmitter_get_property;
101
102
103
104 /**
105 * FsTransmitter:gst-src:
106 *
107 * A network source #GstElement to be used by the #FsSession
108 * This element MUST provide a source pad named "src%d" per component.
109 * These pads number must start at 1 (the %d corresponds to the component
110 * number).
111 * These pads MUST be static pads.
112 *
113 */
114 g_object_class_install_property (gobject_class,
115 PROP_GST_SRC,
116 g_param_spec_object ("gst-src",
117 "The network source",
118 "A source GstElement to be used by a FsSession",
119 GST_TYPE_ELEMENT,
120 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
121
122 /**
123 * FsTransmitter:gst-sink:
124 *
125 * A network source #GstElement to be used by the #FsSession
126 * These element's sink must have async=FALSE
127 * This element MUST provide a pad named "sink\%d" per component.
128 * These pads number must start at 1 (the \%d corresponds to the component
129 * number).
130 * These pads MUST be static pads.
131 *
132 */
133 g_object_class_install_property (gobject_class,
134 PROP_GST_SINK,
135 g_param_spec_object ("gst-sink",
136 "The network source",
137 "A source GstElement to be used by a FsSession",
138 GST_TYPE_ELEMENT,
139 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
140
141 /**
142 * FsTransmitter:components:
143 *
144 * The number of components to create
145 */
146 g_object_class_install_property (gobject_class,
147 PROP_COMPONENTS,
148 g_param_spec_uint ("components",
149 "Number of componnets",
150 "The number of components to create",
151 1, 255, 1,
152 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153
154 /**
155 * FsTransmitter:tos:
156 *
157 * Sets the IP ToS field (and if possible the IPv6 TCLASS field
158 */
159 g_object_class_install_property (gobject_class,
160 PROP_TYPE_OF_SERVICE,
161 g_param_spec_uint ("tos",
162 "IP Type of Service",
163 "The IP Type of Service to set on sent packets",
164 0, 255, 0,
165 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
166
167 /**
168 * FsTransmitter::error:
169 * @self: #FsTransmitter that emitted the signal
170 * @errorno: The number of the error
171 * @error_msg: Error message to be displayed to user
172 *
173 * This signal is emitted in any error condition
174 *
175 */
176 signals[ERROR_SIGNAL] = g_signal_new ("error",
177 G_TYPE_FROM_CLASS (klass),
178 G_SIGNAL_RUN_LAST,
179 0,
180 NULL,
181 NULL,
182 _fs_marshal_VOID__ENUM_STRING,
183 G_TYPE_NONE, 2, FS_TYPE_ERROR, G_TYPE_STRING);
184
185 /**
186 * FsTransmitter::get-recvonly-filter
187 * @self: #FsTransmitter that emitted the signal
188 * @component: The component that the filter will be used for
189 *
190 * This signal is emitted when the transmitter wants to get a filter for
191 * to use if sending is disabled. If you want to drop all buffers, just
192 * don't listen to the signal.
193 *
194 * This element should have a "sending" property that can be changed with the
195 * sending state of the stream. It should default to %TRUE.
196 *
197 * Returns: (transfer full) (allow-none): the #GstElement to use as the
198 * filter, or %NULL to drop everything
199 */
200
201 signals[GET_RECVONLY_FILTER_SIGNAL] = g_signal_new ("get-recvonly-filter",
202 G_TYPE_FROM_CLASS (klass),
203 G_SIGNAL_RUN_LAST,
204 0,
205 NULL,
206 NULL,
207 _fs_marshal_OBJECT__UINT,
208 GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
209
210
211 //g_type_class_add_private (klass, sizeof (FsTransmitterPrivate));
212 }
213
214 static void
215 fs_transmitter_init (FsTransmitter *self)
216 {
217 // self->priv = FS_TRANSMITTER_GET_PRIVATE (self);
218 }
219
220 static void
221 fs_transmitter_get_property (GObject *object,
222 guint prop_id,
223 GValue *value,
224 GParamSpec *pspec)
225 {
226 GST_WARNING ("Subclass %s of FsTransmitter does not override the %s property"
227 " getter",
228 G_OBJECT_TYPE_NAME(object),
229 g_param_spec_get_name (pspec));
230 }
231
232 static void
233 fs_transmitter_set_property (GObject *object,
234 guint prop_id,
235 const GValue *value,
236 GParamSpec *pspec)
237 {
238 GST_WARNING ("Subclass %s of FsTransmitter does not override the %s property"
239 " setter",
240 G_OBJECT_TYPE_NAME(object),
241 g_param_spec_get_name (pspec));
242 }
243
244
245 /**
246 * fs_transmitter_new_stream_transmitter:
247 * @transmitter: a #FsTranmitter
248 * @participant: the #FsParticipant for which the #FsStream using this
249 * new #FsStreamTransmitter is created
250 * @n_parameters: The number of parameters to pass to the newly created
251 * #FsStreamTransmitter
252 * @parameters: an array of #GParameter
253 * @error: location of a #GError, or NULL if no error occured
254 *
255 * This function will create a new #FsStreamTransmitter element for a
256 * specific participant for this #FsTransmitter
257 *
258 * Returns: (transfer full): a new #FsStreamTransmitter, or NULL if there is an
259 * error
260 */
261
262 FsStreamTransmitter *
263 fs_transmitter_new_stream_transmitter (FsTransmitter *transmitter,
264 FsParticipant *participant,
265 guint n_parameters,
266 GParameter *parameters,
267 GError **error)
268 {
269 FsTransmitterClass *klass;
270
271 g_return_val_if_fail (transmitter, NULL);
272 g_return_val_if_fail (FS_IS_TRANSMITTER (transmitter), NULL);
273 klass = FS_TRANSMITTER_GET_CLASS (transmitter);
274 g_return_val_if_fail (klass->new_stream_transmitter, NULL);
275
276
277 return klass->new_stream_transmitter (transmitter, participant,
278 n_parameters, parameters, error);
279
280 return NULL;
281 }
282
283 /**
284 * fs_transmitter_new:
285 * @type: The type of transmitter to create
286 * @components: The number of components to create
287 * @tos: The Type of Service of the socket, max is 255
288 * @error: location of a #GError, or NULL if no error occured
289 *
290 * This function creates a new transmitter of the requested type.
291 * It will load the appropriate plugin as required.
292 *
293 * Returns: a newly-created #FsTransmitter of the requested type
294 * (or NULL if there is an error)
295 */
296
297 FsTransmitter *
298 fs_transmitter_new (const gchar *type,
299 guint components,
300 guint tos,
301 GError **error)
302 {
303 FsTransmitter *self = NULL;
304
305 g_return_val_if_fail (type != NULL, NULL);
306 g_return_val_if_fail (tos <= 255, NULL);
307
308 self = FS_TRANSMITTER (fs_plugin_create (type, "transmitter", error,
309 "components", components,
310 "tos", tos,
311 NULL));
312
313 if (!self)
314 return NULL;
315
316 if (self->construction_error) {
317 g_propagate_error(error, self->construction_error);
318 g_object_unref (self);
319 self = NULL;
320 }
321
322 return self;
323 }
324
325 /**
326 * fs_transmitter_get_stream_transmitter_type:
327 * @transmitter: A #FsTransmitter object
328 *
329 * This function returns the GObject type for the stream transmitter.
330 * This is meant for bindings that need to introspect the type of arguments
331 * that can be passed to the _new_stream_transmitter.
332 *
333 * Returns: the #GType
334 */
335
336 GType
337 fs_transmitter_get_stream_transmitter_type (FsTransmitter *transmitter)
338 {
339 FsTransmitterClass *klass;
340
341 g_return_val_if_fail (transmitter, 0);
342 g_return_val_if_fail (FS_IS_TRANSMITTER (transmitter), 0);
343 klass = FS_TRANSMITTER_GET_CLASS (transmitter);
344 g_return_val_if_fail (klass->get_stream_transmitter_type, 0);
345
346 return klass->get_stream_transmitter_type (transmitter);
347 }
348
349
350 /**
351 * fs_transmitter_emit_error:
352 * @transmitter: #FsTransmitter on which to emit the error signal
353 * @error_no: The number of the error
354 * @error_msg: Error message to be displayed to user
355 *
356 * This function emit the "error" signal on a #FsTransmitter, it should
357 * only be called by subclasses.
358 */
359 void
360 fs_transmitter_emit_error (FsTransmitter *transmitter,
361 gint error_no,
362 const gchar *error_msg)
363 {
364 g_signal_emit (transmitter, signals[ERROR_SIGNAL], 0, error_no,
365 error_msg);
366 }
367
368 /**
369 * fs_transmitter_list_available:
370 *
371 * Get the list of all available transmitters
372 *
373 * Returns: (transfer full): a newly allocated array of strings containing the
374 * list of all available transmitters or %NULL if there are none. It should
375 * be freed with g_strfreev().
376 */
377
378 char **
379 fs_transmitter_list_available (void)
380 {
381 return fs_plugin_list_available ("transmitter");
382 }
383
384 /**
385 * fs_transmitter_get_recvonly_filter:
386 * @transmitter: A #FsTransmitter object
387 * @component: The component to get the filter for
388 *
389 * Get the filter to add on the send pipeline if sending is disabled.
390 *
391 * Only for use by subclasses.
392 *
393 * Returns: (transfer full) (allow-none): a #GstElement to use as the filter or
394 * %NULL
395 */
396
397 GstElement *
398 fs_transmitter_get_recvonly_filter (FsTransmitter *transmitter,
399 guint component)
400 {
401 GstElement *element = NULL;
402
403 g_signal_emit (transmitter, signals[GET_RECVONLY_FILTER_SIGNAL], 0, component,
404 &element);
405
406 return element;
407 }
+0
-126
gst-libs/gst/farstream/fs-transmitter.h less more
0 /*
1 * Farstream - Farstream Transmitter
2 *
3 * Copyright 2007 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2007 Nokia Corp.
6 *
7 * fs-transmitter.h - A Farstream Transmitter (base implementation)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef __FS_TRANSMITTER_H__
25 #define __FS_TRANSMITTER_H__
26
27 #include <gst/gst.h>
28
29 #include <gst/farstream/fs-participant.h>
30 #include <gst/farstream/fs-session.h>
31 #include <gst/farstream/fs-stream-transmitter.h>
32
33 G_BEGIN_DECLS
34
35 /* TYPE MACROS */
36 #define FS_TYPE_TRANSMITTER \
37 (fs_transmitter_get_type ())
38 #define FS_TRANSMITTER(obj) \
39 (G_TYPE_CHECK_INSTANCE_CAST((obj), FS_TYPE_TRANSMITTER, FsTransmitter))
40 #define FS_TRANSMITTER_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_CAST((klass), FS_TYPE_TRANSMITTER, FsTransmitterClass))
42 #define FS_IS_TRANSMITTER(obj) \
43 (G_TYPE_CHECK_INSTANCE_TYPE((obj), FS_TYPE_TRANSMITTER))
44 #define FS_IS_TRANSMITTER_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_TYPE((klass), FS_TYPE_TRANSMITTER))
46 #define FS_TRANSMITTER_GET_CLASS(obj) \
47 (G_TYPE_INSTANCE_GET_CLASS ((obj), FS_TYPE_TRANSMITTER, FsTransmitterClass))
48 #define FS_TRANSMITTER_CAST(obj) ((FsTransmitter *) (obj))
49
50 typedef struct _FsTransmitter FsTransmitter;
51 typedef struct _FsTransmitterClass FsTransmitterClass;
52 typedef struct _FsTransmitterPrivate FsTransmitterPrivate;
53
54 /**
55 * FsTransmitterClass:
56 * @parent_class: Our parent
57 * @new_stream_transmitter: Creates a new #FsStreamTransmitter
58 * @get_stream_transmitter_type: Returns the #GType of the stream transmitter
59 * created by this class (useful for bindings)
60 *
61 * You must override both methods in a subclass.
62 */
63
64 struct _FsTransmitterClass
65 {
66 GstObjectClass parent_class;
67
68 /*virtual functions */
69 FsStreamTransmitter *(*new_stream_transmitter) (FsTransmitter *transmitter,
70 FsParticipant *participant,
71 guint n_parameters,
72 GParameter *parameters,
73 GError **error);
74 GType (*get_stream_transmitter_type) (FsTransmitter *transmitter);
75
76 /*< private >*/
77 gpointer _padding[8];
78 };
79
80 /**
81 * FsTransmitter:
82 *
83 * All members are private, access them using methods and properties
84 */
85 struct _FsTransmitter
86 {
87 GstObject parent;
88
89 /*< private >*/
90 FsTransmitterPrivate *priv;
91
92 /* This parameter should only be set by the construction methods
93 * of the subclasses
94 */
95 GError *construction_error;
96
97 gpointer _padding[8];
98 };
99
100 GType fs_transmitter_get_type (void);
101
102 FsStreamTransmitter *fs_transmitter_new_stream_transmitter (
103 FsTransmitter *transmitter, FsParticipant *participant,
104 guint n_parameters, GParameter *parameters, GError **error);
105
106 FsTransmitter *fs_transmitter_new (const gchar *type,
107 guint components,
108 guint tos,
109 GError **error);
110
111 GType fs_transmitter_get_stream_transmitter_type (FsTransmitter *transmitter);
112
113 void fs_transmitter_emit_error (FsTransmitter *transmitter,
114 gint error_no,
115 const gchar *error_msg);
116
117 char **fs_transmitter_list_available (void);
118
119 GstElement *
120 fs_transmitter_get_recvonly_filter (FsTransmitter *transmitter,
121 guint component);
122
123 G_END_DECLS
124
125 #endif /* __FS_TRANSMITTER_H__ */
+0
-271
gst-libs/gst/farstream/fs-utils.c less more
0 /*
1 * Farstream - Miscellaneous useful functions
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include "fs-utils.h"
27
28 #include <string.h>
29
30 #include "fs-rtp.h"
31
32 /**
33 * SECTION:fs-utils
34 * @short_description: Miscellaneous useful functions
35 */
36
37 static GList *
38 load_default_codec_preferences_from_path (const gchar *element_name,
39 const gchar *path)
40 {
41 GList *codec_prefs = NULL;
42 gchar *filename;
43
44 filename = g_build_filename (path, PACKAGE, FS_MAJORMINOR, element_name,
45 "default-codec-preferences", NULL);
46 codec_prefs = fs_codec_list_from_keyfile (filename, NULL);
47 g_free (filename);
48
49 return codec_prefs;
50 }
51
52 static const gchar *
53 factory_name_from_element (GstElement *element)
54 {
55 GstElementFactory *factory = gst_element_get_factory (element);
56
57 if (factory)
58 return gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
59 else
60 return NULL;
61 }
62
63 /**
64 * fs_utils_get_default_codec_preferences:
65 * @element: Element for which to fetch default codec preferences
66 *
67 * These default codec preferences should work with the elements that are
68 * available in the main GStreamer element repositories.
69 * They should be suitable for standards based protocols like SIP or XMPP.
70 *
71 * Returns: (element-type FsCodec) (transfer full):
72 * The default codec preferences for this plugin.
73 * This #GList should be freed with fs_codec_list_destroy()
74 */
75 GList *
76 fs_utils_get_default_codec_preferences (GstElement *element)
77 {
78 const gchar * const * system_data_dirs = g_get_system_data_dirs ();
79 GList *codec_prefs = NULL;
80 guint i;
81 const gchar *factory_name = factory_name_from_element (element);
82
83 if (!factory_name)
84 return NULL;
85
86 codec_prefs = load_default_codec_preferences_from_path (factory_name,
87 g_get_user_data_dir ());
88 if (codec_prefs)
89 return codec_prefs;
90
91 for (i = 0; system_data_dirs[i]; i++)
92 {
93 codec_prefs = load_default_codec_preferences_from_path (factory_name,
94 system_data_dirs[i]);
95 if (codec_prefs)
96 return codec_prefs;
97 }
98
99 return NULL;
100 }
101
102 /**
103 * fs_utils_get_default_element_properties: (skip):
104 * @element: Element for which to fetch default element properties
105 *
106 * This function produces a #GKeyFile that can be fed to
107 * fs_element_added_notifier_set_properties_from_keyfile(). If no
108 * default properties have been found, it will return %NULL.
109 *
110 * Returns: a #GKeyFile containing the default element
111 * properties for this element or %NULL if no properties were found.
112 * Caller must free the #GKeyFile when he is done.
113 */
114
115 GKeyFile *
116 fs_utils_get_default_element_properties (GstElement *element)
117 {
118 gboolean file_loaded;
119 GKeyFile *keyfile = g_key_file_new ();
120 gchar *filename;
121 const gchar *factory_name = factory_name_from_element (element);
122
123 filename = g_build_filename (PACKAGE, FS_MAJORMINOR, factory_name,
124 "default-element-properties", NULL);
125 file_loaded = g_key_file_load_from_data_dirs (keyfile, filename, NULL,
126 G_KEY_FILE_NONE, NULL);
127 g_free (filename);
128
129 if (file_loaded)
130 {
131 return keyfile;
132 }
133 else
134 {
135 g_key_file_free (keyfile);
136 return NULL;
137 }
138 }
139
140 /**
141 * fs_utils_set_bitrate:
142 * @element: The #GstElement
143 * @bitrate: The bitrate in bits/sec
144 *
145 * This allows setting the bitrate on all elements that have a "bitrate"
146 * property without having to know the type or of the unit used by that element.
147 *
148 * This will be obsolete in 0.11 (when all elements use bit/sec for the
149 * "bitrate" property.
150 */
151
152 void
153 fs_utils_set_bitrate (GstElement *element, glong bitrate)
154 {
155 GParamSpec *spec;
156 const char *elements_in_kbps[] = { "lamemp3enc", "lame", "x264enc", "twolame",
157 "mpeg2enc", NULL
158 };
159 int i;
160 GstElementFactory *factory;
161 const gchar *factory_name = NULL;
162
163 g_return_if_fail (GST_IS_ELEMENT (element));
164
165 spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "bitrate");
166 g_return_if_fail (spec != NULL);
167
168 factory = gst_element_get_factory (element);
169 if (factory)
170 factory_name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
171
172 /* divide by 1000 for elements that are known to use kbs */
173 for (i = 0; elements_in_kbps[i]; i++)
174 if (factory_name && !strcmp (factory_name, elements_in_kbps[i]))
175 {
176 bitrate /= 1000;
177 break;
178 }
179
180 if (G_PARAM_SPEC_TYPE (spec) == G_TYPE_LONG)
181 {
182 g_object_set (element, "bitrate", (glong) CLAMP (bitrate,
183 G_PARAM_SPEC_LONG (spec)->minimum,
184 G_PARAM_SPEC_LONG (spec)->maximum), NULL);
185 }
186 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_ULONG)
187 {
188 g_object_set (element, "bitrate", (gulong) CLAMP (bitrate,
189 G_PARAM_SPEC_ULONG (spec)->minimum,
190 G_PARAM_SPEC_ULONG (spec)->maximum), NULL);
191 }
192 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_INT)
193 {
194 gint tmp = MIN (bitrate, G_MAXINT);
195
196 g_object_set (element, "bitrate", (gint) CLAMP (tmp,
197 G_PARAM_SPEC_INT (spec)->minimum,
198 G_PARAM_SPEC_INT (spec)->maximum), NULL);
199 }
200 else if (G_PARAM_SPEC_VALUE_TYPE (spec) == G_TYPE_UINT)
201 {
202 guint tmp = MIN (bitrate, G_MAXUINT);
203
204 g_object_set (element, "bitrate", (guint) CLAMP (tmp,
205 G_PARAM_SPEC_UINT (spec)->minimum,
206 G_PARAM_SPEC_UINT (spec)->maximum), NULL);
207 }
208 else
209 {
210 g_warning ("bitrate parameter of unknown type");
211 }
212 }
213
214 static GList *
215 load_default_rtp_hdrext_preferences_from_path (const gchar *element_name,
216 const gchar *path, FsMediaType media_type)
217 {
218 GList *rtp_hdrext_prefs = NULL;
219 gchar *filename;
220
221 filename = g_build_filename (path, PACKAGE, FS_MAJORMINOR, element_name,
222 "default-codec-preferences", NULL);
223 rtp_hdrext_prefs = fs_rtp_header_extension_list_from_keyfile (filename,
224 media_type, NULL);
225 g_free (filename);
226
227 return rtp_hdrext_prefs;
228 }
229
230 /**
231 * fs_utils_get_default_rtp_header_extension_preferences
232 * @element: Element for which to fetch default RTP Header Extension preferences
233 * @media_type: The #FsMediaType for which to get default RTP Header Extension
234 * preferences
235 *
236 * These default rtp header extension preferences should work with the elements
237 * that are available in the main GStreamer element repositories.
238 * They should be suitable for standards based protocols like SIP or XMPP.
239 *
240 * Returns: (element-type FsCodec) (transfer full): The default rtp
241 * header extension preferences for this plugin, this #GList should be
242 * freed with fs_codec_list_destroy()
243 */
244 GList *
245 fs_utils_get_default_rtp_header_extension_preferences (GstElement *element,
246 FsMediaType media_type)
247 {
248 const gchar * const * system_data_dirs = g_get_system_data_dirs ();
249 GList *rtp_hdrext_prefs = NULL;
250 guint i;
251 const gchar *factory_name = factory_name_from_element (element);
252
253 if (!factory_name)
254 return NULL;
255
256 rtp_hdrext_prefs = load_default_rtp_hdrext_preferences_from_path (
257 factory_name, g_get_user_data_dir (), media_type);
258 if (rtp_hdrext_prefs)
259 return rtp_hdrext_prefs;
260
261 for (i = 0; system_data_dirs[i]; i++)
262 {
263 rtp_hdrext_prefs = load_default_rtp_hdrext_preferences_from_path (
264 factory_name, system_data_dirs[i], media_type);
265 if (rtp_hdrext_prefs)
266 return rtp_hdrext_prefs;
267 }
268
269 return NULL;
270 }
+0
-45
gst-libs/gst/farstream/fs-utils.h less more
0 /*
1 * Farstream - Miscellaneous useful functions
2 *
3 * Copyright 2011 Collabora Ltd.
4 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
5 * Copyright 2011 Nokia Corp.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23
24 #ifndef __FS_UTILS_H__
25 #define __FS_UTILS_H__
26
27 #include <gst/gst.h>
28
29 #include <gst/farstream/fs-codec.h>
30
31 G_BEGIN_DECLS
32
33 GList *fs_utils_get_default_codec_preferences (GstElement *element);
34
35 GKeyFile *fs_utils_get_default_element_properties (GstElement *element);
36
37 void fs_utils_set_bitrate (GstElement *element, glong bitrate);
38
39 GList *fs_utils_get_default_rtp_header_extension_preferences (
40 GstElement *element, FsMediaType media_type);
41
42 G_END_DECLS
43
44 #endif /* __FS_UTILS_H__ */
2323
2424 farstream_la_LIBADD = \
2525 $(PYFARSTREAM_LIBS) \
26 $(top_builddir)/gst-libs/gst/farstream/libfarstream-@GST_MAJORMINOR@.la
26 $(top_builddir)/farstream/libfarstream-@GST_MAJORMINOR@.la
2727
2828 farstream_la_LDFLAGS = -module -avoid-version
2929
44
55 #include <gst/gst.h>
66
7 #include <gst/farstream/fs-conference.h>
8
9 #include <gst/farstream/fs-element-added-notifier.h>
7 #include <farstream/fs-conference.h>
8
9 #include <farstream/fs-element-added-notifier.h>
1010
1111 /* This is new in python 2.5 */
1212 #if PYTHON_API_VERSION < 1013
00 #include <pygobject.h>
1 #include <gst/farstream/fs-codec.h>
1 #include <farstream/fs-codec.h>
22
33 void fs_register_classes (PyObject *d);
44 void fs_add_constants(PyObject *module, const gchar *strip_prefix);
1010 fs-element-added-notifier.h \
1111 fs-enumtypes.h"
1212
13 srcdir=../gst-libs/gst/farstream/
13 srcdir=../farstream/
1414
1515 output=pyfarstream.defs
1616 filter=pyfarstream-filter.defs
1212 GST_PLUGIN_LOADING_WHITELIST=gstreamer:gst-plugins-base:gst-plugins-good:libnice:valve:siren:autoconvert:rtpmux:dtmf:mimic:shm:farstream@$(top_builddir)/gst \
1313 GST_PLUGIN_PATH=$(top_builddir)/gst:${GST_PLUGIN_PATH} \
1414 FS_PLUGIN_PATH=$(top_builddir)/transmitters/rawudp/.libs:$(top_builddir)/transmitters/multicast/.libs:$(top_builddir)/transmitters/nice/.libs:$(top_builddir)/transmitters/shm/.libs \
15 LD_LIBRARY_PATH=$(top_builddir)/gst-libs/gst/farstream/.libs:${LD_LIBRARY_PATH} \
15 LD_LIBRARY_PATH=$(top_builddir)/farstream/.libs:${LD_LIBRARY_PATH} \
1616 UPNP_XML_PATH=$(srcdir)/upnp \
1717 SRCDIR=$(srcdir) \
1818 XDG_CACHE_HOME=$(builddir)/cache
6666 $(GST_CFLAGS)
6767
6868 LDADD = \
69 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
69 $(top_builddir)/farstream/libfarstream-0.10.la \
7070 $(GST_CHECK_LIBS) \
7171 $(GST_LIBS)
7272
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include "gst/farstream/fs-codec.h"
26 #include "gst/farstream/fs-rtp.h"
25 #include "farstream/fs-codec.h"
26 #include "farstream/fs-rtp.h"
2727
2828 #include "testutils.h"
2929
2323 #endif
2424
2525 #include <gst/check/gstcheck.h>
26 #include <gst/farstream/fs-transmitter.h>
27 #include <gst/farstream/fs-conference.h>
26 #include <farstream/fs-transmitter.h>
27 #include <farstream/fs-conference.h>
2828
2929
3030 GST_START_TEST (test_fstransmitter_new_fail)
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-conference.h>
25 #include <farstream/fs-conference.h>
2626
2727 #include "check-threadsafe.h"
2828
2323 #endif
2424
2525 #include <gst/check/gstcheck.h>
26 #include <gst/farstream/fs-conference.h>
27 #include <gst/farstream/fs-stream-transmitter.h>
26 #include <farstream/fs-conference.h>
27 #include <farstream/fs-stream-transmitter.h>
2828
2929 #include "check-threadsafe.h"
3030
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-conference.h>
26 #include <gst/farstream/fs-rtp.h>
25 #include <farstream/fs-conference.h>
26 #include <farstream/fs-rtp.h>
2727
2828 #include "generic.h"
2929
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-conference.h>
26 #include <gst/farstream/fs-stream-transmitter.h>
25 #include <farstream/fs-conference.h>
26 #include <farstream/fs-stream-transmitter.h>
2727
2828 #include "check-threadsafe.h"
2929
2525 #include "generic.h"
2626
2727 #include <gst/check/gstcheck.h>
28 #include <gst/farstream/fs-conference.h>
28 #include <farstream/fs-conference.h>
2929
3030
3131 static GstBusSyncReply
2222 #define __GENERIC_H__
2323
2424 #include <gst/gst.h>
25 #include <gst/farstream/fs-conference.h>
25 #include <farstream/fs-conference.h>
2626
2727 struct SimpleTestConference {
2828 gint id;
2424 #include <gst/check/gstcheck.h>
2525 #include <gst/rtp/gstrtpbuffer.h>
2626
27 #include <gst/farstream/fs-conference.h>
28 #include <gst/farstream/fs-element-added-notifier.h>
27 #include <farstream/fs-conference.h>
28 #include <farstream/fs-element-added-notifier.h>
2929
3030 #include "check-threadsafe.h"
3131
2424 #include <gst/check/gstcheck.h>
2525 #include <gst/rtp/gstrtpbuffer.h>
2626
27 #include <gst/farstream/fs-conference.h>
27 #include <farstream/fs-conference.h>
2828
2929 #include "check-threadsafe.h"
3030 #include "generic.h"
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-transmitter.h>
26 #include <gst/farstream/fs-stream-transmitter.h>
25 #include <farstream/fs-transmitter.h>
26 #include <farstream/fs-stream-transmitter.h>
2727
2828 #include <sys/types.h>
2929 #include <sys/wait.h>
1919
2020
2121 #include <gst/gst.h>
22 #include <gst/farstream/fs-transmitter.h>
22 #include <farstream/fs-transmitter.h>
2323
2424 #ifndef __GENERIC_H__
2525 #define __GENERIC_H__
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-transmitter.h>
26 #include <gst/farstream/fs-conference.h>
25 #include <farstream/fs-transmitter.h>
26 #include <farstream/fs-conference.h>
2727
2828 #include "check-threadsafe.h"
2929 #include "generic.h"
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-transmitter.h>
26 #include <gst/farstream/fs-conference.h>
25 #include <farstream/fs-transmitter.h>
26 #include <farstream/fs-conference.h>
2727
2828 #include <unistd.h>
2929
2222 #endif
2323
2424 #include <gst/check/gstcheck.h>
25 #include <gst/farstream/fs-transmitter.h>
26 #include <gst/farstream/fs-conference.h>
25 #include <farstream/fs-transmitter.h>
26 #include <farstream/fs-conference.h>
2727
2828 #include <arpa/inet.h>
2929 #include <netdb.h>
2323 #endif
2424
2525 #include <gst/check/gstcheck.h>
26 #include <gst/farstream/fs-transmitter.h>
27 #include <gst/farstream/fs-conference.h>
26 #include <farstream/fs-transmitter.h>
27 #include <farstream/fs-conference.h>
2828
2929 #include <arpa/inet.h>
3030 #include <netdb.h>
2323 #endif
2424
2525 #include <gst/check/gstcheck.h>
26 #include <gst/farstream/fs-element-added-notifier.h>
26 #include <farstream/fs-element-added-notifier.h>
2727
2828 #include "testutils.h"
2929
1111 $(CFLAGS)
1212
1313 LDADD = \
14 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
14 $(top_builddir)/farstream/libfarstream-0.10.la \
1515 $(top_builddir)/gst/fsrtpconference/libfsrtpconference-convenience.la \
1616 $(GST_CHECK_LIBS) \
1717 $(GST_PLUGINS_BASE_LIBS) \
1919
2020 #include <gst/gst.h>
2121
22 #include <gst/farstream/fs-codec.h>
22 #include <farstream/fs-codec.h>
2323
2424 #include "fs-rtp-discover-codecs.h"
2525 #include "fs-rtp-conference.h"
1515 $(GST_CFLAGS)
1616 libmulticast_transmitter_la_LDFLAGS = $(FS_PLUGIN_LDFLAGS)
1717 libmulticast_transmitter_la_LIBADD = \
18 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
18 $(top_builddir)/farstream/libfarstream-0.10.la \
1919 $(FS_LIBS) \
2020 $(GST_BASE_LIBS) \
2121 $(GST_LIBS)
5959 #include "fs-multicast-stream-transmitter.h"
6060 #include "fs-multicast-transmitter.h"
6161
62 #include <gst/farstream/fs-candidate.h>
63 #include <gst/farstream/fs-conference.h>
62 #include <farstream/fs-candidate.h>
63 #include <farstream/fs-conference.h>
6464
6565 #include <gst/gst.h>
6666
2727 #include <glib.h>
2828 #include <glib-object.h>
2929
30 #include <gst/farstream/fs-stream-transmitter.h>
31 #include <gst/farstream/fs-plugin.h>
30 #include <farstream/fs-stream-transmitter.h>
31 #include <farstream/fs-plugin.h>
3232 #include "fs-multicast-transmitter.h"
3333
3434 G_BEGIN_DECLS
3636 #include "fs-multicast-transmitter.h"
3737 #include "fs-multicast-stream-transmitter.h"
3838
39 #include <gst/farstream/fs-conference.h>
40 #include <gst/farstream/fs-plugin.h>
39 #include <farstream/fs-conference.h>
40 #include <farstream/fs-plugin.h>
4141
4242 #include <string.h>
4343 #include <sys/types.h>
2424 #ifndef __FS_MULTICAST_TRANSMITTER_H__
2525 #define __FS_MULTICAST_TRANSMITTER_H__
2626
27 #include <gst/farstream/fs-transmitter.h>
27 #include <farstream/fs-transmitter.h>
2828
2929 #include <gst/gst.h>
3030
1717 $(NICE_CFLAGS)
1818 libnice_transmitter_la_LDFLAGS = $(FS_PLUGIN_LDFLAGS)
1919 libnice_transmitter_la_LIBADD = \
20 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
20 $(top_builddir)/farstream/libfarstream-0.10.la \
2121 $(FS_LIBS) \
2222 $(GST_BASE_LIBS) \
2323 $(GST_LIBS) \
3131 #include "config.h"
3232 #endif
3333
34 #include <gst/farstream/fs-conference.h>
34 #include <farstream/fs-conference.h>
3535
3636 #include "fs-nice-transmitter.h"
3737 #include "fs-nice-agent.h"
2525 #define __FS_NICE_AGENT_H__
2626
2727 #include <glib-object.h>
28 #include <gst/farstream/fs-plugin.h>
28 #include <farstream/fs-plugin.h>
2929
3030
3131 G_BEGIN_DECLS
3737 #include "fs-nice-transmitter.h"
3838 #include "fs-nice-agent.h"
3939
40 #include <gst/farstream/fs-conference.h>
40 #include <farstream/fs-conference.h>
4141
4242 #include <gst/gst.h>
4343
2727 #include <glib.h>
2828 #include <glib-object.h>
2929
30 #include <gst/farstream/fs-stream-transmitter.h>
31 #include <gst/farstream/fs-plugin.h>
30 #include <farstream/fs-stream-transmitter.h>
31 #include <farstream/fs-plugin.h>
3232 #include "fs-nice-transmitter.h"
3333
3434 G_BEGIN_DECLS
3838 #include "fs-nice-stream-transmitter.h"
3939 #include "fs-nice-agent.h"
4040
41 #include <gst/farstream/fs-conference.h>
42 #include <gst/farstream/fs-plugin.h>
41 #include <farstream/fs-conference.h>
42 #include <farstream/fs-plugin.h>
4343
4444 #include <agent.h>
4545
2424 #ifndef __FS_NICE_TRANSMITTER_H__
2525 #define __FS_NICE_TRANSMITTER_H__
2626
27 #include <gst/farstream/fs-transmitter.h>
27 #include <farstream/fs-transmitter.h>
2828
2929 #include <gst/gst.h>
3030 #include <agent.h>
2323 $(GUPNP_CFLAGS)
2424 librawudp_transmitter_la_LDFLAGS = $(FS_PLUGIN_LDFLAGS)
2525 librawudp_transmitter_la_LIBADD = \
26 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
26 $(top_builddir)/farstream/libfarstream-0.10.la \
2727 $(FS_LIBS) \
2828 $(GST_PLUGINS_BASE_LIBS) \
2929 $(GST_LIBS) \
3636 #include <nice/address.h>
3737 #include <nice/interfaces.h>
3838
39 #include <gst/farstream/fs-conference.h>
39 #include <farstream/fs-conference.h>
4040
4141 #include <gst/netbuffer/gstnetbuffer.h>
4242
2727 #include <glib.h>
2828 #include <glib-object.h>
2929
30 #include <gst/farstream/fs-stream-transmitter.h>
31 #include <gst/farstream/fs-plugin.h>
30 #include <farstream/fs-stream-transmitter.h>
31 #include <farstream/fs-plugin.h>
3232 #include "fs-rawudp-transmitter.h"
3333
3434 G_BEGIN_DECLS
6565
6666 #include "fs-rawudp-component.h"
6767
68 #include <gst/farstream/fs-candidate.h>
69 #include <gst/farstream/fs-conference.h>
68 #include <farstream/fs-candidate.h>
69 #include <farstream/fs-conference.h>
7070
7171 #ifdef HAVE_GUPNP
7272 #include <libgupnp-igd/gupnp-simple-igd-thread.h>
2727 #include <glib.h>
2828 #include <glib-object.h>
2929
30 #include <gst/farstream/fs-stream-transmitter.h>
31 #include <gst/farstream/fs-plugin.h>
30 #include <farstream/fs-stream-transmitter.h>
31 #include <farstream/fs-plugin.h>
3232 #include "fs-rawudp-transmitter.h"
3333
3434 G_BEGIN_DECLS
3636 #include "fs-rawudp-transmitter.h"
3737 #include "fs-rawudp-stream-transmitter.h"
3838
39 #include <gst/farstream/fs-conference.h>
40 #include <gst/farstream/fs-plugin.h>
39 #include <farstream/fs-conference.h>
40 #include <farstream/fs-plugin.h>
4141
4242 #include <string.h>
4343 #include <sys/types.h>
2424 #ifndef __FS_RAWUDP_TRANSMITTER_H__
2525 #define __FS_RAWUDP_TRANSMITTER_H__
2626
27 #include <gst/farstream/fs-transmitter.h>
27 #include <farstream/fs-transmitter.h>
2828
2929 #include <gst/netbuffer/gstnetbuffer.h>
3030
1515 $(GST_CFLAGS)
1616 libshm_transmitter_la_LDFLAGS = $(FS_PLUGIN_LDFLAGS)
1717 libshm_transmitter_la_LIBADD = \
18 $(top_builddir)/gst-libs/gst/farstream/libfarstream-0.10.la \
18 $(top_builddir)/farstream/libfarstream-0.10.la \
1919 $(FS_LIBS) \
2020 $(GST_BASE_LIBS) \
2121 $(GST_LIBS)
6565 #include "fs-shm-stream-transmitter.h"
6666 #include "fs-shm-transmitter.h"
6767
68 #include <gst/farstream/fs-candidate.h>
69 #include <gst/farstream/fs-conference.h>
68 #include <farstream/fs-candidate.h>
69 #include <farstream/fs-conference.h>
7070
7171 #include <gst/gst.h>
7272
2727 #include <glib.h>
2828 #include <glib-object.h>
2929
30 #include <gst/farstream/fs-stream-transmitter.h>
31 #include <gst/farstream/fs-plugin.h>
30 #include <farstream/fs-stream-transmitter.h>
31 #include <farstream/fs-plugin.h>
3232 #include "fs-shm-transmitter.h"
3333
3434 G_BEGIN_DECLS
3636 #include "fs-shm-transmitter.h"
3737 #include "fs-shm-stream-transmitter.h"
3838
39 #include <gst/farstream/fs-conference.h>
40 #include <gst/farstream/fs-plugin.h>
39 #include <farstream/fs-conference.h>
40 #include <farstream/fs-plugin.h>
4141
4242 #include <string.h>
4343
2424 #ifndef __FS_SHM_TRANSMITTER_H__
2525 #define __FS_SHM_TRANSMITTER_H__
2626
27 #include <gst/farstream/fs-transmitter.h>
27 #include <farstream/fs-transmitter.h>
2828
2929 #include <gst/gst.h>
3030