2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "rtsp-media-factory.h"
22 #define DEFAULT_LAUNCH NULL
31 static void gst_rtsp_media_factory_get_property (GObject *object, guint propid,
32 GValue *value, GParamSpec *pspec);
33 static void gst_rtsp_media_factory_set_property (GObject *object, guint propid,
34 const GValue *value, GParamSpec *pspec);
35 static void gst_rtsp_media_factory_finalize (GObject * obj);
37 static GstRTSPMediaBin * default_construct (GstRTSPMediaFactory *factory, const gchar *location);
39 G_DEFINE_TYPE (GstRTSPMediaFactory, gst_rtsp_media_factory, G_TYPE_OBJECT);
42 gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
44 GObjectClass *gobject_class;
46 gobject_class = G_OBJECT_CLASS (klass);
48 gobject_class->get_property = gst_rtsp_media_factory_get_property;
49 gobject_class->set_property = gst_rtsp_media_factory_set_property;
50 gobject_class->finalize = gst_rtsp_media_factory_finalize;
53 * GstRTSPMediaFactory::launch
55 * The gst_parse_launch() line to use for constructing the pipeline in the
56 * default prepare vmethod.
58 * The pipeline description should return a GstBin as the toplevel element
59 * which can be accomplished by enclosing the dscription with brackets '('
62 * The description should return a pipeline with payloaders named pay0, pay1,
63 * etc.. Each of the payloaders will result in a stream.
65 g_object_class_install_property (gobject_class, PROP_LAUNCH,
66 g_param_spec_string ("launch", "Launch", "A launch description of the pipeline",
67 DEFAULT_LAUNCH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
69 klass->construct = default_construct;
73 gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
78 gst_rtsp_media_factory_finalize (GObject * obj)
80 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (obj);
82 g_free (factory->launch);
84 G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
88 gst_rtsp_media_factory_get_property (GObject *object, guint propid,
89 GValue *value, GParamSpec *pspec)
91 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
95 g_value_take_string (value, gst_rtsp_media_factory_get_launch (factory));
98 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
103 gst_rtsp_media_factory_set_property (GObject *object, guint propid,
104 const GValue *value, GParamSpec *pspec)
106 GstRTSPMediaFactory *factory = GST_RTSP_MEDIA_FACTORY (object);
110 gst_rtsp_media_factory_set_launch (factory, g_value_get_string (value));
113 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
118 * gst_rtsp_media_factory_new:
120 * Create a new #GstRTSPMediaFactory instance.
122 * Returns: a new #GstRTSPMediaFactory object or %NULL when location did not contain a
123 * valid or understood URL.
125 GstRTSPMediaFactory *
126 gst_rtsp_media_factory_new (void)
128 GstRTSPMediaFactory *result;
130 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY, NULL);
136 * gst_rtsp_media_factory_set_launch:
137 * @factory: a #GstRTSPMediaFactory
138 * @launch: the launch description
141 * The gst_parse_launch() line to use for constructing the pipeline in the
142 * default prepare vmethod.
144 * The pipeline description should return a GstBin as the toplevel element
145 * which can be accomplished by enclosing the dscription with brackets '('
148 * The description should return a pipeline with payloaders named pay0, pay1,
149 * etc.. Each of the payloaders will result in a stream.
152 gst_rtsp_media_factory_set_launch (GstRTSPMediaFactory *factory, const gchar *launch)
154 g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
155 g_return_if_fail (launch != NULL);
157 factory->launch = g_strdup (launch);
161 * gst_rtsp_media_factory_get_launch:
162 * @factory: a #GstRTSPMediaFactory
164 * Get the gst_parse_launch() pipeline description that will be used in the
165 * default prepare vmethod.
167 * Returns: the configured launch description. g_free() after usage.
170 gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory *factory)
174 result = g_strdup (factory->launch);
180 * gst_rtsp_media_factory_construct:
181 * @factory: a #GstRTSPMediaFactory
182 * @location: the url used
184 * Prepare the media bin object and create its streams. Implementations
185 * should create the needed gstreamer elements and add them to the result
186 * object. No state changes should be performed on them yet.
188 * One or more GstRTSPMediaStream objects should be added to the result with
189 * the srcpad member set to a source pad that produces buffer of type
192 * Returns: a new #GstRTSPMediaBin if the media could be prepared.
195 gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory, const gchar *location)
197 GstRTSPMediaBin *res;
198 GstRTSPMediaFactoryClass *klass;
200 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
202 if (klass->construct)
203 res = klass->construct (factory, location);
207 g_message ("constructed mediabin %p for location %s", res, location);
213 caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPMediaStream * stream)
216 gst_caps_unref (stream->caps);
217 if ((stream->caps = GST_PAD_CAPS (pad)))
218 gst_caps_ref (stream->caps);
221 static GstRTSPMediaBin *
222 default_construct (GstRTSPMediaFactory *factory, const gchar *location)
224 GstRTSPMediaBin *bin;
225 GstRTSPMediaStream *stream;
226 GstElement *pay, *element;
229 GError *error = NULL;
231 /* we need a parse syntax */
232 if (factory->launch == NULL)
235 /* parse the user provided launch line */
236 element = gst_parse_launch (factory->launch, &error);
241 /* a recoverable error was encountered */
242 g_warning ("recoverable parsing error: %s", error->message);
243 g_error_free (error);
246 bin = g_object_new (GST_TYPE_RTSP_MEDIA_BIN, NULL);
247 bin->element = element;
249 /* try to find all the payloader elements, they should be named 'pay%d'. for
250 * each of the payloaders we will create a stream, collect the source pad and
251 * add a notify::caps on the pad. */
255 name = g_strdup_printf ("pay%d", i);
257 if (!(pay = gst_bin_get_by_name (GST_BIN (element), name))) {
258 /* no more payloaders found, we have found all the streams and we can
264 /* create the stream */
265 stream = g_new0 (GstRTSPMediaStream, 1);
266 stream->mediabin = bin;
267 stream->element = element;
268 stream->payloader = pay;
269 stream->idx = bin->streams->len;
271 pad = gst_element_get_static_pad (pay, "src");
273 /* ghost the pad of the payloader to the element */
274 stream->srcpad = gst_ghost_pad_new (name, pad);
275 gst_element_add_pad (stream->element, stream->srcpad);
277 stream->caps_sig = g_signal_connect (pad, "notify::caps", (GCallback) caps_notify, stream);
278 gst_object_unref (pad);
281 g_array_append_val (bin->streams, stream);
282 gst_object_unref (pay);
292 g_critical ("no launch line specified");
297 g_critical ("could not parse launch syntax (%s): %s", factory->launch,
298 (error ? error->message : "unknown reason"));
300 g_error_free (error);