8cca5ec111461ec347f9f701f2b7e58dd75f9b6c
[platform/upstream/gst-rtsp-server.git] / gst / rtsp-server / rtsp-media-factory-wfd.c
1 /* GStreamer
2  * Copyright (C) 2015 Samsung Electronics Hyunjun Ko <zzoon.ko@samsung.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /**
20  * SECTION:rtsp-media-factory
21  * @short_description: A factory for media pipelines
22  * @see_also: #GstRTSPMountPoints, #GstRTSPMedia
23  *
24  * The #GstRTSPMediaFactoryWFD is responsible for creating or recycling
25  * #GstRTSPMedia objects based on the passed URL.
26  *
27  * The default implementation of the object can create #GstRTSPMedia objects
28  * containing a pipeline created from a launch description set with
29  * gst_rtsp_media_factory_wfd_set_launch().
30  *
31  * Media from a factory can be shared by setting the shared flag with
32  * gst_rtsp_media_factory_wfd_set_shared(). When a factory is shared,
33  * gst_rtsp_media_factory_wfd_construct() will return the same #GstRTSPMedia when
34  * the url matches.
35  *
36  * Last reviewed on 2013-07-11 (1.0.0)
37  */
38
39 #include <stdio.h>
40 #include "rtsp-media-factory-wfd.h"
41 #include "gstwfdmessage.h"
42
43 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj)  \
44        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
45
46 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)       (&(GST_RTSP_MEDIA_FACTORY_WFD_CAST(f)->priv->lock))
47 #define GST_RTSP_MEDIA_FACTORY_WFD_LOCK(f)           (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
48 #define GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK(f)         (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
49
50 struct _GstRTSPMediaFactoryWFDPrivate
51 {
52   GMutex lock;
53   GstRTSPPermissions *permissions;
54   gchar *launch;
55   gboolean shared;
56   GstRTSPLowerTrans protocols;
57   guint buffer_size;
58   guint mtu_size;
59
60   guint8 videosrc_type;
61   guint8 video_codec;
62   gchar *video_encoder;
63   guint video_bitrate;
64   guint video_width;
65   guint video_height;
66   guint video_framerate;
67   guint video_enc_skip_inbuf_value;
68   GstElement *video_queue;
69
70   gchar *audio_device;
71   gchar *audio_encoder_aac;
72   gchar *audio_encoder_ac3;
73   guint8 audio_codec;
74   guint64 audio_latency_time;
75   guint64 audio_buffer_time;
76   gboolean audio_do_timestamp;
77   guint8 audio_channels;
78   guint8 audio_freq;
79   guint8 audio_bitrate;
80   GstElement *audio_queue;
81
82   guint64 video_resolution_supported;
83
84   gboolean dump_ts;
85 };
86
87 #define DEFAULT_LAUNCH          NULL
88 #define DEFAULT_SHARED          FALSE
89 #define DEFAULT_PROTOCOLS       GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
90                                         GST_RTSP_LOWER_TRANS_TCP
91 #define DEFAULT_BUFFER_SIZE     0x80000
92
93 enum
94 {
95   PROP_0,
96   PROP_LAUNCH,
97   PROP_SHARED,
98   PROP_SUSPEND_MODE,
99   PROP_EOS_SHUTDOWN,
100   PROP_PROTOCOLS,
101   PROP_BUFFER_SIZE,
102   PROP_LAST
103 };
104
105 enum
106 {
107   SIGNAL_MEDIA_CONSTRUCTED,
108   SIGNAL_MEDIA_CONFIGURE,
109   SIGNAL_LAST
110 };
111
112 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
113 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
114
115 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
116     guint propid, GValue * value, GParamSpec * pspec);
117 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
118     guint propid, const GValue * value, GParamSpec * pspec);
119
120 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
121
122
123 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
124     factory, const GstRTSPUrl * url);
125 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
126     factory, const GstRTSPUrl * url);
127
128 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
129     GST_TYPE_RTSP_MEDIA_FACTORY);
130
131 static void
132 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
133 {
134   GObjectClass *gobject_class;
135   GstRTSPMediaFactoryClass *factory_class;
136
137   g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
138
139   gobject_class = G_OBJECT_CLASS (klass);
140   factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
141
142   gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
143   gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
144   gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
145
146   factory_class->construct = rtsp_media_factory_wfd_construct;
147   factory_class->create_element = rtsp_media_factory_wfd_create_element;
148
149   GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
150       "GstRTSPMediaFactoryWFD");
151 }
152
153 void  gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
154     guint8 videosrc_type, gchar *audio_device, guint64 audio_latency_time,
155     guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
156 {
157   GstRTSPMediaFactoryWFDPrivate *priv =
158       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
159   factory->priv = priv;
160
161   priv->videosrc_type = videosrc_type;
162   priv->audio_device = audio_device;
163   priv->audio_latency_time = audio_latency_time;
164   priv->audio_buffer_time = audio_buffer_time;
165   priv->audio_do_timestamp = audio_do_timestamp;
166   priv->mtu_size = mtu_size;
167 }
168
169 void  gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
170     gchar *video_encoder, gchar *audio_encoder_aac, gchar *audio_encoder_ac3)
171 {
172   GstRTSPMediaFactoryWFDPrivate *priv =
173       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
174   factory->priv = priv;
175
176   priv->video_encoder = video_encoder;
177   priv->audio_encoder_aac = audio_encoder_aac;
178   priv->audio_encoder_ac3 = audio_encoder_ac3;
179 }
180
181 void  gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
182     gboolean dump_ts)
183 {
184   GstRTSPMediaFactoryWFDPrivate *priv =
185       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
186   factory->priv = priv;
187
188   priv->dump_ts = dump_ts;
189 }
190 void gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *factory,
191    guint32 width, guint32 height)
192 {
193   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
194   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
195
196   priv->video_width = width;
197   priv->video_height = height;
198 }
199 void gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory *factory,
200    guint audio_codec)
201 {
202   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
203   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
204
205   priv->audio_codec = audio_codec;
206 }
207
208 static void
209 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
210 {
211   GstRTSPMediaFactoryWFDPrivate *priv =
212       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
213   factory->priv = priv;
214
215   priv->launch = g_strdup (DEFAULT_LAUNCH);
216   priv->shared = DEFAULT_SHARED;
217   priv->protocols = DEFAULT_PROTOCOLS;
218   priv->buffer_size = DEFAULT_BUFFER_SIZE;
219
220   //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
221   //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
222   //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
223   priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
224   priv->video_codec = GST_WFD_VIDEO_H264;
225   priv->video_encoder = g_strdup ("omxh264enc");
226   priv->video_bitrate = 200000;
227   priv->video_width = 640;
228   priv->video_height = 480;
229   priv->video_framerate = 30;
230   priv->video_enc_skip_inbuf_value = 5;
231
232   priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
233   priv->audio_codec = GST_WFD_AUDIO_AAC;
234   priv->audio_encoder_aac = g_strdup ("avenc_aac");
235   priv->audio_encoder_ac3 = g_strdup ("avenc_ac3");
236   priv->audio_latency_time = 10000;
237   priv->audio_buffer_time = 200000;
238   priv->audio_do_timestamp = FALSE;
239   priv->audio_channels = GST_WFD_CHANNEL_2;
240   priv->audio_freq = GST_WFD_FREQ_48000;
241
242   g_mutex_init (&priv->lock);
243 }
244
245 static void
246 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
247 {
248   GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
249   GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
250
251   if (priv->permissions)
252     gst_rtsp_permissions_unref (priv->permissions);
253   g_free (priv->launch);
254   g_mutex_clear (&priv->lock);
255
256   if (priv->audio_device)
257     g_free (priv->audio_device);
258   if (priv->audio_encoder_aac)
259     g_free (priv->audio_encoder_aac);
260   if (priv->audio_encoder_ac3)
261     g_free (priv->audio_encoder_ac3);
262
263   if (priv->video_encoder)
264     g_free (priv->video_encoder);
265
266   G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
267 }
268
269 GstRTSPMediaFactoryWFD *
270 gst_rtsp_media_factory_wfd_new (void)
271 {
272   GstRTSPMediaFactoryWFD *result;
273
274   result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
275
276   return result;
277 }
278
279 static void
280 gst_rtsp_media_factory_wfd_get_property (GObject * object,
281     guint propid, GValue * value, GParamSpec * pspec)
282 {
283   //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
284
285   switch (propid) {
286     default:
287       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
288   }
289 }
290
291 static void
292 gst_rtsp_media_factory_wfd_set_property (GObject * object,
293     guint propid, const GValue * value, GParamSpec * pspec)
294 {
295   //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
296
297   switch (propid) {
298     default:
299       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
300   }
301 }
302
303 static GstPadProbeReturn
304 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo *info, gpointer u_data)
305 {
306   guint8 *data;
307   gsize size;
308   FILE *f;
309   GstMapInfo mapinfo;
310
311   if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
312     GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
313
314     gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
315     data = mapinfo.data;
316     size = gst_buffer_get_size (buffer);
317
318     f = fopen ("/root/probe.ts", "a");
319     if (f != NULL) {
320       fwrite (data, size, 1, f);
321       fclose (f);
322     }
323     gst_buffer_unmap (buffer, &mapinfo);
324   }
325
326   return GST_PAD_PROBE_OK;
327 }
328
329 static gboolean
330 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
331     factory, GstBin * srcbin)
332 {
333   GstElement *audiosrc = NULL;
334   GstElement *acaps = NULL;
335   GstElement *acaps2 = NULL;
336   GstElement *aenc = NULL;
337   GstElement *audio_convert = NULL;
338   GstElement *aqueue = NULL;
339   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
340   GstStructure *audio_properties_name = NULL;
341
342   guint channels = 0;
343   gboolean is_enc_req = TRUE;
344   guint freq = 0;
345   gchar *acodec = NULL;
346
347   priv = factory->priv;
348
349   /* create audio src element */
350   audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
351   if (!audiosrc) {
352     GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
353     goto create_error;
354   }
355
356   GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
357   GST_INFO_OBJECT (factory, "audio latency time  : %"G_GUINT64_FORMAT,
358       priv->audio_latency_time);
359   GST_INFO_OBJECT (factory, "audio_buffer_time  : %"G_GUINT64_FORMAT,
360       priv->audio_buffer_time);
361   GST_INFO_OBJECT (factory, "audio_do_timestamp  : %d",
362       priv->audio_do_timestamp);
363
364   audio_properties_name = gst_structure_new_from_string(priv->audio_device);
365
366   g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
367   g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
368       NULL);
369   g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
370       NULL);
371   g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
372       NULL);
373   g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
374   g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
375
376   if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
377     /* To meet miracast certification */
378     gint64 block_size = 1920;
379     g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
380
381     audio_convert = gst_element_factory_make ("capssetter", "audio_convert");
382     if (NULL == audio_convert) {
383       GST_ERROR_OBJECT (factory, "failed to create audio convert element");
384       goto create_error;
385     }
386     g_object_set (audio_convert, "caps", gst_caps_new_simple("audio/x-lpcm",
387               "width", G_TYPE_INT, 16,
388               "rate", G_TYPE_INT, 48000,
389               "channels", G_TYPE_INT, 2,
390               "dynamic_range", G_TYPE_INT, 0,
391               "emphasis", G_TYPE_BOOLEAN, FALSE,
392               "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
393     g_object_set (audio_convert, "join", (gboolean)FALSE, NULL);
394     g_object_set (audio_convert, "replace", (gboolean)TRUE, NULL);
395
396     acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
397     if (NULL == acaps2) {
398       GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
399       goto create_error;
400     }
401     /* In case of LPCM, uses big endian */
402         g_object_set (G_OBJECT (acaps2), "caps",
403             gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
404                 /* In case of LPCM, uses big endian */
405                 "rate", G_TYPE_INT, 48000,
406                 "channels", G_TYPE_INT, 2, NULL), NULL);
407   }
408
409   /* create audio caps element */
410   acaps = gst_element_factory_make ("capsfilter", "audiocaps");
411   if (NULL == acaps) {
412     GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
413     goto create_error;
414   }
415
416   if (priv->audio_channels == GST_WFD_CHANNEL_2)
417     channels = 2;
418   else if (priv->audio_channels == GST_WFD_CHANNEL_4)
419     channels = 4;
420   else if (priv->audio_channels == GST_WFD_CHANNEL_6)
421     channels = 6;
422   else if (priv->audio_channels == GST_WFD_CHANNEL_8)
423     channels = 8;
424   else
425     channels = 2;
426
427   if (priv->audio_freq == GST_WFD_FREQ_44100)
428     freq = 44100;
429   else if (priv->audio_freq == GST_WFD_FREQ_48000)
430     freq = 48000;
431   else
432     freq = 44100;
433
434   if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
435     g_object_set (G_OBJECT (acaps), "caps",
436         gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
437             "rate", G_TYPE_INT, 48000,
438             "channels", G_TYPE_INT, 2,
439             "dynamic_range", G_TYPE_INT, 0,
440             "emphasis", G_TYPE_BOOLEAN, FALSE,
441             "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
442   } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
443       || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
444     g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
445             "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
446             "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
447             G_TYPE_INT, channels, NULL), NULL);
448   }
449
450   if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
451     acodec = g_strdup (priv->audio_encoder_aac);
452     is_enc_req = TRUE;
453   } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
454     acodec = g_strdup (priv->audio_encoder_ac3);
455     is_enc_req = TRUE;
456   } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
457     GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
458     is_enc_req = FALSE;
459   } else {
460     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
461     goto create_error;
462   }
463
464   if (is_enc_req) {
465     aenc = gst_element_factory_make (acodec, "audioenc");
466     if (NULL == aenc) {
467       GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
468       goto create_error;
469     }
470
471     g_object_set (aenc, "compliance", -2, NULL);
472     g_object_set (aenc, "tolerance", 400000000, NULL);
473     g_object_set (aenc, "bitrate", (guint) 128000, NULL);
474     g_object_set (aenc, "rate-control", 2, NULL);
475
476     aqueue = gst_element_factory_make ("queue", "audio-queue");
477     if (!aqueue) {
478       GST_ERROR_OBJECT (factory, "failed to create audio queue element");
479       goto create_error;
480     }
481
482     gst_bin_add_many (srcbin, audiosrc, acaps, aenc, aqueue, NULL);
483
484     if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
485       GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
486       goto create_error;
487     }
488   } else {
489     aqueue = gst_element_factory_make ("queue", "audio-queue");
490     if (!aqueue) {
491       GST_ERROR_OBJECT (factory, "failed to create audio queue element");
492       goto create_error;
493     }
494
495     gst_bin_add_many (srcbin, audiosrc, acaps2, audio_convert, acaps, aqueue, NULL);
496
497     if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue, NULL)) {
498       GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
499       goto create_error;
500     }
501   }
502
503   priv->audio_queue = aqueue;
504   if (acodec) g_free (acodec);
505   if (gst_structure_free) gst_structure_free(audio_properties_name);
506   return TRUE;
507
508 create_error:
509   if (acodec) g_free (acodec);
510   if (gst_structure_free) gst_structure_free(audio_properties_name);
511   return FALSE;
512 }
513
514 static gboolean
515 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
516     GstBin * srcbin)
517 {
518   GstElement *videosrc = NULL;
519   GstElement *vcaps = NULL;
520   GstElement *videoconvert = NULL;
521   GstElement *venc_caps = NULL;
522   gchar *vcodec = NULL;
523   GstElement *venc = NULL;
524   GstElement *vparse = NULL;
525   GstElement *vqueue = NULL;
526   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
527
528   priv = factory->priv;
529
530   GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
531
532   videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
533   if (NULL == videosrc) {
534     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
535     goto create_error;
536   }
537
538   /* create video caps element */
539   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
540   if (NULL == vcaps) {
541     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
542     goto create_error;
543   }
544
545   g_object_set (G_OBJECT (vcaps), "caps",
546       gst_caps_new_simple ("video/x-raw",
547           "format", G_TYPE_STRING, "I420",
548           "width", G_TYPE_INT, priv->video_width,
549           "height", G_TYPE_INT, priv->video_height,
550           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
551       NULL);
552
553   /* create video convert element */
554   videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
555   if (NULL == videoconvert) {
556     GST_ERROR_OBJECT (factory, "failed to create video videoconvert element");
557     goto create_error;
558   }
559
560   venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
561   if (NULL == venc_caps) {
562     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
563     goto create_error;
564   }
565
566   g_object_set (G_OBJECT (venc_caps), "caps",
567       gst_caps_new_simple ("video/x-raw",
568           "format", G_TYPE_STRING, "SN12",
569           "width", G_TYPE_INT, priv->video_width,
570           "height", G_TYPE_INT, priv->video_height,
571           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
572       NULL);
573
574   if (priv->video_codec == GST_WFD_VIDEO_H264)
575     vcodec = g_strdup (priv->video_encoder);
576   else {
577     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
578     goto create_error;
579   }
580
581   venc = gst_element_factory_make (vcodec, "videoenc");
582   if (vcodec) g_free (vcodec);
583
584   if (!venc) {
585     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
586     goto create_error;
587   }
588
589   g_object_set (venc, "aud", 0, NULL);
590   g_object_set (venc, "byte-stream", 1, NULL);
591   g_object_set (venc, "bitrate", 512, NULL);
592
593   vparse = gst_element_factory_make ("h264parse", "videoparse");
594   if (NULL == vparse) {
595     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
596     goto create_error;
597   }
598   g_object_set (vparse, "config-interval", 1, NULL);
599
600   vqueue = gst_element_factory_make ("queue", "video-queue");
601   if (!vqueue) {
602     GST_ERROR_OBJECT (factory, "failed to create video queue element");
603     goto create_error;
604   }
605
606   gst_bin_add_many (srcbin, videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL);
607   if (!gst_element_link_many (videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL)) {
608     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
609     goto create_error;
610   }
611
612   priv->video_queue = vqueue;
613
614   return TRUE;
615
616 create_error:
617   return FALSE;
618 }
619
620 static gboolean
621 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
622     GstBin * srcbin)
623 {
624   GstElement *videosrc = NULL;
625   GstElement *vcaps = NULL;
626   gchar *vcodec = NULL;
627   GstElement *venc = NULL;
628   GstElement *vparse = NULL;
629   GstElement *vqueue = NULL;
630   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
631
632   priv = factory->priv;
633
634   GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
635
636   videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
637   if (NULL == videosrc) {
638     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
639     goto create_error;
640   }
641
642   /* create video caps element */
643   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
644   if (NULL == vcaps) {
645     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
646     goto create_error;
647   }
648
649   g_object_set (G_OBJECT (vcaps), "caps",
650       gst_caps_new_simple ("video/x-raw",
651           "format", G_TYPE_STRING, "SN12",
652           "width", G_TYPE_INT, priv->video_width,
653           "height", G_TYPE_INT, priv->video_height,
654           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
655       NULL);
656
657   if (priv->video_codec == GST_WFD_VIDEO_H264)
658     vcodec = g_strdup (priv->video_encoder);
659   else {
660     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
661     goto create_error;
662   }
663
664   venc = gst_element_factory_make (vcodec, "videoenc");
665   if (vcodec) g_free (vcodec);
666
667   if (!venc) {
668     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
669     goto create_error;
670   }
671
672   g_object_set (venc, "aud", 0, NULL);
673   g_object_set (venc, "byte-stream", 1, NULL);
674   g_object_set (venc, "bitrate", 512, NULL);
675
676   vparse = gst_element_factory_make ("h264parse", "videoparse");
677   if (NULL == vparse) {
678     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
679     goto create_error;
680   }
681   g_object_set (vparse, "config-interval", 1, NULL);
682
683   vqueue = gst_element_factory_make ("queue", "video-queue");
684   if (!vqueue) {
685     GST_ERROR_OBJECT (factory, "failed to create video queue element");
686     goto create_error;
687   }
688
689   gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
690   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
691     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
692     goto create_error;
693   }
694
695   priv->video_queue = vqueue;
696
697   return TRUE;
698
699 create_error:
700   return FALSE;
701 }
702
703 static gboolean
704 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
705     factory, GstBin * srcbin)
706 {
707   GstElement *videosrc = NULL;
708   GstElement *vcaps = NULL;
709   GstElement *venc = NULL;
710   GstElement *vparse = NULL;
711   GstElement *vqueue = NULL;
712   gchar *vcodec = NULL;
713   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
714
715   priv = factory->priv;
716
717   videosrc = gst_element_factory_make ("camerasrc", "videosrc");
718   if (NULL == videosrc) {
719     GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
720     goto create_error;
721   }
722
723   /* create video caps element */
724   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
725   if (NULL == vcaps) {
726     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
727     goto create_error;
728   }
729
730   GST_INFO_OBJECT (factory, "picked camerasrc as video source");
731   g_object_set (G_OBJECT (vcaps), "caps",
732       gst_caps_new_simple ("video/x-raw",
733           "width", G_TYPE_INT, priv->video_width,
734           "height", G_TYPE_INT, priv->video_height,
735           "format", G_TYPE_STRING, "SN12",
736           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
737       NULL);
738
739   if (priv->video_codec == GST_WFD_VIDEO_H264)
740     vcodec = g_strdup (priv->video_encoder);
741   else {
742     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
743     goto create_error;
744   }
745
746   venc = gst_element_factory_make (vcodec, "videoenc");
747   if (vcodec) g_free (vcodec);
748
749   if (!venc) {
750     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
751     goto create_error;
752   }
753
754   g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
755   g_object_set (venc, "byte-stream", 1, NULL);
756   g_object_set (venc, "append-dci", 1, NULL);
757
758   vparse = gst_element_factory_make ("h264parse", "videoparse");
759   if (NULL == vparse) {
760     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
761     goto create_error;
762   }
763   g_object_set (vparse, "config-interval", 1, NULL);
764
765   vqueue = gst_element_factory_make ("queue", "video-queue");
766   if (!vqueue) {
767     GST_ERROR_OBJECT (factory, "failed to create video queue element");
768     goto create_error;
769   }
770
771   gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
772
773   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
774     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
775     goto create_error;
776   }
777
778   priv->video_queue = vqueue;
779
780   return TRUE;
781
782 create_error:
783   return FALSE;
784 }
785
786 static gboolean
787 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
788     GstBin * srcbin)
789 {
790   GstElement *videosrc = NULL;
791   GstElement *vcaps = NULL;
792   GstElement *venc_caps = NULL;
793   GstElement *videoconvert = NULL, *videoscale = NULL;
794   gchar *vcodec = NULL;
795   GstElement *venc = NULL;
796   GstElement *vparse = NULL;
797   GstElement *vqueue = NULL;
798   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
799
800   priv = factory->priv;
801
802   GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
803
804   videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
805   if (NULL == videosrc) {
806     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
807     goto create_error;
808   }
809
810   videoscale = gst_element_factory_make ("videoscale", "videoscale");
811   if (NULL == videoscale) {
812     GST_ERROR_OBJECT (factory, "failed to create videoscale element");
813     goto create_error;
814   }
815
816   videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
817   if (NULL == videoconvert) {
818     GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
819     goto create_error;
820   }
821
822   /* create video caps element */
823   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
824   if (NULL == vcaps) {
825     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
826     goto create_error;
827   }
828
829   g_object_set (G_OBJECT (vcaps), "caps",
830       gst_caps_new_simple ("video/x-raw",
831           "width", G_TYPE_INT, priv->video_width,
832           "height", G_TYPE_INT, priv->video_height,
833           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
834       NULL);
835
836   if (priv->video_codec == GST_WFD_VIDEO_H264)
837     vcodec = g_strdup (priv->video_encoder);
838   else {
839     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
840     goto create_error;
841   }
842
843   venc = gst_element_factory_make (vcodec, "videoenc");
844   if (vcodec) g_free (vcodec);
845
846   if (!venc) {
847     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
848     goto create_error;
849   }
850
851   g_object_set (venc, "aud", 0, NULL);
852   g_object_set (venc, "byte-stream", 1, NULL);
853   g_object_set (venc, "bitrate", 512, NULL);
854
855   venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
856   if (NULL == venc_caps) {
857     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
858     goto create_error;
859   }
860
861   g_object_set (G_OBJECT (venc_caps), "caps",
862       gst_caps_new_simple ("video/x-h264",
863           "profile", G_TYPE_STRING, "baseline", NULL), NULL);
864
865   vparse = gst_element_factory_make ("h264parse", "videoparse");
866   if (NULL == vparse) {
867     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
868     goto create_error;
869   }
870   g_object_set (vparse, "config-interval", 1, NULL);
871
872   vqueue = gst_element_factory_make ("queue", "video-queue");
873   if (!vqueue) {
874     GST_ERROR_OBJECT (factory, "failed to create video queue element");
875     goto create_error;
876   }
877
878   gst_bin_add_many (srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
879       venc_caps, vparse, vqueue, NULL);
880   if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
881           venc_caps, vparse, vqueue, NULL)) {
882     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
883     goto create_error;
884   }
885
886   priv->video_queue = vqueue;
887
888   return TRUE;
889
890 create_error:
891   return FALSE;
892 }
893
894 static gboolean
895 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
896     GstBin * srcbin)
897 {
898   GstElement *videosrc = NULL;
899   GstElement *vcaps = NULL;
900   gchar *vcodec = NULL;
901   GstElement *venc = NULL;
902   GstElement *vparse = NULL;
903   GstElement *vqueue = NULL;
904   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
905
906   priv = factory->priv;
907
908   GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
909
910   videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
911   if (NULL == videosrc) {
912     GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
913     goto create_error;
914   }
915
916   /* create video caps element */
917   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
918   if (NULL == vcaps) {
919     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
920     goto create_error;
921   }
922
923   g_object_set (G_OBJECT (vcaps), "caps",
924       gst_caps_new_simple ("video/x-raw",
925           "width", G_TYPE_INT, priv->video_width,
926           "height", G_TYPE_INT, priv->video_height,
927           "format", G_TYPE_STRING, "SN12",
928           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
929       NULL);
930
931   if (priv->video_codec == GST_WFD_VIDEO_H264) {
932     vcodec = g_strdup (priv->video_encoder);
933   } else {
934     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
935     goto create_error;
936   }
937
938   venc = gst_element_factory_make (vcodec, "videoenc");
939   if (!venc) {
940     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
941     goto create_error;
942   }
943   g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
944   g_object_set (venc, "byte-stream", 1, NULL);
945   g_object_set (venc, "append-dci", 1, NULL);
946   g_object_set (venc, "idr-period", 120, NULL);
947   g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
948
949   vparse = gst_element_factory_make ("h264parse", "videoparse");
950   if (NULL == vparse) {
951     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
952     goto create_error;
953   }
954   g_object_set (vparse, "config-interval", 1, NULL);
955
956   vqueue = gst_element_factory_make ("queue", "video-queue");
957   if (!vqueue) {
958     GST_ERROR_OBJECT (factory, "failed to create video queue element");
959     goto create_error;
960   }
961
962   gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
963   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
964     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
965     goto create_error;
966   }
967
968   priv->video_queue = vqueue;
969   if (vcodec) g_free (vcodec);
970
971   return TRUE;
972
973 create_error:
974   if (vcodec) g_free (vcodec);
975   return FALSE;
976 }
977
978 static GstElement *
979 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
980 {
981   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
982
983   GstBin *srcbin = NULL;
984   GstElement *mux = NULL;
985   GstElement *mux_queue = NULL;
986   GstElement *payload = NULL;
987   GstPad *srcpad = NULL;
988   GstPad *mux_vsinkpad = NULL;
989   GstPad *mux_asinkpad = NULL;
990
991   priv = factory->priv;
992
993   /* create source bin */
994   srcbin = GST_BIN (gst_bin_new ("srcbin"));
995   if (!srcbin) {
996     GST_ERROR_OBJECT (factory, "failed to create source bin...");
997     goto create_error;
998   }
999
1000   /* create video src element */
1001   switch (priv->videosrc_type) {
1002     case GST_WFD_VSRC_XIMAGESRC:
1003       if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
1004         GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
1005         goto create_error;
1006       }
1007       break;
1008     case GST_WFD_VSRC_XVIMAGESRC:
1009       if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
1010         GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
1011         goto create_error;
1012       }
1013       break;
1014     case GST_WFD_VSRC_CAMERASRC:
1015       if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
1016         GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
1017         goto create_error;
1018       }
1019       break;
1020     case GST_WFD_VSRC_VIDEOTESTSRC:
1021       if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
1022         GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1023         goto create_error;
1024       }
1025       break;
1026     case GST_WFD_VSRC_WAYLANDSRC:
1027       if (!_rtsp_media_factory_wfd_create_waylandsrc_bin (factory, srcbin)) {
1028         GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1029         goto create_error;
1030       }
1031       break;
1032     default:
1033       GST_ERROR_OBJECT (factory, "unknow mode selected...");
1034       goto create_error;
1035   }
1036
1037   mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1038   if (!mux) {
1039     GST_ERROR_OBJECT (factory, "failed to create muxer element");
1040     goto create_error;
1041   }
1042
1043   g_object_set (mux, "wfd-mode", TRUE, NULL);
1044
1045   mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1046   if (!mux_queue) {
1047     GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1048     goto create_error;
1049   }
1050
1051   g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1052
1053   payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1054   if (!payload) {
1055     GST_ERROR_OBJECT (factory, "failed to create payload element");
1056     goto create_error;
1057   }
1058
1059   g_object_set (payload, "pt", 33, NULL);
1060   g_object_set (payload, "mtu", priv->mtu_size, NULL);
1061   g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
1062
1063   gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1064
1065   if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1066     GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
1067     goto create_error;
1068   }
1069
1070   /* request video sink pad from muxer, which has elementary pid 0x1011 */
1071   mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
1072   if (!mux_vsinkpad) {
1073     GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1074     goto create_error;
1075   }
1076
1077   /* request srcpad from video queue */
1078   srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1079   if (!srcpad) {
1080     GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1081     goto create_error;
1082   }
1083
1084   if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1085     GST_ERROR_OBJECT (factory,
1086         "Failed to link video queue src pad & muxer video sink pad...");
1087     goto create_error;
1088   }
1089
1090   gst_object_unref (mux_vsinkpad);
1091   gst_object_unref (srcpad);
1092   srcpad = NULL;
1093
1094   /* create audio source elements & add to pipeline */
1095   if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
1096     goto create_error;
1097
1098   /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1099   mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
1100   if (!mux_asinkpad) {
1101     GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1102     goto create_error;
1103   }
1104
1105   /* request srcpad from audio queue */
1106   srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1107   if (!srcpad) {
1108     GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1109     goto create_error;
1110   }
1111
1112   /* link audio queue's srcpad & muxer sink pad */
1113   if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
1114     GST_ERROR_OBJECT (factory,
1115         "Failed to link audio queue src pad & muxer audio sink pad...");
1116     goto create_error;
1117   }
1118   gst_object_unref (mux_asinkpad);
1119   gst_object_unref (srcpad);
1120
1121   if (priv->dump_ts)
1122   {
1123     GstPad *pad_probe = NULL;
1124     pad_probe = gst_element_get_static_pad (mux, "src");
1125
1126     if (NULL == pad_probe) {
1127       GST_INFO_OBJECT (factory, "pad for probe not created");
1128     } else {
1129       GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1130     }
1131     gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1132         rtsp_media_wfd_dump_data, factory, NULL);
1133   }
1134
1135   GST_DEBUG_OBJECT (factory, "successfully created source bin...");
1136
1137   return GST_ELEMENT_CAST (srcbin);
1138
1139 create_error:
1140   GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1141   return NULL;
1142 }
1143
1144 static GstElement *
1145 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1146     const GstRTSPUrl * url)
1147 {
1148   GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1149   GstElement *element = NULL;
1150
1151   GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1152
1153   element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1154
1155   GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1156
1157   return element;
1158 }
1159
1160 static GstRTSPMedia *
1161 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1162     const GstRTSPUrl * url)
1163 {
1164   GstRTSPMedia *media;
1165   GstElement *element, *pipeline;
1166   GstRTSPMediaFactoryClass *klass;
1167
1168   klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1169
1170   if (!klass->create_pipeline)
1171     goto no_create;
1172
1173   element = gst_rtsp_media_factory_create_element (factory, url);
1174   if (element == NULL)
1175     goto no_element;
1176
1177   /* create a new empty media */
1178   media = gst_rtsp_media_new (element);
1179
1180   gst_rtsp_media_collect_streams (media);
1181
1182   pipeline = klass->create_pipeline (factory, media);
1183   if (pipeline == NULL)
1184     goto no_pipeline;
1185
1186   return media;
1187
1188   /* ERRORS */
1189 no_create:
1190   {
1191     g_critical ("no create_pipeline function");
1192     return NULL;
1193   }
1194 no_element:
1195   {
1196     g_critical ("could not create element");
1197     return NULL;
1198   }
1199 no_pipeline:
1200   {
1201     g_critical ("can't create pipeline");
1202     g_object_unref (media);
1203     return NULL;
1204   }
1205 }