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